モーダルダイアログなのに、下のウィンドウに触れてしまう。

[戻る]
たけ 2004/12/02(木) 16:42:31
たけです。

CListViewから以下のようにCHogeDlgをモーダルで表示しています。

CHogeDlg dlg;
dlg.DoModal();

モーダルで表示するときに以下のように、モードレスダイアログも
表示しています。
pWnd = new CHoge2Dlg; (pWndはCWndのポインタ)
pWnd->Create(CHoge2DlgのID);
pWnd->ShowWindow(SW_SHOW);

この時点では、CHogeDlgの下のウィンドウには触れません。
(モーダルダイアログの標準の動作をしてくれます)

この状態から、モードレスダイアログを×で閉じると
なぜか、下のウィンドウに触れるようになり
メニューや、ツールバーの押せるようになってしまいます。

何が原因でこうなっているのかわかりません。
ご教授下さい。

環境 Win2000,VC++6.0

PATIO 2004/12/03(金) 11:29:05
CHoge2Dlgの方の実装がどうなっているか確認しましょう。
通常、×ボタンを押すとCDialogのOnCancel()が呼ばれる仕様になっていると思います。
これが呼ばれてしまうとモーダルダイアログの時と同じようにEndDialogが呼ばれてしまい、
親ウインドウの無効化が解除されます。
しかも、これだと非表示になるだけでウインドウが破棄されません。
この辺はHELPのCDialogの説明を最初から最後まで読んでみてください。
モードレスにする時の注意点も書いてあります。

×ボタンが押されるとOnCancelが呼ばれるのは、ためしに簡単なテストプログラムでも
作ってデバッガで追えばすぐにわかりますから御自分で確認してみてください。

一番簡単な実装は、OnCancelをオーバーライドしてDestroyWindowを呼ぶようにしておき、
PostNcDestroyをオーバーライドして中でdelete this;をするようにすることでしょう。
基本的にダイアログ上にOKボタンがなくてもOnOK()もオーバーライドしてデフォルトの処
理が呼ばれないようにしておく方が安全です。
OnCancelは×ボタンを生かしておくのであれば、必ずオーバーライドして処理するように
しないと駄目だと思います。

たけ 2004/12/03(金) 13:03:49
[[解決]]
詳しくありがとうございました。

>一番簡単な実装は、OnCancelをオーバーライドしてDestroyWindowを呼ぶようにしておき、
>PostNcDestroyをオーバーライドして中でdelete this;をするようにすることでしょう。
↑のとおりで解決しました。

>通常、×ボタンを押すとCDialogのOnCancel()が呼ばれる仕様になっていると思います。
>これが呼ばれてしまうとモーダルダイアログの時と同じようにEndDialogが呼ばれてしまい、
>親ウインドウの無効化が解除されます。
これ、意識したことなかったです。

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