CWinApp::OnIdle
更新 : 2007 年 11 月
アイドル処理を行う場合は、このメンバ関数をオーバーライドします。
virtual BOOL OnIdle(
LONG lCount
);
パラメータ
- lCount
アプリケーションのメッセージ キューが空のときに、OnIdle が呼び出されるたびに増分されるカウンタ。このカウンタは、新しいメッセージが処理されるたびに 0 にリセットされます。lCount は、アプリケーションがメッセージを処理していない相対的なアイドル状態の時間を調べるために使うことができます。
戻り値
アイドル処理時間がさらに必要な場合は 0 以外を返します。不要な場合は 0 を返します。
解説
アプリケーションのメッセージ キューが空のとき、既定のメッセージ ループで OnIdle 関数が呼び出されます。独自のバックグラウンド アイドル処理を呼び出すには、自身でオーバーライドした関数を使用します。
OnIdle は、アイドル処理時間が必要ないことを示す 0 を返します。パラメータ lCount は、メッセージ キューが空のときに、OnIdle が呼び出されるたびに増分され、新しいメッセージが処理されるたびに 0 にリセットされます。このカウントに基づいて、別のアイドル処理ルーチンを呼び出すことができます。
以下に、アイドル ループ処理を要約します。
Microsoft Foundation Class ライブラリのメッセージ ループはメッセージ キューを調べ、未処理のメッセージが見つからないと、アプリケーション オブジェクトの OnIdle を呼び出し、引数 lCount に 0 を渡します。
OnIdle は、何かの処理をした後に 0 以外の値を返し、続きの処理を行うために再度呼び出される必要があることを示します。
メッセージ ループが再度メッセージ キューを調べます。メッセージがない場合は、引数 lCount を増分して、再度 OnIdle を呼び出します。
最後に、OnIdle はすべてのアイドル タスクの処理を終了し、0 を返します。これが、メッセージ キューから次の新しいメッセージを受信するまで OnIdle の呼び出しを停止するようにメッセージ ループに指示します。新しいメッセージを受信した時点で、引数を 0 に設定してアイドル サイクルを再開します。
OnIdle から復帰するまで、アプリケーションは入力を処理できないので、OnIdle では時間のかかる処理はしないでください。
メモ : |
---|
OnIdle 関数の既定の実装は、メニュー項目やツール バー ボタンなどのコマンド ユーザー インターフェイス オブジェクトを更新し、内部データ構造の後処理を行います。そのため、OnIdle 関数をオーバーライドするときは、オーバーライドした OnIdle 関数で lCount を渡して CWinApp::OnIdle を呼び出す必要があります。最初に、(基本クラスの OnIdle が 0 を返すまで) すべての基本クラスのアイドル処理を呼び出してください。基本クラスの処理が終わる前に作業をする必要があるときは、作業に必要な妥当な lCount の値が選択できるように、基本クラスの実装を調査してください。 |
メッセージ キューからメッセージを取得するたびに OnIdle を呼び出す必要がない場合は、CWinThreadIsIdleMessage をオーバーライドできます。アプリケーションで非常に短い時間のタイマを設定したときや、システムが WM_SYSTIMER メッセージを送信中のときは、OnIdle が繰り返し呼び出されるため、パフォーマンスが低下します。
使用例
次の 2 つの例は、OnIdle の使い方を示しています。最初の例では、2 つアイドル タスクを引数 lCount を使ってどのように優先処理するかを示します。最初のタスクは優先度が高く、可能なときは常に処理します。2 番目のタスクは重要度は低く、長い間入力がされなかったときにだけ処理します。基本クラスの OnIdle の呼び出しに注意してください。2 番目の例では、異なる優先度を持つアイドル タスクのグループを管理します。
BOOL CMyApp::OnIdle(LONG lCount)
{
BOOL bMore = CWinApp::OnIdle(lCount);
if (lCount == 0)
{
TRACE(_T("App idle for short period of time\n"));
bMore = TRUE;
}
else if (lCount == 10)
{
TRACE(_T("App idle for longer amount of time\n"));
bMore = TRUE;
}
else if (lCount == 100)
{
TRACE(_T("App idle for even longer amount of time\n"));
bMore = TRUE;
}
else if (lCount == 1000)
{
TRACE(_T("App idle for quite a long period of time\n"));
// bMore is not set to TRUE, no longer need idle
// IMPORTANT: bMore is not set to FALSE since CWinApp::OnIdle may
// have more idle tasks to complete.
}
return bMore;
// return TRUE as long as there are any more idle tasks
}
2 番目の例
// In this example, four idle loop tasks are given various
// opportunities to run:
// Task1 is always given a chance to run during idle time, provided
// that no message has queued up while the framework was processing
// its own idle loop tasks (at lCount levels 0 and 1).
// Task2 is given a chance to run only if Task1 has already run,
// provided that no message has queued up while Task1 was running.
// Task3 and Task4 are given a chance to run only if both Task1 and
// Task2 have already run, and no message has queued up in the mean
// time. If Task3 gets its chance to run, then Task4 always gets
// a chance to run immediately after Task3.
BOOL CMyWinApp::OnIdle(LONG lCount)
{
// In this example, as in most applications, you should let the
// base class CWinApp::OnIdle complete its processing before you
// attempt any additional idle loop processing.
if (CWinApp::OnIdle(lCount))
return TRUE;
// The base class CWinApp::OnIdle reserves the lCount values 0
// and 1 for the framework's own idle processing. If you wish to
// share idle processing time at a peer level with the framework,
// then replace the above if-statement with a straight call to
// CWinApp::OnIdle; and then add a case statement for lCount value
// 0 and/or 1. Study the base class implementation first to
// understand how your idle loop tasks will compete with the
// framework's idle loop processing.
switch (lCount)
{
case 2:
Task1();
return TRUE; // next time give Task2 a chance
case 3:
Task2();
return TRUE; // next time give Task3 and Task4 a chance
case 4:
Task3();
Task4();
return FALSE; // cycle through the idle loop tasks again
}
return TRUE;
}
必要条件
ヘッダー : afxwin.h