我有一个奇怪的错误,花了几个小时在调试器没有找到解决方案。(但它帮助我修复了另一个错误,你不应该从WM_KICKIDLE任务调用EndDialog)。
我的问题是,我有一个主窗口和一个非模态对话框窗口,它引发了一个模态子对话框窗口。子对话框窗口关闭时。非模态对话框窗口将自己转换为模态窗口。我的代码确实离开了模态循环。如果我关闭现在的模态窗口,它的行为就像一个不可见的模态窗口是活动的,这意味着没有交互是可能的了。
当我只运行一个模态对话框在主窗口的顶部它是关闭的好。
BTW:主窗口不是一个可用的视图CWinApp:: m_pmainwind,而是一个新的创建FrameWindow。我隐藏了p_mainwind并将其用作不可见的消息窗口。从一些评论和我的调试会话中,我发现pmainnd有一些特殊的含义,但我可以弄清楚它究竟与模态窗口有什么关系(例如,有一个未记录的"CWinApp::DoEnableModeless")。
编辑:我发布一个WM_CLOSE对话框,然后使用EndDialog(0)从OnClose()处理程序退出模态状态。我也尝试直接使用EndDialog(0)。这两种方法没有区别。
当MFC创建一个模态对话框时,它通过禁用它上面的窗口来使它成为模态。当对话框通过调用EndDialog正常结束时,重新启用这些窗口的代码就会发生。如果有任何东西阻止该代码运行,其他窗口将被锁定。
非模态对话框是另一种动物,在EndDialog文档中有一个特别的注释,警告你使用DestroyWindow。
也许这是合理的,但我有一个问题:
为什么要使用隐藏窗口?它是否被创建为消息窗口(传递HWND_MESSAGE作为父句柄和消息作为类),或者你只是叫它消息?
好的,关于MFC和对话框的更多信息。
MFC不使用Windows模态对话框。它总是创建非模态对话框;Create或dommode依次调用::CreateDlgIndirect windows API
非模态拨号依赖于主窗口消息调度,而模态调用RunModalLoop,类似于MFC窗口消息泵浦(不是消息循环)。它在执行的主线程中运行而不冻结,因为它允许空闲处理(调用OnIdle)。
如何关闭非模态对话框?正如Mark指出的,你应该使用DestroyWindow。
至于m_pmainnd, MFC框架广泛使用它来确定控制主窗口行为的许多事情。通过改变它,你可能创造了你所经历的行为。
您是否将值设置为一个新创建的框架,您将其视为主窗口?
它是什么样的MFC应用程序?SDI还是MDI?是否有可能创建测试应用程序来复制这种行为并将其发布到某个地方供下载?
顺便说一句,你不必担心DoEnableModeless,因为它不做任何事情,但调用钩子(COleFrameHook类型)是偶尔使用,除非你试图实现一些功能使用OLE或ActiveX或你试图结婚MFC和。net Windows窗体。总之,如果你(或第三方)的代码使用了这个钩子,我建议检查COleFrameHook类中的代码。