MFCの基礎 - プログラムの終了
概要
Windows APIにおけるプログラムの終了処理の流れを記載する。
ここでは、プログラムをメニュー([ファイル] - [終了])から終了する方法を記載する。
ウィンドウの破棄とプログラムの終了
[ファイル] - [終了]を選択した時のイベントハンドラで、SendMessage関数を使用してメインウィンドウにWM_CLOSEを発行する。
ここで、SendMessage関数のプロトタイプ宣言は以下の通りである。
LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
hWndで指定したウィンドウに、メッセージMsgを送る。メッセージに付随するデータがある場合は、wParamおよびlParamに設定する。
ここでは、WM_CLOSEを発行しているが、WM_CLOSEの場合は、wParamおよびlParamは特に使用しないので0を指定する。
サンプルコードでは、WM_CLOSEのイベントハンドラでは、MessageBox関数でメッセージを表示している。
"Are you sure you want to quit thie program?"メッセージにおいて、[はい]ボタンを押下した場合、MessageBox関数は[IDYES]を返す。
ウィンドウを破棄するためには、DestroyWindow関数を使用する。
BOOL DestroyWindow(HWND hWnd);
DestroyWindow関数は、hWndで指定したウィンドウに、WM_DESTROYを発行してそれを破棄する。
メニューのイベントハンドラで終了の確認を行わない理由は、
[閉じる]ボタンが押下されて終了処理を行う場合、自動的にWM_CLOSEがウィンドウに発行されるからである。
このため、メニューのイベントハンドラでは、WM_CLOSEを発行するだけにして、WM_CLOSEのイベントハンドラでウィンドウの破棄を行う。
WM_DESTROYのイベントハンドラでは、PostQuitMessage関数を使用して、WM_QUITをメッセージキューにポストする。
また、PostQuitMessage関数の引数として、プログラムの終了コードを渡すことができる。ここで渡した値は、WM_QUITのwParam値となる。
WM_QUITを受け取るとGetMessage関数がFALSEとなるため、メッセージループが終了する。
下図に、プログラムの終了確認の流れを示す。
サンプルコード
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int id;
HWND hwndCtl;
UINT codeNotify;
PAINTSTRUCT ps;
HDC hdc;
RECT rect;
switch(uMsg)
{
case WM_CLOSE:
if(IDYES == MessageBox(hwnd, TEXT("Are you sure you want to quit this program?"), TEXT("Confirmation"), MB_YESNO))
{
DestroyWindow(hwnd);
}
break;
case WM_COMMAND:
id = (int) LOWORD(wParam);
hwndCtl = (HWND) lParam;
codeNotify = (UINT) HIWORD(wParam);
switch(id)
{
case IDM_FILE_EXIT:
SendMessage ( hwnd, WM_CLOSE, 0, 0 );
break;
case IDM_HELP_ABOUT:
::MessageBox(NULL, TEXT("Hello, About!"), TEXT("About This Program"), MB_OK);
break;
}
break;
case WM_PAINT:
hdc = BeginPaint ( hwnd, &ps );
GetClientRect ( hwnd, &rect );
DrawText(hdc, TEXT("Hello, world!"), -1, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
EndPaint( hwnd, &ps );
break;
case WM_SIZE:
InvalidateRect( hwnd, NULL, TRUE );
break;
case WM_DESTROY:
::PostQuitMessage( 0 );
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
break;
}
return 0;
}