Skip to content

MS_PostMessage

nishi_74322014 edited this page Aug 21, 2026 · 1 revision

PostMessage

概要

メッセージループにキューイングする。

API

  • PostMessage
  • PostThreadMessage
  • PostQuitMessage
  • ,etc.

補足(3 つの Post 系 API の使い分け): 名前が似ているが、
宛先と役割が異なる

【PostMessage(hWnd, ...)】★
   ・宛先は【ウィンドウ】
   ・そのウィンドウを作ったスレッドのキューに積まれる
   ・hWnd に【HWND_BROADCAST】を渡すと
     全トップレベル ウィンドウに配送される
     → 設定変更の通知(WM_SETTINGCHANGE)等で使う

【PostThreadMessage(threadId, ...)】
   ・宛先は【スレッド】(ウィンドウを持たなくてよい)
   ・受け側は GetMessage の hWnd が NULL になる
     → 【DispatchMessage しても誰にも届かない】★
     → ループ内で msg.message を直接見て処理する
   ・相手にメッセージ キューが無いと【失敗する】
     → 受け側で先に PeekMessage を空打ちして
       キューを作らせておくのが定石 ★

【PostQuitMessage(exitCode)】
   ・自スレッドのキューに【WM_QUIT】を積む
   ・GetMessage が 0 を返し、メッセージ ループが終わる
   ・通常は WM_DESTROY の処理内で呼ぶ
   ・【WM_QUIT はキューに積まれない特別扱い】★
     (フラグとして扱われ、他のメッセージより後で取り出される)

補足(PostMessage の落とし穴): 「積むだけ」ゆえの注意点がある。

【① ポインタを渡してはいけない】★★
   PostMessage(h, WM_APP, 0, (LPARAM)&localStruct);
     → 呼び出し元は【すぐ次に進む】
     → 受け側が処理する頃には
       ローカル変数が【既に無い】
     → 【解放済みメモリへのアクセス】

   【正しくは】
     ・ヒープに確保して渡し、
       【受け側が解放する】と決めておく
     ・または SendMessage(同期)を使う

【② 戻り値は「積めたか」だけ】
   ・TRUE = キューに積めた
   ・処理が成功したかは【分からない】
   ・結果が要るなら
     → SendMessage
     → または完了通知を Post し返す

【③ キューには上限がある】★
   ・既定で【10,000 件】程度
   ・受け側がループを回していないのに
     Post し続けると【溢れて捨てられる】
   ・タイマーで高頻度に Post する設計は危険

【④ UIPI(Vista 以降)】
   ・低い整合性レベル → 高いプロセスへの Post は
     【黙って失敗する】★
   ・必要なら ChangeWindowMessageFilterEx で
     受け側が明示的に許可する
【.NET から使う場合】
   ・UI スレッドへ処理を移すだけなら
     【PostMessage を自分で呼ぶ必要はない】★
     → Control.BeginInvoke(Windows Forms)
     → Dispatcher.BeginInvoke(WPF)
     → いずれも内部でメッセージをポストしている
     → 詳細は [コントロールのInvokeメソッド](MS_ControlInvoke)

   ・カスタム メッセージを使うなら
     WM_APP(0x8000)〜 0xBFFF の範囲を使う
     → WM_USER(0x0400)〜 は
       【コントロールが独自に使っている】ため
       他人のウィンドウに送ると誤動作する ★

参考

移行メモ(リンク切れ): 移行元の msdn.microsoft.com/ja-jp/library/cc410952.aspx
MSDN ライブラリの廃止により到達しないため、
Microsoft Learn の現行ページに差し替えた。


Tags: 移行, Windows, ウィンドウ・システム, プログラミング

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally