さて、前回は Dialog を使ってパラメータの設定することをやりましたが、 ここでは Main Window にボタンを付けることをやってみましょう。
Windows には、ボタンをはじめ Control と呼ばれる いくつかの Window Class が用意されています。 これらは主に Dialog で使用されますが、これらもまた Window で すので、自分の作った Window 上に Child Window として置く ことも可能です。
具体的には Parent Window を作った後、CreateWindow() を 使って、Child Window を生成します。次のコードは、Client Window の 左上隅に幅 100 ピクセル、高さ 24 ピクセルの "Push Me" と書かれた ボタンを置く例です。
: int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { : /* Create our window. */ hwnd = CreateWindow( MY_CLASS_NAME, MY_WINDOW_TITLE, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, (HWND)NULL, (HMENU)NULL, hInstance, (LPVOID)NULL ); : /* Create Button */ hButtonWnd = CreateWindow( "BUTTON", "Push Me", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE, 0, 0, 100, 24, hwnd, (HMENU)NULL, hInstance, (LPVOID)NULL );コントロールに何か変化があった場合は Parent Window に対し、 WM_COMMAND メッセージが送られます。この時、 LPARAM に Child Window のハンドルが設定されています。例えば、ボタンがクリック された場合にはメッセージ ID として BN_CLICKED が送られて きます。従って、WndProc() の書き方は、
LRESULT CALLBACK WndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { WORD wNotifyCode; WORD wID; HDC hdc; PAINTSTRUCT ps; HINSTANCE hInst; switch( uMsg ) { case WM_COMMAND: wNotifyCode = HIWORD( wParam ); wID = LOWORD( wParam ); switch( wID ) { case ID_FILE_EXIT: DestroyWindow( hwnd ); break; case ID_FILE_CMND: hInst = (HINSTANCE)GetWindowLong( hwnd, GWL_HINSTANCE ); DialogBox( hInst, "MyCmndDlg", hwnd, (DLGPROC)MyCmndProc ); break; case BN_CLICKED: if( (HWND)lParam == hButtonWnd ) { : /* Action code for the button pressed event */ : } break; default: MessageBox( NULL, "Sorry. Not implemented yet.", "My Program", MB_OK ); break; } break; :のようになるでしょう。
さて、上の書き方でも処理はできますが、Child Window のハンドルで見る必要 があるという点が厄介です。もう一つの方法として、Child Window を生成する 際に、ID を付与しておくという方法があります。ID を付与する場合は、 CreateWindow() の HMENU の引数として与えます。例えば MY_BUTTON_ID という値を付与するには
#define ID_MY_BUTTON 12345 : /* Create Button */ hButtonWnd = CreateWindow( "BUTTON", "Push Me", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE, 0, 0, 100, 24, hwnd, (HMENU)ID_MY_BUTTON, hInstance, (LPVOID)NULL );とします。そうすると、ボタンが押された時、メッセージ ID として ID_MY_BUTTON を伴ってきますので、DialogBox を通じたメッセージと同じように処理することが できます。