我的应用程序有几个窗口,每个窗口都有一个不同的CDialog
派生类。
点击窗口框架右上角的“X”按钮关闭窗口并调用PostNcDestroy
.
但是,对于四个窗口中的一个,它还PostNcDestroy
额外调用另一个窗口的 () 并使该窗口也变得不可见。
有任何想法吗?
你没有提供太多信息。我们只能猜测...由于您声明所有窗口都是对话框,我猜想在您的应用程序的 InitInstance() 方法中,您调用了主 CDialog 派生类的 DoModal()。关闭主对话框后,它退出 DoModal() 循环,然后退出 InitInstance() 并关闭应用程序。应用程序关闭会导致其他对话框被破坏,并导致发送 WM_NCDESTROY,然后调用 PostNcDestroy()。
简短回答:该行为是由在m_pMainWnd
创建所有四个窗口之后设置引起的。如果在创建第二个窗口之前设置,则不再出现上述问题。
长答案:问题是窗户彼此不是兄弟姐妹。他们每个人都是以前的孩子。
窗口 1 的父级是值“0”(桌面)。窗口 2 的父窗口是窗口 1。窗口 3 的父窗口是窗口 2。窗口 4 的父窗口是窗口 3。
我最初的问题报告指出,当窗口 3 关闭时,窗口 4 神秘地关闭了。所以现在原因很明显了。(关闭一个窗口也会关闭它的所有子窗口。)我随后发现关闭窗口 2 导致 3 和 4 也关闭,这也是有原因的。(3 是 2 的孩子如此关闭,这使得 4,即 3 的孩子,关闭。)最后,关闭窗口 1 检查未保存的工作,如果没有则调用exit()
. 我假设如果这个窗口没有退出,其他窗口也会全部关闭。
CDialog::Create()
NULL
其第二个 arg具有默认参数pParentWnd
,并且NULL
意味着父级“设置为主应用程序窗口”。踏入CDialog::Create()
,呼唤CDialog::CreateIndirect()
,呼唤AfxGetMainWnd()
我最终进入CWinThread::GetMainWnd()
。如果m_pMainWnd
尚未设置该方法,则只返回CWnd::GetActiveWindow()
最近创建的窗口。
所以:问题的根源是我的应用程序创建了四个窗口,然后设置m_pMainWnd
。这就是为什么窗口 3 是窗口 2 的子窗口(此时的活动窗口)4 是窗口 3 的子窗口,依此类推。
通过m_pMainWnd
在创建窗口 1 后设置,则窗口 2 3 和 4 是 1 的子窗口。这样就摆脱了“关闭窗口 3 使窗口 4 也关闭”的问题。
这仍然不是我所需要的,因为它可以防止窗口 1 被带到其他三个窗口的前面。这超出了我最初问题的范围,但这是解决方法。显式更改Create()
调用传递GetDesktopWindow()
似乎使应用程序按我想要的方式工作,四个窗口可以独立关闭并且可以在窗口堆栈中自由排序:
Create( resource_ID, GetDesktopWindow() );
我很惊讶这不是一个著名的问题,因为这些函数中的 NONE 的文档(截至 VS2008Pro)实际上解释了它们在m_pMainWnd
未设置时实际执行的操作,并且将这个简单的分配移动到m_pMainWnd
窗口创建的末尾会可能会搞砸任何创建两个以上窗口的应用程序......