我有一个奇怪的错误,在调试器中花了好几个小时而没有找到解决方案。 (但它帮助我修复了另一个你永远不应该从WM_KICKIDLE任务调用EndDialog的错误。)
我的问题是我有一个主窗口和一个无模式对话窗口,它会引发一个模态子窗口窗口。当子菜单窗口关闭时。无模式对话框窗口将自身变为模态窗口。我的代码确实离开了模态循环。如果我关闭现在的模态窗口,它的行为就像一个隐形模态窗口是活动的,这意味着不再可能进行交互。
当我只在主窗口顶部运行模态对话框时,它会很好地关闭。
顺便说一句:主窗口不是一个可用的视图CWinApp :: m_pMainWnd,而是一个新的创建FrameWindow。我隐藏了p_MainWnd并将其用作不可见的消息窗口。从一些评论和我的调试会话中我发现pMainWnd有一些特殊含义,但我可以确定它与模态窗口有什么关系(例如,有一个未记录的“CWinApp :: DoEnableModeless”)。
编辑:我正在向对话框发布WM_CLOSE,然后使用OnClose()处理程序中的EndDialog(0)退出模态状态。我也尝试直接使用EndDialog(0)。这两种方法没有区别。
答案 0 :(得分:0)
当MFC创建模态对话框时,它通过禁用其上方的窗口使其成为模态。当对话框正常结束并调用EndDialog时,会重新启用这些窗口的代码。如果有任何东西阻止该代码运行,其他窗口将被锁定。
无模式对话框是一个不同的野兽,EndDialog文档中有一条特别说明警告您使用DestroyWindow。
答案 1 :(得分:0)
也许这是合理的,但我有一个问题:
你为什么要使用隐藏窗口?它是作为仅消息窗口创建的(将HWND_MESSAGE作为父句柄传递,将Message作为类传递)还是仅将其称为消息?
好的,关于MFC和对话框的更多信息。
MFC不使用Windows模式对话框。它总是创建无模式对话;要么Create或DoModal调用:: CreateDlgIndirect windows API。
无模式拨号依赖于主窗口消息调度,而模态调用RunModalLoop则类似于MFC窗口消息pupmp(不是消息循环)。 它在执行的主线程中运行而不会冻结,因为它允许空闲处理(调用OnIdle)。
你如何解雇无模式对话框?正如马克指出的那样,你应该使用DestroyWindow。
对于m_pMainWnd,MFC框架广泛使用它来确定控制主窗口行为的事物。通过更改它,您可能已经创建了您所经历的行为。
您是否将值设置为您将其视为主窗口的新创建的框架?
它是什么样的MFC应用程序? SDI还是MDI? 是否可以创建测试应用程序来复制此行为并将其发布到某个地方进行下载?
顺便说一句,你不必担心DoEnableModeless,因为除了你试图使用OLE或ActiveX实现某些功能之外它没有做任何事情,只是调用钩子(COleFrameHook类型),或者你是试图嫁给MFC和.NET Windows窗体。 总之,如果您(或第三方代码使用此钩子,我建议检查COleFrameHook类中的代码。