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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
ExcelのBOOKが消えた!
-
ラジオボタンの初期指定
-
検索の画面がでなくなってしま...
-
Excelの上下を固定したい
-
VBA .Value=.Value ?
-
Alt+P,Alt+NをPostmessageで送...
-
Vba LongPtrについて教えてくだ...
-
最大化と最小化ボタン
-
ゲームでは結局どっちが良いの?
-
Excelの「ウィンドウ枠の固定」...
-
エクセルで保存したものを開く...
-
ボタンのハンドルウィンド取得...
-
[VBA] UserForm を Excel の W...
-
win32apiにおける終了処理について
-
ダイアログをスクロールさせるには
-
勝手にウィンドウが開いて止ま...
-
コンソールアプリケーションで...
-
他アプリケーション’(ウィンド...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
勝手にウィンドウが開いて止ま...
-
ゲームでは結局どっちが良いの?
-
検索の画面がでなくなってしま...
-
VBA .Value=.Value ?
-
Excelの上下を固定したい
-
ExcelのBOOKが消えた!
-
他のアプリケーションの終了処理
-
Vba LongPtrについて教えてくだ...
-
「&HFFFF」「&H1A」とは?
-
MFC ダイアログ上のID取得につ...
-
作成したウインドウのサイズを...
-
[VBA] UserForm を Excel の W...
-
ラジオボタンの初期指定
-
【VB2008】 マウス操作の一時的...
-
ExcelVBAでAPIを使って外部ウイ...
-
VBAで単一ブック複数窓を閉じる...
-
EnumChildWindowsの使い方(VBA)
-
隠れたウィンドウの画面をキャ...
おすすめ情報