では、さっそく実行してみて下さい。確かに「ファイル」「終了」を選択すると 望み通りの結果となります。では、右上の「バッテン印」をクリックしてみて下さい。 または、左上についているアイコンをクリックして「閉じる」を選択して下さい。 いきなり、プログラムが終了してしまいましたね。これではメニューバーから 「終了」を選択しない限りいきなり終了するプログラムとなってしまいます。LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { int id; switch (msg) { case WM_COMMAND: switch(LOWORD(wParam)) { case IDM_END: id = MessageBox(hWnd, (LPCSTR)"終了しますか", (LPCSTR)"終了確認", MB_OKCANCEL); if (id == IDCANCEL) return (0L); SendMessage(hWnd, WM_CLOSE, 0, 0L); break; ・・以下省略
では、どうすればよいのでしょうか。 ウィンドウがクローズされようとしているとき WM_CLOSEメッセージが発生します。 これをウィンドウプロシージャで処理しないときは DefWindowProc関数がDestroyWindow関数を呼び出しウィンドウを破棄します。
従って、上のプログラムはメニューバーから「終了」を選んだとき の処理はしていますが、「バッテン印」やら「システムメニュー」の 「閉じる」を選択したときに発生するWM_CLOSE メッセージを処理していないためこれがDefWindowProc関数にわたってしまい いきなりプログラムが終了してしまいます。
従ってウィンドウプロシージャの中で自前でWM_CLOSEメッセージを 処理すればよいということになります。この場合WM_CLOSEメッセージは DefWindowProc関数にわたらないので自分でDestroyWindow関数を 呼び出す必要があります。
プロシージャを上のように修正すればいきなり終了しない プログラムとなります。LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { int id; switch (msg) { case WM_COMMAND: switch(LOWORD(wParam)) { case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0L); break; case IDM_TEST: MessageBox(hWnd, (LPCSTR)"テストが押されました", (LPCSTR)"test", MB_OK); break; case IDM_ABOUT: MessageBox(hWnd, (LPCSTR)"ABOUTが押されました", (LPCSTR)"About", MB_OK); break; } break; case WM_CLOSE: id = MessageBox(hWnd, (LPCSTR)"終了しますか", (LPCSTR)"終了確認", MB_OKCANCEL | MB_ICONQUESTION); if(id == IDOK) DestroyWindow(hWnd); return (0L); case WM_DESTROY: PostQuitMessage(0); break; case WM_PAINT: ShowMyText(hWnd); break; default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } return (0L); }
バッテン印をクリックしてもめでたく終了確認メッセージ
ボックスが出てきます。MessageBox関数の最後の引数を
MB_OKCANCEL | MB_ICONQUESTIONとしたので
クエッションマークのアイコンがつきましたね。
他にもいろいろあるので試してみて下さい。
Update Mar/27/1997 By Y.Kumei