dポイントプレゼントキャンペーン実施中!

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クラスのダイアログを、
呼び出したいのです。
うまく説明できず申し訳ありませんが、
お詳しい方おられましたら、具体例など交えてご説明頂けると幸いです。
お手数ですが、どうか宜しくお願い致します。

A 回答 (2件)

追記と訂正。



フレームウインドウの中のクライアント領域に「クライアントウィンドウ」を作成し、そのクライアントウィンドウの中に、子MDIウィンドウを作成する必要があります。

先ほどの回答では「クライアントウィンドウの作成」を失念していました。

フレームウインドウ(WinMainで作る)
 クライアントウィンドウ(プロシジャコールバックのWM_CREATEで作る)
  最初に作られる子MDIウィンドウ1
  WM_MDICREATEなどで後から作られる子MDIウィンドウ2
  WM_MDICREATEなどで後から作られる子MDIウィンドウ3
という関係になります。

http://wisdom.sakura.ne.jp/system/winapi/win32/w …
を参考にすると良いでしょう。

なお、クライアントウインドウを作る時の「(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")にしなければならない」のと同じです。

この回答への補足

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関数が正しく動いていれば、プログラム実行時に
自動で呼び出される認識なのですが。。
何か定義が間違っているのでしょうか??
重ねての質問申し訳ありませんが、ご回答頂けると幸いです。

補足日時:2009/02/06 13:11
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/02/06 17:18

メインウィンドウの作成


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 //アプリケーション定義の値
);

この回答への補足

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

補足日時:2009/02/05 18:01
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!