MFC:一个 window 上的 X 按钮也在关闭第二个 window
MFC: X button on one window is closing a second window also
我的应用程序有几个 windows,每个都是不同的 CDialog
派生的 class。
点击 window 框架右上角的 "X" 按钮关闭 window 并调用 PostNcDestroy
.
但是,对于四个 windows 之一,它还另外调用另一个 window 的 PostNcDestroy
() 并使 window 不可见。
有什么想法吗?
你提供的信息不多。我们只能猜测...因为您声明所有 windows 都是对话框,我猜想在您的应用程序的 InitInstance() 方法中,您调用了主 CDialog 派生的 DoModal() class.关闭主对话框后,它退出 DoModal() 循环,然后退出 InitInstance() 并关闭应用程序。应用程序关闭导致其他对话框被销毁,导致 WM_NCDESTROY 被发送,然后 PostNcDestroy() 被调用。
简短回答:该行为是由在创建所有四个 windows 之后设置 m_pMainWnd
引起的。如果在创建第二个window之前设置,则不会再出现上述问题。
长答案:问题是 windows 彼此不是兄弟姐妹。它们都是上一个的 CHILD。
Parent of window 1 是值“0”(桌面)。
window 2 的 Parent 是 window 1。
window 3 的 Parent 是 window 2。
window 4 的 Parent 是 window 3.
我最初的问题报告指出 window 4 在 window 3 关闭时神秘关闭。所以现在原因很明显了。 (关闭 window 也会关闭其所有 children。)我随后发现关闭 window 2 也会导致 3 和 4 关闭,这也被考虑在内。 (3 是 2 的 child 所以关闭,这使得 4 是 3 的 child,关闭。)最后,关闭 window 1 检查未保存的工作,如果 none调用 exit()
。我假设如果这个 window 没有退出,另一个 windows 也会全部关闭。
CDialog::Create()
的第二个参数 pParentWnd
有默认参数 NULL
,而 NULL
表示 parent "is set to the main application window." 进入 CDialog::Create()
,它调用 CDialog::CreateIndirect()
,它调用 AfxGetMainWnd()
我最终在 CWinThread::GetMainWnd()
。该方法,如果尚未设置m_pMainWnd
,则returns CWnd::GetActiveWindow()
即most-recently-created window.
所以:问题的根源是我的应用程序创建了四个 windows,然后设置了 m_pMainWnd
。这就是为什么 window 3 是 window 2 的 child(当时活跃的 window)4 是 3 的 child,依此类推。
通过在创建window1之后设置m_pMainWnd
,那么windows2 3和4就是1的children。这样就去掉了"closing window 3 makes window 4 close too"问题。
这仍然不是我所需要的,因为它阻止了 window 1 被带到其他三个 windows 的前面。这超出了我最初问题的范围,但这是解决方法。更改 Create()
调用以明确传入 GetDesktopWindow()
似乎已经让应用程序按我想要的方式运行,四个 windows 可以独立关闭并可以在 window 中自由订购堆栈:
Create( resource_ID, GetDesktopWindow() );
我很惊讶这不是一个著名的问题,因为这些函数的 NONE 的文档(从 VS2008Pro 开始)实际上解释了当未设置 m_pMainWnd
时它们实际做了什么,并将该简单分配移动到 m_pMainWnd
到 window 创建的末尾可能会搞砸任何创建超过两个 windows...
的应用程序
我的应用程序有几个 windows,每个都是不同的 CDialog
派生的 class。
点击 window 框架右上角的 "X" 按钮关闭 window 并调用 PostNcDestroy
.
但是,对于四个 windows 之一,它还另外调用另一个 window 的 PostNcDestroy
() 并使 window 不可见。
有什么想法吗?
你提供的信息不多。我们只能猜测...因为您声明所有 windows 都是对话框,我猜想在您的应用程序的 InitInstance() 方法中,您调用了主 CDialog 派生的 DoModal() class.关闭主对话框后,它退出 DoModal() 循环,然后退出 InitInstance() 并关闭应用程序。应用程序关闭导致其他对话框被销毁,导致 WM_NCDESTROY 被发送,然后 PostNcDestroy() 被调用。
简短回答:该行为是由在创建所有四个 windows 之后设置 m_pMainWnd
引起的。如果在创建第二个window之前设置,则不会再出现上述问题。
长答案:问题是 windows 彼此不是兄弟姐妹。它们都是上一个的 CHILD。
Parent of window 1 是值“0”(桌面)。 window 2 的 Parent 是 window 1。 window 3 的 Parent 是 window 2。 window 4 的 Parent 是 window 3.
我最初的问题报告指出 window 4 在 window 3 关闭时神秘关闭。所以现在原因很明显了。 (关闭 window 也会关闭其所有 children。)我随后发现关闭 window 2 也会导致 3 和 4 关闭,这也被考虑在内。 (3 是 2 的 child 所以关闭,这使得 4 是 3 的 child,关闭。)最后,关闭 window 1 检查未保存的工作,如果 none调用 exit()
。我假设如果这个 window 没有退出,另一个 windows 也会全部关闭。
CDialog::Create()
的第二个参数 pParentWnd
有默认参数 NULL
,而 NULL
表示 parent "is set to the main application window." 进入 CDialog::Create()
,它调用 CDialog::CreateIndirect()
,它调用 AfxGetMainWnd()
我最终在 CWinThread::GetMainWnd()
。该方法,如果尚未设置m_pMainWnd
,则returns CWnd::GetActiveWindow()
即most-recently-created window.
所以:问题的根源是我的应用程序创建了四个 windows,然后设置了 m_pMainWnd
。这就是为什么 window 3 是 window 2 的 child(当时活跃的 window)4 是 3 的 child,依此类推。
通过在创建window1之后设置m_pMainWnd
,那么windows2 3和4就是1的children。这样就去掉了"closing window 3 makes window 4 close too"问题。
这仍然不是我所需要的,因为它阻止了 window 1 被带到其他三个 windows 的前面。这超出了我最初问题的范围,但这是解决方法。更改 Create()
调用以明确传入 GetDesktopWindow()
似乎已经让应用程序按我想要的方式运行,四个 windows 可以独立关闭并可以在 window 中自由订购堆栈:
Create( resource_ID, GetDesktopWindow() );
我很惊讶这不是一个著名的问题,因为这些函数的 NONE 的文档(从 VS2008Pro 开始)实际上解释了当未设置 m_pMainWnd
时它们实际做了什么,并将该简单分配移动到 m_pMainWnd
到 window 创建的末尾可能会搞砸任何创建超过两个 windows...