モーダルのダイアログを別のダイアログ(スレッド)から閉じる方法。

[戻る]
マサ 2010/05/26(水) 19:36:13
MFCのダイアログアプリケーションを作成しています。
メインダイアログとは別に、モーダレスのダイアログ(※A)が1つ存在します。

また、このモーダレスのダイアログから1つ、モーダルダイアログ(確認のYES NO用 ※
B)が必要に応じて表示されます。
このとき不定期(別のワーカススレッドからのメッセージ、タイムアウトなど)に※Aダ
イアログを
非表示(ShowWindow(SW_HIDE))するケースがあります。このときに※Bダイアログが表示
(DoModal())されていたら、
※Bダイアログを閉じることをしたいと思います。


Aダイアログクラス内に、メンバでBダイアログを持たせ、
Aが非表示(OnShowWindowが呼ばれ)の時にBに対してSendMessageで"WM_CLOSE"を送信しま
したが、
デバッグで動作させると落ちます。 (Bのダイアログが表示されていない場合)
Bの表示の有無をIsWindowVisible()で確認しても落ちます。

どのように、すればスマートに実現できるのかアドバイスをいただけないでしょうか?
よろしくお願いいたします。

仲澤@失業者 2010/05/27(木) 10:22:17
DLG_B.PostMessage( WM_COMMAND, MAKEWPARAM( IDCANCEL, BN_CLICKED), NULL);
ではどうでしょう。

subaru 2010/05/27(木) 10:50:57
>(Bのダイアログが表示されていない場合)
ハンドルが有効でない状態ではウインドウにアクセスするようなメソッドは使えません。
ダイアログが作成されているかどうかはGetSafeHandle()で判断できるでしょう。

PATIO 2010/05/27(木) 14:14:21
モーダレスじゃなくてモードレスだと思いますよ。
モーダルの方はモーダルで正解だと思いますけれど。

ダイアログに対してメッセージを送る場合、ハンドルが有効で無いと
駄目でしょというのはsubaruさんが書かれている通りですね。

複数のウインドウを連携して制御するのであれば、
各ウインドウの表示状態を管理すると言う考え方は必要だと思います。
特に制御対象のウインドウがどういう状況にあるのかは制御側で
把握できるような仕組み立てが必要です。
CWnd::GetSafeHwndで確認するというのも一つの方法でしょうし、
自前で制御対象の状態をフラグ等で管理するというのも方法でしょう。
いずれにせよ、管理する必要がある事に変わりはありません。

PATIO 2010/05/27(木) 14:16:43
追伸:
デバッグで落ちるとかかれていますけれど、
アサーテーションが出てとまるというのが正確なのでは?
掲示板のやり取りではこの辺の正確さも必要です。
できる限り起こっている現象を正確に表現するようにしないと
話がすれ違ってしまってうまく伝わりません。

subaru 2010/05/27(木) 14:49:35
>CWnd::GetSafeHwndで確認するというのも一つの方法でしょうし、
GetSafeHandleじゃなくてPATIOさんの書かれているとおりGetSafeHwndでした。
失礼いたしました。

マサ 2010/05/27(木) 15:10:27
[[解決]]
返信とご指摘ありがとうございます。

>> PATIO さん
ご指摘の通り、アサートで止まっている状態です。


DlgB.GetSafeHwnd();でハンドルのNULLチェックを入れることによって、うまく実装でき
ました。
IsWindowVisible()がウィンドが作成されていないと使用できないことも初めて知りまし
た(^^; 重ね重ねありがとうございました。

PATIO 2010/05/27(木) 15:19:43
解決になっていますが、

せっかくでているアサートを無駄にしているのでは?
と言う気がしています。
アサートはデバッグ時に危険な状況にある事を教えてくれている
とても便利で助かる物です。
アサートメッセージには何処でアサートが起こっているかも
表示されているはずです。
該当するソースを確認する事でウインドウハンドルが無効だと
駄目だと言うことが把握できます。
アサートが出た場合はその情報を積極的に利用するべきですよ。

古いスレッドには追加発言できません。