メッセージループとWinProc(ウィンドウプロシージャ)の関係
はじめに:パソコンの中の「受付カウンター」だと思おう
ゲームやアプリのウィンドウは、「人の出入りがある受付カウンター」だと思ってください。この受付では次のようなことが起きます:
誰かがマウスをクリックした
キーボードを押した
ウィンドウを閉じようとしたこういった出来事(イベント)は、「メッセージ」としてパソコン内に届けられます。
1. メッセージとは?
Windowsは、「○○が起きましたよ」という通知をメッセージという形で送ってきます。
たとえば:
- 「WM_KEYDOWN」 → キーボードが押された
- 「WM_LBUTTONDOWN」 → マウスの左ボタンが押された
- 「WM_DESTROY」 → ウィンドウを閉じようとしている
2. メッセージループ:ポスト(郵便受け)をチェックし続ける
アプリの中には「郵便受け(メッセージキュー)」があり、そこにメッセージがどんどん届きます。 メッセージループは、その郵便受けをずっと見張って、届いたら処理に回す係です。
3. WinProc(ウィンドウプロシージャ):メッセージを受け取って処理する関数
WinProcは、受付係(または配達先の人)です。 メッセージループから渡された「出来事(メッセージ)」に応じて、どう処理するかを決めます。
return DefWindowProc(hwnd, msg, wParam, lParam); // 他はWindowsに任せる }
4. たとえ話でまとめると…
| 実体 | たとえ |
|---|---|
| メッセージ | 郵便や伝票:「何が起きたか」の情報 |
| メッセージループ | 郵便受けを見張る人+仕分け係 |
| DispatchMessage | 書類を担当者に回す作業 |
| WinProc | 実際に中身を読んで処理する人 |
5. よくある勘違いと注意点
- 「WinProcはずっと動いてる」 → × 間違い!
- WinProcは、何かメッセージが届いたときだけ呼ばれる関数です。
- ゲームの描画やロジック処理はWinProcに書く? → × 基本はメッセージループのelse側に書く!
- WinProcは「イベント処理」、ゲームの更新は「メインループ内で別にやる」が原則。
6. まとめ:全体の流れイメージ図
[ユーザーがマウスをクリック]
↓
[WindowsがWM_LBUTTONDOWNメッセージを送る]
↓
[メッセージループでPeekMessageが受け取る]
↓
[DispatchMessageでWinProcに転送]
↓
[WinProcが switch(msg) で判定して処理]
まとめ
| 要素 | 役割 | イメージ |
|---|---|---|
| WinMain | ゲームの開始点 | C++のmain関数のようなもの |
| RegisterClassEx | ウィンドウの設計図を作る | 図面を描く |
| CreateWindowEx | ウィンドウを作る | 部屋を建てる |
| ShowWindow | 表示命令 | 部屋を見せる |
| メッセージループ | 出来事の監視と処理 | 郵便の仕分け係 |
| WinProc | 出来事に応じた処理 | 郵便に返事する係 |