タイマーの使い方
タイマーは、結構お世話になることが多いと思います。
定期的に画面を更新したりするときには、必要不可欠でしょう。
MS-DOSでプログラミングをされた人はおわかりになると思いますが、こういうときはたいていループを作って処理したものだと思います。
そして、その中で、キーなどの入力を待つ。
でも、Windowsではその手は使えません。同時に他のアプリケーションが動いているかもしれないからです。
タイマーを使うのは結構簡単です。
CWndのメンバ関数のSetTimerという関数を使います。
関数の定義は次のようになっています。
UINT SetTimer( UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD) );
ここでは、3番目の引数についてはいっさいふれません。なぜなら、僕が知らないからです。(^^;
興味のある方は調べてみて下さい。
nIDEvent : タイマー識別子です。0以外の値を指定します。
nElapse : タイムアウト値をミリ秒単位で指定します。
lpfnTimer : タイムアウトによって発生するWM_TIMERメッセージを処理する
アプリケーション側が用意したコールバック関数を指定するようですが、
何に使うのかよくわかりません。
NULLを指定しておけば、WM_TIMERメッセージは、CWndオブジェクトによって処理されるようです。
戻り値は、成功した場合はタイマー識別子、失敗したときは、0が返ります。
SetTimerを記述するクラスは、CWndから派生されたクラスならどれでもかまいません。
目的とする処理にあったクラスに記述して下さい。
また、タイマーの動作を開始する時期も問題ですが、これは、ウィンドウが作成されてから、破壊されるまでのどの時点でもかまいません。
ウィンドウが存在する間、ずっとタイマーをかけておきたいのなら、ウィンドウが作成されてすぐにSetTimerを呼び出せばいいことになります。
なお、後述するKillTimerを使えば、タイマーを取り消すこともできます。
ウィンドウが生成される時のSetTimerの呼び出しのタイミングですが、
一番最初のチャンスはWM_CREATE メッセージを処理するときです。
具体的には、OnCreate()をオーバーライドします。このメンバ関数は、ウィンドウの作成直後、ウィンドウが可視になる前にフレームワークから呼び出されます。
なお、以降の例では、AppWizardでドキュメント・ビュー・アーキテクチャのアプリケーションを作成し、
CMainFrameクラスでタイマーを設定すると仮定します。ドキュメント・ビュー・アーキテクチャでは、必ずCMainFrameクラスがあるので説明しやすいので。
他のCWndから派生されたクラスにタイマーを設定するときは、適宜読み替えて下さい。
ClassWizardを使えば、オーバーライドは簡単にできます。
ClassWizardのメッセージマップでクラス名にCMainFrameを選んで、メッセージ欄のWM_CREATEをダブルクリックし、OKを押すだけです。図
そして、追加された関数に、SetTimerの記述を追加します。
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
SetTimer(1, 1000, NULL);
return 0;
}
ここでは、タイマーの間隔を1秒、タイマー識別子を1にしています。
SetTimerを呼び出すと、その後指定した時間間隔でWM_TIMERメッセージが発生します。
そのメッセージを処理することで、タイマーを処理できます。
メッセージを処理するには、OnTimer()メンバ関数をオーバーライドします。
OnCreateをオーバーライドしたときと同じようにして、OnTimerをオーバーライドして下さい。
関数の例を示します。
void CMainFrame::OnTimer(UINT nIDEvent)
{
if(nIDEvent==1){
; //タイマーの処理
} else
CFrameWnd::OnTimer(nIDEvent);
}
引数として、タイマー識別子が渡されてきます。
ここでは、タイマー識別子が1なので、タイマー識別子を調べ、1だったら、目的の処理を行います。
タイマーを複数設定した場合、タイマー識別子で処理を分けられます。
タイマーがいらなくなった場合、KillTimerでタイマーを削除します。
関数の定義です。
BOOL KillTimer( int nIDEvent );
nIDEventには、SetTimerで渡したタイマー識別子を渡します。
E-Mail:wbs03748@mail.wbs.ne.jp
質問・感想などのメールはこちらへ。