アークピットのホームページに戻る

WinAPIトピックのトップページに戻る

APIトピックの各章に移動する

ダウンロードのページに移動する
ダウンロードができ
ない場合の対処法
 

ページ移動

2-4-6. MDIのウィンドウプロシージャとメッセージループ

 フレームウィンドウ(アプリケーションのメインウィンドウ)の作成は、MDIスタイルでも、SIDのメインウィンドウを作成する手順と何ら変わりはありません。ただしメッセージループとウィンドウプロシージャはMDIの場合は、やや異なります。

MDIのメッセージループ

 MDIにはキーボードアクセラレータ機能があります。よってメッセージループに、TranslateMDISysAccel 関数を追加します。
    while (GetMessage(&msg,NULL,0,0))
    {
        if (!TranslateAccelerator(hWndMain,hAccel,&msg) &&
                          !TranslateMDISysAccel(hWndClient,&msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
 TranslateMDISysAccel 関数は、キー関係のメッセージを検査して、もしMDI操作用のキーならそれに対する処理を行い、真を返します。その場合の対象のウィンドウパラメータは、クライアントウィンドウです。MDIはクライアントウィンドウに機能の大部分を負っています。

MDIのフレームウィンドウプロシージャ

 フレームウィンドウのウィンドウプロシージャ(ApMdiProc)の構成は、MDIもSDIも似ていますがが、下記の1点だけ違います。
LRESULT CALLBACK ApMdiProc(HWND hWnd,UINT uMsg
                                    ,WPARAM wParam,LPARAM lParam)
{
    static HINSTANCE  hRtfLib;  // リッチテキストDLLのインスタンスのハンドル
    static CLIPFORMAT cfRTF;    // クリップボードのフォーマット

    switch (uMsg)
    {
        case WM_CREATE:         // メインウィンドウの新規作成
                : (他のコード)
    }
    return DefFrameProc(hWnd,hWndClient,uMsg,wParam,lParam);
}
 SDIの場合は、DefWindowProc 関数が、省略時のプロシージャ処理ですが、MDIの場合は、DefFrameProc 関数がそれに対応します。この関数は、MDI機能をフックして、それに対する処理を行い、残りを DefWindowProc 関数に渡しています。

DefFrameProc のメッセージの対応

 一部のメッセージについては、フレームウィンドウプロシージャは、メッセージを処理した場合でもそのメッセージをデフォルトプロシージャに渡さなければなりません。そのようなメッセージを次の表に示します。

メッセージ 対 応(DefFrameProc 関数の処理)
WM_COMMAND ユーザーが選択したMDI子ウィンドウをアクティブ化します。このメッセージは、ユーザーがMDIフレーム ウィンドウの[ウィンドウ]メニューからMDI子ウィンドウのタイトルを選択したときに送られます。このメッセージで送られるウィンドウ識別子は、アクティブ化するMDI子ウィンドウを識別します。
WM_MENUCHAR ユーザーが[Alt]+[-](マイナス)キーを押したときに、アクティブなMDI子ウィンドウのコントロールメニューをオープンします。
WM_SETFOCUS MDIクライアントウィンドウにキーボードフォーカスを設定します。クライアントウィンドウは、キーボードフォーカスをアクティブなMDI子ウィンドウに渡します。
WM_SIZE MDIクライアントウィンドウがフレームウィンドウの新しいクライアント領域に収まるようにクライアントウィンドウのサイズを変更します。フレームウィンドウプロシージャは、MDIクライアントウィンドウのサイズを独自に変更する場合、このメッセージを、DefFrameProc 関数に渡さないでください。

ページ移動