
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/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関数が正しく動いていれば、プログラム実行時に
自動で呼び出される認識なのですが。。
何か定義が間違っているのでしょうか??
重ねての質問申し訳ありませんが、ご回答頂けると幸いです。
これ以上深く質問してしまうと、掲題の主旨に沿わないので、
申し訳ありませんが、いったんここで締め切らせて頂きます。
上記疑問点については、現時点で未解決なので、
また改めて質問させて頂きます。
chie65535様、ご丁寧な解説ありがとうございました。
大変参考になりました。よろしければまたご教授宜しくお願い致します。
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 //アプリケーション定義の値
);
この回答への補足
こちらが予測していた以上に具体的な回答ありがとうございます!
コメントも丁寧に記載して頂き、非常に分かりやすいです。
インスタンスハンドル「hInstance」について、
WinMain関数の引数でもらっているのですね。
私が作成したいプログラムでは、ボタン押下のタイミングで、
子MDIウィンドウを作成したいので、インスタンスハンドルをグローバルか、
クラスのメンバ変数に持たせて、それをボタンハンドラ関数内で
使用してやるという方法を思いつきました。
もしその方法が不可能であったり、この方が効率が良いなどありましたら、
お手数ですが、再度ご指摘頂けませんでしょうか?
【参考URL】
http://www.kab-studio.biz/Programing/Codian/MxA/ …
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 動かなくなってしまった古いVBAを動くようにしたい 8 2022/09/20 13:57
- Visual Basic(VBA) Vba LongPtrについて教えてください 2 2022/08/19 11:14
- Microsoft ASP Windows10エンタープライズ版をインストールしたらアプリが使えなくなった 3 2023/03/07 11:08
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/17 18:41
- Visual Basic(VBA) VBA 参照先で選んだファイルをコピーし、出力先に別名で保存したい 8 2022/05/13 20:37
- その他(OS) Windowsで大量の画像サイズを半自動で変更する方法 6 2023/02/17 08:45
- JavaScript ソースコードのいじる場所が分かりません。 1 2022/12/23 02:06
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/06 09:28
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- その他(ソフトウェア) Figma 1 2023/06/23 14:22
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
ラジオボタンの初期指定
-
検索の画面がでなくなってしま...
-
Alt+P,Alt+NをPostmessageで送...
-
Vba LongPtrについて教えてくだ...
-
ツールバーから選択で一つだけ...
-
Excelの上下を固定したい
-
EnumChildWindowsの使い方(VBA)
-
どこでも良いからクリックした...
-
C#でファイル転送プログラムWin...
-
タスクトレイからのバルーン表示
-
ExcelVBA:フォームの最小化ボ...
-
ダイアログをスクロールさせるには
-
MFCでハンドルを取得するには
-
[ExcelVBA] 別ウィンドウのエク...
-
Tera Termに他のアプリから文字...
-
SendMessage関数がうまく動作し...
-
EXCEL2016で新しいウィンドウを...
-
指定したインアクティブウィン...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
ラジオボタンの初期指定
-
勝手にウィンドウが開いて止ま...
-
Vba LongPtrについて教えてくだ...
-
検索の画面がでなくなってしま...
-
Excelの上下を固定したい
-
ExcelのBOOKが消えた!
-
[VBA] UserForm を Excel の W...
-
VBA .Value=.Value ?
-
作成したウインドウのサイズを...
-
Console.WriteLine で表示されない
-
エクセルで1行目から3行目が消...
-
「&HFFFF」「&H1A」とは?
-
【VB2008】 マウス操作の一時的...
-
UWSCで特定のChromeのタブをア...
-
他のアプリケーションの終了処理
-
MFCでハンドルを取得するには
-
VBAで単一ブック複数窓を閉じる...
-
EnumChildWindowsの使い方(VBA)
おすすめ情報