我的应用程序有几个窗口,每个窗口都有一个不同的CDialog
派生类。
点击" X"窗口框右上角的按钮关闭窗口并调用PostNcDestroy
。
对于四个窗口中的一个,它还会另外调用另一个窗口的PostNcDestroy
(),并使该窗口也不可见。
有什么想法吗?
答案 0 :(得分:0)
您没有提供太多信息。我们只能猜测...因为你声明所有的窗口都是对话框,我猜你在应用程序的InitInstance()方法中调用了主要的CDialog派生类的DoModal()。关闭主对话框后,它退出DoModal()循环,然后退出InitInstance()并关闭应用程序。应用程序关闭导致其他对话框被销毁,结果发送WM_NCDESTROY,然后调用PostNcDestroy()。
答案 1 :(得分:0)
简短的回答:行为是由创建所有四个窗口后设置m_pMainWnd
引起的。如果在创建第二个窗口之前设置它,则不再出现上述问题。
长期答案:问题是窗户彼此之间并不相互矛盾。他们都是PREVIOUS的孩子。
窗口1的父级是值" 0" (桌面)。 窗口2的父级是窗口1。 窗口3的父级是窗口2。 窗口4的父级是窗口3。
我原来的问题报告指出,当窗口3关闭时,窗口4神秘地关闭。所以现在之所以显而易见。 (关闭一个窗口也关闭了它的所有孩子。)我随后发现关闭窗口2导致3和4也关闭,这也是占了。 (3是2岁的孩子如此关闭,这使4岁,即3岁的孩子,关闭。)最后,关闭窗口1检查未保存的工作,如果没有人调用exit()
。我假设如果这个窗口没有退出,其他窗口也会全部关闭。
CDialog::Create()
为其第二个arg NULL
设置了默认参数pParentWnd
,NULL
表示父"设置为主应用程序窗口。"步入调用CDialog::Create()
CDialog::CreateIndirect()
的{{1}},调用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
到窗口创建的结束可能会搞砸任何创建两个以上窗口的应用程序......