0

我有一个奇怪的错误,在调试器中花了几个小时没有找到解决方案。(但它帮助我修复了另一个错误,即您永远不应该从 WM_KICKIDLE 任务中调用 EndDialog)。

我的问题是我有一个主窗口和一个无模式对话框窗口,它会引发一个模式子对话框窗口。当子对话框窗口关闭时。无模式对话窗口将自己变成一个模式窗口。我的代码确实离开了模态循环。如果我关闭现在的模态窗口,它的行为就像一个不可见的模态窗口处于活动状态,这意味着不再可能进行交互。

当我只在主窗口顶部运行模式对话框时,它关闭得很好。

顺便说一句:主窗口不是一个可用的视图 CWinApp::m_pMainWnd 而是一个新创建的 FrameWindow。我隐藏 p_MainWnd 并将其用作不可见的仅消息窗口。从一些评论和我的调试会话中,我发现 pMainWnd 有一些特殊的含义,但我可以弄清楚它与模式窗口到底有什么关系(例如,有一个未记录的“CWinApp::DoEnableModeless”)。

编辑:我将 WM_CLOSE 发布到对话框,然后使用 OnClose() 处理程序中的 EndDialog(0) 退出模态状态。我也尝试直接使用 EndDialog(0) 。这两种方法没有区别。

4

2 回答 2

0

也许这是有道理的,但我有一个问题:

你为什么使用隐藏窗口?它是作为仅消息窗口创建的(将 HWND_MESSAGE 作为父句柄传递,将 Message 作为类传递)还是仅将其称为消息?

好的,关于 MFC 和对话框的更多信息。

MFC 不使用 Windows 模式对话框。它总是创建无模式对话框;依次调用 Create 或 DoModal ::CreateDlgIndirect windows API。

无模式的 dialof 依赖于主窗口消息派发,而 modal 调用类似于 MFC 窗口消息 pupmp 的 RunModalLoop(不是消息循环)。它在执行的主线程中运行而不会冻结,因为它允许空闲处理(调用 OnIdle)。

你如何关闭无模式对话框?正如马克指出的那样,您应该使用 DestroyWindow。

至于 m_pMainWnd,MFC 框架广泛使用它来确定控制主窗口行为的可能事物。通过更改它,您可能已经创建了您所体验的行为。

您是否将值设置为您视为主窗口的新创建的框架?

它是一个什么样的 MFC 应用程序?SDI还是MDI?是否可以创建测试应用程序来复制此行为并将其发布到某个地方以供下载?

顺便说一句,您不必担心 DoEnableModeless,因为它除了调用经常使用的钩子(COleFrameHook 类型)之外什么都不做,除非您尝试使用 OLE 或 ActiveX 实现某些功能,或者您正在尝试结婚MFC 和 .NET Windows 窗体。总之,如果您的(或第三方代码使用此挂钩,我建议检查 COleFrameHook 类中的代码。

于 2013-01-11T20:10:28.190 回答
0

当 MFC 创建模态对话框时,它通过禁用其上方的窗口使其成为模态对话框。当对话框通过调用 EndDialog 正常结束时,会出现重新启用这些窗口的代码。如果有任何东西阻止该代码运行,其他窗口将被锁定。

无模式对话框是另一种野兽,EndDialog 文档中专门有一条注释警告您改用 DestroyWindow。

于 2013-01-11T00:06:34.600 回答