一个窗口上的MFC:X按钮也在关闭第二个窗口

MFC: X button on one window is closing a second window also

本文关键字:窗口 按钮 第二个 MFC 一个      更新时间:2023-10-16

我的应用程序有几个窗口,每个窗口都有一个不同的CDialog派生类。

点击窗口框架右上角的"X"按钮将关闭窗口并调用PostNcDestroy

不过,对于四个窗口中的一个,它还调用另一个窗口的PostNcDestroy(),并使该窗口不可见。

有什么想法吗?

您没有提供太多信息。我们只能猜测。。。由于您声明所有的窗口都是对话框,我猜在应用程序的InitInstance()方法中,您有一个对主CDialog派生类的DoModal()的调用。关闭主对话框后,它退出DoModal()循环,然后退出InitInstance()并关闭应用程序。应用程序关闭会导致其他对话框被破坏,结果是发送WM_NCDESTROY,然后调用PostNcDestroy()。

SHORT ANSWER:该行为是由在创建所有四个窗口后设置m_pMainWnd引起的。如果在创建第二个窗口之前设置了它,则不再出现上述问题。

长话短说:问题是这些窗口之间不相互关联。他们每个人都是上一代的孩子。

窗口1的父级是值"0"(桌面)。窗口2的父窗口是窗口1。窗口3的父窗口是窗口2。窗口4的父窗口是窗口3。

我最初的问题报告指出,当窗户3关闭时,窗户4神秘地关闭了。所以现在原因是显而易见的。(关闭一个窗口也会关闭它的所有子窗口。)随后我发现关闭窗口2会导致3和4也关闭,这也是原因之一。(3是2的子级,因此关闭,而作为3的子级的4也将关闭。)最后,关闭窗口1会检查未保存的工作,如果没有,则调用exit()。我想,如果这个窗口没有退出,其他窗口也会全部关闭。

CDialog::Create()的第二个参数pParentWnd有默认参数NULLNULL表示父级"设置为主应用程序窗口"。进入CDialog::Create(),调用CDialog::CreateIndirect(),调用AfxGetMainWnd(),我最终进入CWinThread::GetMainWnd()。如果尚未设置m_pMainWnd,则该方法只返回最近创建的窗口CWnd::GetActiveWindow()

所以:问题的根源是我的应用程序创建了四个窗口,然后设置了m_pMainWnd。这就是为什么窗口3是窗口2的子窗口(此时的活动窗口)4是3的子窗口,依此类推

通过在创建窗口1之后设置m_pMainWnd,则窗口2、3和4是1的子级。这样就消除了"关闭窗口3使窗口4也关闭"的问题。

这仍然不是我所需要的,因为它阻止了窗口1被带到其他三个窗口的前面。这超出了我最初问题的范围,但这是解决问题的方法。明确地将Create()调用更改为在GetDesktopWindow()中传递似乎使应用程序按我的意愿工作,有四个窗口可以独立关闭,并在窗口堆栈中自由排序:

  Create( resource_ID, GetDesktopWindow() );

我很惊讶这不是一个著名的问题,因为这些函数中没有一个的文档(截至VS2008Pro)实际上解释了它们在未设置m_pMainWnd时的实际操作,并且将对m_pMainWnd的简单分配移动到窗口创建结束可能会破坏任何创建两个以上窗口的应用程序。。。