>> WINAPI入門トップに戻る

タイマー

今回はタイマーについて説明します。

タイマーを設定すると一定の間隔で自動で処理させることができます。
方法は二通りあり、一定時間後にタイマーイベントを発生させるか、
一定時間ごとに指定した関数を実行するかの二つです。
タイマーの設定にはSetTimer関数を使います。
関数の定義は以下の通りです。

UINT_PTR SetTimer(
HWND hWnd, // ウィンドウのハンドル
UINT_PTR nIDEvent, // タイマの識別子
UINT uElapse, // タイムアウト値
TIMERPROC lpTimerFunc // タイマのプロシージャ
);

関数が成功すると、タイマー識別子が返って来ます。失敗すると0が返ります。
この識別子はタイマーを止める為に使う、killTimer関数
ウィンドウハンドルと共に渡すことでタイマーを止めることができます。
第二引数のタイマー識別子というのはユニークな任意の整数値を指定して下さい。
タイムアウト値はミリ秒で指定して下さい。
1000ミリ秒なら1秒おきにタイマーイベントが発生します。
第四引数ですが、ここには関数を指定するか、NULLを指定します。
関数を指定した場合は、その指定した関数が第三引数で設定したミリ秒ごとに実行され続けます。
NULLを指定した場合は、WM_TIMERというウィンドウメッセージが
一定時間ごとに送信されます。
そのWPARAMには第二引数で指定したタイマー識別子が入っています。

以下のコードを確認して下さい。

#include <windows.h>
#include <stdio.h>

#define MSG(m) {\
	MessageBoxA(NULL,m,NULL,MB_OK);}

//ウィンドウハンドル
HWND hwnd;
//インスタンスハンドル
HINSTANCE hinst;

//ウィンドウ横幅
#define WIDTH 500
#define HEIGHT 300

#define TIMER_ID 1

LRESULT CALLBACK WinProc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp)
{
static int count=0;
char buf[1000];
	switch(msg){
		case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
		case WM_CREATE:
			SetTimer(hwnd,TIMER_ID,1000,NULL);
			return 0;
		case WM_TIMER:
			if(wp==TIMER_ID){
				sprintf(buf,"%d秒経過",count);
				SetWindowText(hwnd,buf);
				++count;
				return 0;
			}
			break;

	}
	return DefWindowProc(hwnd,msg,wp,lp);
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
	MSG msg;
	WNDCLASS wc;

	wc.style=CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc=WinProc;
	wc.cbClsExtra=wc.cbWndExtra=0;
	wc.hInstance=hInstance;
	wc.hCursor=wc.hIcon=NULL;
	wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
	wc.lpszClassName="test";
	wc.lpszMenuName=NULL;
	
	if(!RegisterClass(&wc)){
		MSG("クラスの登録失敗");
		return -1;
	}

	hwnd=CreateWindowA("test","テストウィンドウ",WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
		0,0,400,400,NULL,NULL,hInstance,NULL);

	if(hwnd==NULL){
		MSG("ウィンドウ作成失敗");
		return -1;
	}

	//インスタンスハンドル
	hinst=hInstance;

	//エラーチェック用変数
	int check;

	while(check=GetMessage(&msg,NULL,0,0)){
		if(check==-1){
			break;
		}
		DispatchMessage(&msg);
	}

	//クラス解放
	UnregisterClass("test",hinst);

	return 0;
}

これを実行すると下記のような画面が表示されます。

上記のコードでは1000ミリ秒(1秒)おきにタイマーイベントを発生させ、
カウントを足していき、それをウィンドウタイトルに表示しています。
今回は第四引数にNULLを指定しているので、WM_TIMERメッセージが飛んできています。
関数を指定すればその関数が実行されることになります。
これを使いこなせば色々と処理を自動で動かせますね。

今回の説明は以上です。
次回はスレッドについて説明します。


>> 【スレッド】に進む
>> WINAPI入門トップに戻る