 |
- アナログ時計を作ってみよう -
今までの関数を利用し、総まとめとしてアナログ時計を作ってみます
使用する関数は以下
現在時間を取得するCTime関数、円を描くEllipse()関数
線を引くMoveTo(),LineTo()関数、文字列表示のSetWindowText関数
※解説ではOnPaint関数を使用していますがViewクラスのOnDraw関数でも同じように出来ます
≪ MFC・SDIでの作成例 ≫
■ クラスウイザードを呼び出しViewクラスにWM_PAINTを追加する

※画面表示用メッセージWM_PAINTを呼び出し、OnPaint関数を追加
■ sin、cos関数使用のため StdAfx.cpp にmath.hファイルをインクルード
// stdafx.cpp : 標準インクルードファイルを含むソース ファイル
// Test09.pch : 生成されるプリコンパイル済ヘッダー
// stdafx.obj : 生成されるプリコンパイル済タイプ情報
#include <math.h>
#include "stdafx.h"
|
■ ClassWizradを呼び出しViewクラスに左クリックイベント関数と、タイマー関数を追加

※C***View → WM_LBUTTONDOWN → 関数を追加
※C***View → WM_TIMER → 関数を追加
■ 追加した左クリックイベント関数(OnLButtonDown)にソースを追加
void CTest09View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください
//タイマー開始
SetTimer(1,1000,NULL);
CView::OnLButtonDown(nFlags, point);
}
|
■ OnTimer関数にソースを追加
void CTest09View::OnTimer(UINT nIDEvent)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください
//------時間取得(START)--------
//時間、分、秒の変数宣言
int secnd;
int min,min_;
int hour;
//誤差修正用配列の初期設定
int gosa[61] = {45,46,47,48,49,50,51,52,53,54,
55,56,57,58,59,60,1,2,3,4,
5,6,7,8,9,10,11,12,13,14,
15,16,17,18,19,20,21,22,23,24,
25,26,27,28,29,30,31,32,33,34,
35,36,37,38,39,40,41,42,43,44
};
//CTimeクラスのTime_Nowオブジェクトを作成
CTime Time_Now;
//現在の時間を取得し作成したオブジェクトに格納
Time_Now = CTime::GetCurrentTime();
//CString型のch変数を作成
CString ch;
//秒を取得
ch = Time_Now.Format("%S");
secnd = atoi(ch.GetBuffer(lstrlen(ch)));
secnd = gosa[secnd];
//分を取得
ch = Time_Now.Format("%M");
min_ = atoi(ch.GetBuffer(lstrlen(ch)));
min = gosa[min_];
//時間を取得
ch = Time_Now.Format("%H");
hour = atoi(ch.GetBuffer(lstrlen(ch)));
if(hour > 12){
hour = hour -12;
}
hour = hour * 5;
hour = hour + int(min_ / 12);
hour = gosa[hour];
//------時間取得(END)----------
//デバイスコンテキストのポインタ宣言
CDC* pDC;
//デバイスコンテキストの取得
pDC = GetDC();
//楕円を描画
CRect obj01(0,0,201,201);
pDC->Ellipse(obj01);
//時間表示
pDC->TextOut(187,92,"3");//3時
pDC->TextOut(97,180,"6");//6時
pDC->TextOut(6,92,"9"); //9時
pDC->TextOut(92,3,"12");//12時
//-------秒針 (ここから)---------
int secnd_x;
int secnd_y;
double ang = 2.0 * 3.141592653 * secnd / 60;
secnd_x = int(95 * cos(ang) + 100);
secnd_y = int(95 * sin(ang) + 100);
if(secnd == 45){
secnd_x++;
}
pDC->MoveTo(100,100);
pDC->LineTo(secnd_x,secnd_y);
//-------秒針 (ここまで)---------
//-------分針 (ここから)---------
int min_x;
int min_y;
double ang_min = 2.0 * 3.141592653 * min / 60;
min_x = int(90 * cos(ang_min) + 100);
min_y = int(90 * sin(ang_min) + 100);
if(min == 45){
min_x++;
}
pDC->MoveTo(100,100);
pDC->LineTo(min_x,min_y);
//-------分針 (ここまで)---------
//-------時針 (ここから)---------
int hour_x;
int hour_y;
double ang_hour = 2.0 * 3.141592653 * hour / 60;
hour_x = int(60 * cos(ang_hour) + 100);
hour_y = int(60 * sin(ang_hour) + 100);
if(hour == 45){
hour_x++;
}
pDC->MoveTo(100,100);
pDC->LineTo(hour_x,hour_y);
//-------時針 (ここまで)---------
//デバイスコンテキストの開放
ReleaseDC(pDC);
//画面描画
OnPaint();
CView::OnTimer(nIDEvent);
}
|
■ 以上コンパイルすれば完成

画面を左クリックするとパソコンの時間を取得し時計が動き出します
ちょっとスッキリしないプログラムですが、これに手を加えるとしっかりしたアナログ時計が出来るかもしれません。(^^;
ちなみに私の作った物はこちらからDLできます
SetTimer関数の時間設定は正確ではないようなので秒針がずれる事があります。
パソコンの時間を取得して表示していますので時間のずれ自体はありません。
最低限の関数での作成例ですので予めご了承ください。
|
|
 |