• 締切済み

MDIでのダイアログ生成

VC++2005でMDIアプリケーションを作成しています。 ダイアログベースでは、DoModal()にてダイアログを生成していましたが、 MDIでのダイアログ生成の方法が分かりません。。 調べた結果、 (1)CreateWindow()にてクライアントウィンドウを作成 (2)CreateMDIWindow()にて子ウィンドウを作成 の順序で処理を行うことは分かりましたが、 関数の一部の引数に何を設定してやれば良いのかが不明です。。 ※下記はネット上にあったサンプルソースです。  「???」の箇所が不明な引数です。 (1) CreateWindow(   TEXT("MDICLIENT"), //MDICLIENT は固定です   NULL,   WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,   0, 0, 0, 0,   hWnd,       //メインウィンドウのハンドル←???   (HMENU)1,    //←???   hInst,       //インスタンスハンドル←???   (LPSTR)&ccs    //CLIENTCREATESTRUCT構造体のポインタ←???  ); (2) HWND CreateMDIWindow(  MDI_CHILD ,   //ウィンドウクラス名  TITLE ,     //ウィンドウのタイトルバーテキスト  0 ,       //ウィンドウスタイル。WS_MAXIMIZE(最大化表示)など  CW_USEDEFAULT , //X座標  CW_USEDEFAULT , //Y座標  CW_USEDEFAULT , //幅  CW_USEDEFAULT , //高さ  hClientWindow , //クライアントウィンドウのハンドル ←???  hIns ,      //インスタンスハンドル       ←???  0        //アプリケーション定義の値 ); なお、行いたい処理の流れとしては、 CTestDialogクラスより、CTest2Dialogクラスのダイアログを、 呼び出したいのです。 うまく説明できず申し訳ありませんが、 お詳しい方おられましたら、具体例など交えてご説明頂けると幸いです。 お手数ですが、どうか宜しくお願い致します。

みんなの回答

回答No.2

追記と訂正。 フレームウインドウの中のクライアント領域に「クライアントウィンドウ」を作成し、そのクライアントウィンドウの中に、子MDIウィンドウを作成する必要があります。 先ほどの回答では「クライアントウィンドウの作成」を失念していました。 フレームウインドウ(WinMainで作る)  クライアントウィンドウ(プロシジャコールバックのWM_CREATEで作る)   最初に作られる子MDIウィンドウ1   WM_MDICREATEなどで後から作られる子MDIウィンドウ2   WM_MDICREATEなどで後から作られる子MDIウィンドウ3 という関係になります。 http://wisdom.sakura.ne.jp/system/winapi/win32/win139.html を参考にすると良いでしょう。 なお、クライアントウインドウを作る時の「(HMENU)1」の「1」は、フレームウィンドウ内に作るウィンドウのID番号で、 LRESULT CALLBACK FrameProc(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp) { (中略)   switch (msg) { (中略)   case WM_COMMAND:    if (LOWORD(wp) == 1) { //CreateWindowのhMenu引数の値。この「1」が「(HMENU)1」に対応する     何かの処理    } (以下略) って感じで使います。 なお、紹介したページにも書いてますが、ウインドウプロシージャのコールバック関数から呼ぶ「デフォルトプロシージャ」が普通と違うので注意して下さい。 また「クライアントウィンドウのクラス名」は、システムに登録済みの「TEXT("MDICLIENT")」でなければなりません。 同様に「子MDIウインドウのクラス名」も、システムに登録済みの「TEXT("MDICHILD")」でなければなりません。 これらは「ボタンのクラス名はTEXT("BUTTON")にしなければならない」のと同じです。

zigen8513
質問者

お礼

これ以上深く質問してしまうと、掲題の主旨に沿わないので、 申し訳ありませんが、いったんここで締め切らせて頂きます。 上記疑問点については、現時点で未解決なので、 また改めて質問させて頂きます。 chie65535様、ご丁寧な解説ありがとうございました。 大変参考になりました。よろしければまたご教授宜しくお願い致します。

zigen8513
質問者

補足

chie65535様、追加のご回答ありがとうございます。 どうやらMDIで作成する場合、複雑な手順を踏まないといけないようですね。。 とりあえず、WinMain関数を作成しようと思い、 CTestDialogクラス内に、下記の雛形を追加しました。 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow){ MSG msg; while ( GetMessage( &msg, NULL, 0, 0 ) ){ TranslateMessage( &msg ); DispatchMessage( &msg ); } return msg.wParam; } ビルドしてみると、通るのですが、 中にデバッグポイントを打って実行してみても、 どうやら中に入っていないようです。 WinMain関数が正しく動いていれば、プログラム実行時に 自動で呼び出される認識なのですが。。 何か定義が間違っているのでしょうか?? 重ねての質問申し訳ありませんが、ご回答頂けると幸いです。

回答No.1

メインウィンドウの作成 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hWnd; WNDCLASSEX wndclass ;  wndclass.cbSize = sizeof(wndclass);  wndclass.style = CS_??????; //好みのスタイルで  wndclass.lpfnWndProc = WndProc; //メッセージ処理のコールバック関数  wndclass.cbClsExtra = 0;  wndclass.cbWndExtra = 0;  wndclass.hInstance = hInstance; //WinMainの第1引数  wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); //アイコン  wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); //カーソル  wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //ブラシ  wndclass.lpszMenuName = NULL; //メニュー  wndclass.lpszClassName = TEXT("MDICLIENT"); //クラス名  wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);  RegisterClassEx (&wndclass); // ウインドウクラスMDICLIENTを登録  hWnd = CreateWindow( //hWndが「親ウィンドウのハンドル」。★1   TEXT("MDICLIENT"), //クラス名   TEXT("子ウィンドウを作るMDIのテスト"), //タイトルバー   WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,   0, 0, //表示位置   256, 256, //ウィンドウサイズ   NULL, //親ウィンドウのハンドルだが親は居ない   NULL, //メニューはない   hInstance, //WinMainの第1引数   NULL //CLIENTCREATESTRUCT構造体のポインタ  ); 以下略。 子MDIウィンドウの作成 HWND hChildWnd; hChildWnd = CreateMDIWindow(  MDI_CHILD , //ウィンドウクラス名  TITLE , //ウィンドウのタイトルバーテキスト  0 , //ウィンドウスタイル。WS_MAXIMIZE(最大化表示)など  CW_USEDEFAULT , //X座標  CW_USEDEFAULT , //Y座標  CW_USEDEFAULT , //幅  CW_USEDEFAULT , //高さ  hWnd , //親ウィンドウのハンドル。上記★1で返されたハンドル  hInstance, //WinMainの第1引数  0 //アプリケーション定義の値 );

zigen8513
質問者

補足

こちらが予測していた以上に具体的な回答ありがとうございます! コメントも丁寧に記載して頂き、非常に分かりやすいです。 インスタンスハンドル「hInstance」について、 WinMain関数の引数でもらっているのですね。 私が作成したいプログラムでは、ボタン押下のタイミングで、 子MDIウィンドウを作成したいので、インスタンスハンドルをグローバルか、 クラスのメンバ変数に持たせて、それをボタンハンドラ関数内で 使用してやるという方法を思いつきました。 もしその方法が不可能であったり、この方が効率が良いなどありましたら、 お手数ですが、再度ご指摘頂けませんでしょうか? 【参考URL】 http://www.kab-studio.biz/Programing/Codian/MxA/03.html

関連するQ&A