-1

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

点击窗口框架右上角的“X”按钮关闭窗口并调用PostNcDestroy.

但是,对于四个窗口中的一个,它还PostNcDestroy额外调用另一个窗口的 () 并使该窗口也变得不可见。

有任何想法吗?

4

2 回答 2

0

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

于 2015-11-28T07:24:02.110 回答
0

简短回答:该行为是由在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窗口创建的末尾会可能会搞砸任何创建两个以上窗口的应用程序......

于 2015-11-30T15:01:17.093 回答