こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

MDI frame_windowのsize変更後にMSGが届かない

C++のカテゴリでWindowsプログラミングの質問もおかしいと思いましたが、他に質問するカテゴリが無かったので申し訳ありませんが、よろしくお願いします。

久しぶりに時間が空いたため、windows apiを使って自作でクラスライブラリを作成に挑戦し、WINDOWSプログラミングを行っています。

MDIウィンドウのアプリケーションについて質問です。

アプリケーション起動時に、MDIのフレームウィンドウとクライアントウィンドウを生成し、クライアントウィンドウをダブルクリックした時に、MDI子ウィンドウを生成するようにプログラムを作成しました。

アプリケーション起動後、フレームウィンドウのサイズを変更せずにクライアントウィンドウ領域でダブルクリックするとダブルクリックした回数分、MDI子ウィンドウが生成されました。
しかし、一度でもフレームウィンドウのサイズを変更してしまった場合に、ダブルクリックしてもMDI子ウィンドウが生成されなくなってしまいました。
(※「WM_LBUTTONDBLCLK」メッセージ自体が来なくなった。)

何故、ダブルクリックのメッセージが来なくなるのか心当たりが無く困っています。

以下のホームページにクライアントウィンドウのリサイズした時の処理について記載されていますが、内容を追加しても解決しませんでした。
http://www.arcpit.co.jp/winapi/api_02/ap020407.htm

申し訳ありませんが、ダブルクリックのメッセージが来なくなる理由についてお心当たりがあれば、お教えお願い致します。

※環境
OS:Windows Vista Home Basic
開発環境:Visual C++ Express Edition

投稿日時 - 2009-09-06 13:35:53

QNo.5267258

困ってます

質問者が選んだベストアンサー

 こんばんは。

 何となく想像がつくのですが、MDIフレーム側のプロシージャでWM_LBUTTONDBLCLKメッセージを処理しているのではないでしょうか。
 メッセージが来なくなったのは、リサイズされた時にMDIクライアントがサイズ調整されてMDIフレームのクライアント領域に覆いかぶさった為だと思います。
 MDIフレーム→MDIクライアント→MDIチャイルド(複数)と言う構成になるので、MDIクライアント側のプロシージャ側で処理すれば出来るのではないでしょうか。
 上記URLで言えば、

 hWndClient = CreateWindow("MDICLIENT", NULL, ...)

 で作成しているhWndClientのプロシージャ内でWM_LBUTTONDBLCLKメッセージを処理すると言う事です。
 また、MDIクライアントはシステム側に登録されているウィンドウですので、プロシージャをフックする必要があります。
 実行していないのですが、以下のような感じでしょうか。

static WNDPROC _S_wndProcMDIClientOrg = NULL;

LRESULT CALLBACK WndProcMDIClient(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_LBUTTONDBLCLK:
{
//此処でMDIチャイルドを作成する
break;
}
}
return ::CallWindowProc(_S_wndProcMDIClientOrg, hWnd, uMsg, wParam, lParam);
}

//MDIフレーム側
LRESULT CALLBACK WndProcMDIFrame(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE:
{
LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;

CLIENTCREATESTRUCT ccs;
ccs.hWindowMenu = GetSubMenu(lpcs->hMenu,IDMC_WINDOW);
ccs.idFirstChild = ID_MDICHILD;

RECT crc = {0};
::GetClientRect(hWnd, &rc);

//MDIクライアントの作成
HINSTANCE hInst = (HINSTANCE)::GetWindowLong(hWnd, GWL_HINSTANCE);
HWND hWndClient = ::CreateWindowEx(0, "MDICLIENT",NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_HSCROLL | WS_VSCROLL,
0, 0, rc.right, rc.bottom, hWnd, lpcs->hMenu, hInst, (LPVOID)&ccs);

const DWORD dwClsStyle = ::GetClassLong(hWndClient, GCL_STYLE);
::SetClassLong(hWndClient, GCL_STYLE, dwClsStyle | CS_DBLCLKS);

//MDIクライアントのプロシージャフック
_S_wndProcMDIClientOrg = (WNDPROC)::SetWindowLong(hWndClient, GWL_WNDPROC, (LONG)&::WndProcMDIClient);
}
}
//...
}

投稿日時 - 2009-09-07 23:45:27

お礼

回答ありがとうございます。
[machongola]様の回答で問題解決しました。

私の勘違いは以下の通りでした。

(1)MDIクライアントウィンドウに対してはMDIフレームウィンドウの
 ウィンドウプロシージャが適用されていると勘違いしていた所。

回答を参照し以下の不足点を補い、問題解決しました。

(1)MDIクライアントのウィンドウスタイルでダブルクリックメッセージも
 受け付けるように対応
(2)MDIクライアントウィンドウのデフォルトウィンドウプロシージャの
 アドレスをフックし、ダブルクリックメッセージは新規ウィンドウ
 プロシージャで対応、それ以外はフックしたウィンドウプロシージャで
 対応

今までWINDOWS系OSでプログラムを組んできましたが、組込み系のソフトで、独自に用意されているクラスライブラリを使用してのプログラム開発ばかりでしたので、勉強になりました。

これで、独自のクラスライブラリを作って遊んでみようと頑張ってみている夢を続けられます。

質問自体が少ない情報で申し訳ありませんでした。
本当にありがとうございます。

投稿日時 - 2009-09-08 12:28:17

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(1)

あなたにオススメの質問