キューへのメッセージの送信

SendMessage()

指定のメッセージをウィンドウへ送信できます。この関数はウィンドウのウィンドウ プロシージャを呼び、それがメッセージの処理を終えるまで制御を返しません。

LRESULT SendMessage(
  HWND   hWnd,
  UINT   Msg,
  WPARAM wParam,
  LPARAM lParam
);
SendMessage function (winuser.h) | Microsoft Learn

戻り値で、処理の結果を受け取れます。

PostMessage

指定のウィンドウを作成したスレッドに関連付けられているメッセージ キューに、メッセージを追加できます。この関数は、スレッドがメッセージを処理するのを待たずに制御を戻します。

BOOL PostMessageA(
  HWND   hWnd,
  UINT   Msg,
  WPARAM wParam,
  LPARAM lParam
);
PostMessageA function (winuser.h) | Microsoft Learn

関数が成功したならば、ゼロではない値が返されます。

SetTimer()

一定時間ごとにWM_TIMERメッセージをポストさせ、処理をくり返せます。

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

lpTimerFuncをNULLとするとWM_TIMERメッセージがポストされます。これに次の形式のコールバック関数を指定すれば、代わりに指定の関数を呼び出させられます。

VOID CALLBACK TimerProc(
  HWND hwnd,         // ウィンドウのハンドル
  UINT uMsg,         // WM_TIMER メッセージ
  UINT_PTR idEvent,  // タイマの識別子
  DWORD dwTime       // 現在のシステム時刻
  );
TimerProc 関数 | MSDN

サンプルコード

WM_TIMERメッセージで処理するならば、次のようにします。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_CREATE:
        // タイマを作成する
        SetTimer(hWnd, 1, 500, (TIMERPROC)NULL);
        break;

    case WM_TIMER:
        // タイムアウト時の処理
        break;

    case WM_PAINT:
        // 描画領域を更新する ※1
        hdc = BeginPaint(hWnd, &ps);
        EndPaint(hWnd, &ps);
        break;

    case WM_DESTROY:
        // タイマを破棄する
        KillTimer(hWnd, 1);

        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

※1 WM_PAINTに応答しながら何も処理をしないと、コールバックの呼び出しやWM_TIMERメッセージのポストが行われなくなります。

指定のコールバック関数で処理するならば、次のようにします。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_CREATE:
        // タイマを作成する
        SetTimer(hWnd, 1, 500, (TIMERPROC)TimerProc);
        break;

    case WM_PAINT:
        // 描画領域を更新する ※1
        hdc = BeginPaint(hWnd, &ps);
        EndPaint(hWnd, &ps);
        break;

    case WM_DESTROY:
        // タイマを破棄する
        KillTimer(hWnd, 1);

        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
    // タイムアウト時の処理
}

参考

参考書

Microsoft Learnから検索