MFCの基礎 - プログラムの終了

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動

概要

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となるため、メッセージループが終了する。

下図に、プログラムの終了確認の流れを示す。

WindowsProgram EndProcess 1.png



サンプルコード

 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;
 }