0

奇妙なエラーが発生し、解決策が見つからずにデバッガーで何時間も費やしています。(しかし、WM_KICKIDLE タスクから EndDialog を呼び出すべきではないという別のエラーを修正するのに役立ちました)。

私の問題は、メイン ウィンドウと、モーダル サブダイアログ ウィンドウを表示するモードレス ダイアログ ウィンドウがあることです。サブダイアログ ウィンドウが閉じられたとき。モードレス ダイアログ ウィンドウは、モーダル ウィンドウに変わります。私のコードは実際にモーダル ループを離れます。そして、現在のモーダル ウィンドウを閉じると、非表示のモーダル ウィンドウがアクティブであるように動作します。つまり、対話ができなくなります。

メインウィンドウの上でモーダルダイアログのみを実行すると、正常に閉じられます。

ところで: メイン ウィンドウは、利用可能なビュー CWinApp::m_pMainWnd ではなく、新しく作成された FrameWindow です。p_MainWnd を非表示にして、非表示のメッセージのみのウィンドウとして使用します。いくつかのコメントとデバッグ セッションから、pMainWnd には特別な意味があることがわかりましたが、モーダル ウィンドウとの関係を正確に把握できました (たとえば、文書化されていない "CWinApp::DoEnableModeless" があります)。

編集: WM_CLOSE をダイアログに投稿し、OnClose() ハンドラーから EndDialog(0) を使用してモーダル状態を終了します。また、EndDialog(0) を直接使用しようとしました。この 2 つの方法に違いはありません。

4

2 に答える 2

0

多分これは正当化されますが、私は質問があります:

なぜ隠し窓を使っているのですか?メッセージ専用ウィンドウとして作成されましたか(親ハンドルとしてHWND_MESSAGEを渡し、クラスとしてメッセージを渡します)、それとも単にメッセージのみと呼びますか?

OK、MFCとダイアログについてもう少し情報があります。

MFCはWindowsモーダルダイアログを使用しません。常にモードレスダイアログを作成します。CreateまたはDoModalのいずれかを順番に呼び出します::CreateDlgIndirectWindowsAPI。

モードレスdialofは、メインウィンドウのメッセージディスパッチに依存しますが、モーダルは、MFCウィンドウのメッセージpupmp(メッセージループではない)に似たRunModalLoopを呼び出します。アイドル処理(OnIdleを呼び出す)が可能であるため、フリーズせずに実行のメインスレッドで実行されます。

モードレスダイアログをどのように却下しますか?マークが指摘したように、DestroyWindowを使用する必要があります。

m_pMainWndに関しては、MFCフレームワークはそれを広範囲に使用して、メインウィンドウの動作を制御する可能性のあるものを決定します。それを変更することによって、あなたはあなたが経験する振る舞いを作成したかもしれません。

メインウィンドウとして扱う新しく作成されたフレームに値を設定しましたか?

どんなMFCアプリケーションですか?SDIまたはMDI?この動作を複製するテストアプリを作成し、ダウンロード用にどこかに投稿することは可能でしょうか?

ちなみに、DoEnableModelessは、OLEまたはActiveXを使用して一部の機能を実装しようとしている場合、または結婚しようとしている場合を除いて、使用頻度の低いフック(COleFrameHookタイプ)を呼び出すだけなので、心配する必要はありません。 MFCおよび.NETWindowsフォーム。結論として、(またはサードパーティのコードがこのフックを使用している場合は、COleFrameHookクラスのコードを確認することをお勧めします。

于 2013-01-11T20:10:28.190 に答える
0

MFC がモーダル ダイアログを作成すると、その上にあるウィンドウを無効にすることでモーダルになります。これらのウィンドウを再度有効にするコードは、ダイアログが EndDialog の呼び出しで正常に終了したときに発生します。そのコードの実行を妨げるものがあれば、他のウィンドウはロックアウトされます。

モードレス ダイアログは別の獣であり、代わりに DestroyWindow を使用するように警告する EndDialog ドキュメントに特に注意事項があります。

于 2013-01-11T00:06:34.600 に答える