为什么我将桌面作为我的模态对话框的父HWND?
class CSaveProfileAsDlg:
public CSimpleDialog<IDD_DLG_RESOURCE>
{
....
LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&)
{
...
HWND parent = GetParent(); // or GetAncestor(m_hWnd, GA_PARENT);
assert(parent != GetDesktopWindow()); // not ok
...
}
....
}
//somewhere in code
//m_hWnd is some valid HWND
assert(m_hWnd != GetDesktopWindow()); //ok
CSaveProfileAsDlg dlg;
dlg.DoModal(m_hWnd /*as a parent wnd*/);
我可以解决&#34;通过在CSaveProfileAsDlg
ctor中传递更正HWND,但我希望得到正确的解决方案。
谢谢!
答案 0 :(得分:2)
文档非常令人困惑,但我认为我发现了问题。 DoModal
在内部调用::DialogBox()
,其中一个参数采用名为HWND
的{{1}}。来自documentation:
hWndParent [in,optional]
输入: HWND
拥有对话框的窗口的句柄。
这里的关键字是“拥有”这个词。关于owned windows的部分确认了这一点:
默认情况下,对话框和消息框是拥有的窗口。应用程序在调用创建对话框或消息框的函数时指定所有者窗口。
所以我们实际上谈的是所有者窗口而不是它的父窗口。这是有道理的,因为对话框是一个自由浮动的窗口,而不是“父母身份”所暗示的窗口层次结构的一部分。
您可以使用以下方式获取拥有窗口:
hWndParent
答案 1 :(得分:0)
我有一个类似的问题。我想知道为什么GetParent()总是返回不同的CWnd *。
正确的解决方案很简单,只需将所需的pWnd
传递给dlg构造函数。
它将存储在CDialog成员变量m_pParentWnd
中。
然后,您始终可以在对话框中使用此成员变量获取传递的pWnd。
//somewhere in code
//pWnd some valid CWnd pointer
CSaveProfileAsDlg dlg (pWnd); // relevant!
dlg.DoModal();
。
class CSaveProfileAsDlg:
public CSimpleDialog<IDD_DLG_RESOURCE>
{
....
LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&)
{
...
CWnd* _pWnd = GetParent(); // not ok, returns probably CMainFrame or similiar
CWnd* pWnd = m_pParentWnd; // your parent Wnd
...
}
....
}
答案 2 :(得分:0)
我有同一个应用程序的两个版本,其中一个禁用了调用DoModal时应禁用的所有父弹出窗口。第二个版本仅禁用顶级CMainFrame,并且真正的父级保持启用状态,因此我可以调用模式对话框两次或更多次。
这发生在CWnd :: GetSafeOwner_中,行: hWnd = :: GetLastActivePopup(hWnd);
第一个版本返回实际父级,而第二个版本返回CMainFrame。 我花了一天的时间,找不到这种行为的原因。但是我找到了解决方法:
调用DoModal时,它会禁用CMainFrame,因此我也可以禁用它的孩子:
afx_msg void OnEnable(BOOL bEnable);
ON_WM_ENABLE()
void CMainFrame::OnEnable(BOOL bEnable)
{
std::for_each(m_bars.begin(), m_bars.end(),
[=](const std::pair<EBar, BaseBar*>& bar)
{
bar.second->EnableWindow(bEnable);
});
}