当来自 DLL 的 运行 时,C++ CDialogEx 丢失 ParentWnd
C++ CDialogEx losses ParentWnd when run from DLL
我有情况。
有一个巨大的应用程序(C++ MFC)。我写了一个带有可停靠窗格的 .dll 模块。
Pane interface structure:
Pane -> CMFCToolBar
-> CSplitterWndEx -> CListCtrl
-> CDialogEx
这就是我创建 DialogEx 的方式:
int CMyPane::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
///////////////////////////////////////////
////////// TAB CTRL ///////////////////////
///////////////////////////////////////////
const int dwResTabCtrlStyle = WS_CHILD | WS_VISIBLE | TCS_VERTICAL;// | LVS_SINGLESEL;
if(!m_SptitterWndEx.AddTabCtrl(0, 1, &m_tabCtrl, CMFCTabCtrl::STYLE_3D, CMFCBaseTabCtrl::LOCATION_TOP, CSize(10,10)))
return -1;
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_DialogEx.Create(CAccuracyResultPage::IDD, NULL);
}
m_DialogEx.SetParent(&m_tabCtrl);
if(!m_DialogEx.GetParent())
return -1;
str.LoadString( AfxGetStaticModuleState()->m_hCurrentResourceHandle, IDS_RESULT_TAB);
m_tabCtrl.AddTab(&m_DialogEx, str, 0);
AdjustLayout();
return 0;
}
我在 CDialogEx::PreTranslateMessage 上断言。原因是当它到达时 parents
_AFXWIN_INLINE CWnd* CWnd::GetParent() const
{ ASSERT(::IsWindow(m_hWnd)); return CWnd::FromHandle(::GetParent(m_hWnd)); }
m_hWnd 不是 Wnd。但是 CDialog 看起来完全没问题,它有 m_pParentWnd,但它不是 m_tabCtrl。
所以我的问题是:为什么 CDialogEx 不设置它的 parent?!以及如何处理?!
您的对话框模板位于何处?它在同一个dll中吗?如果不是,那么我认为这是你的问题。
我的猜测是,如果您的对话框模板驻留在不同的 dll 中,那么 windows 可能会在该 dll 的模块状态的 HWND=>CWnd 映射中搜索。如果发生这种情况,它将无法在映射中找到 CWnd 并将创建一个临时 CWnd 对象并将其设置为对话框的父对象。
我有情况。 有一个巨大的应用程序(C++ MFC)。我写了一个带有可停靠窗格的 .dll 模块。
Pane interface structure:
Pane -> CMFCToolBar -> CSplitterWndEx -> CListCtrl -> CDialogEx
这就是我创建 DialogEx 的方式:
int CMyPane::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
///////////////////////////////////////////
////////// TAB CTRL ///////////////////////
///////////////////////////////////////////
const int dwResTabCtrlStyle = WS_CHILD | WS_VISIBLE | TCS_VERTICAL;// | LVS_SINGLESEL;
if(!m_SptitterWndEx.AddTabCtrl(0, 1, &m_tabCtrl, CMFCTabCtrl::STYLE_3D, CMFCBaseTabCtrl::LOCATION_TOP, CSize(10,10)))
return -1;
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_DialogEx.Create(CAccuracyResultPage::IDD, NULL);
}
m_DialogEx.SetParent(&m_tabCtrl);
if(!m_DialogEx.GetParent())
return -1;
str.LoadString( AfxGetStaticModuleState()->m_hCurrentResourceHandle, IDS_RESULT_TAB);
m_tabCtrl.AddTab(&m_DialogEx, str, 0);
AdjustLayout();
return 0;
}
我在 CDialogEx::PreTranslateMessage 上断言。原因是当它到达时 parents
_AFXWIN_INLINE CWnd* CWnd::GetParent() const
{ ASSERT(::IsWindow(m_hWnd)); return CWnd::FromHandle(::GetParent(m_hWnd)); }
m_hWnd 不是 Wnd。但是 CDialog 看起来完全没问题,它有 m_pParentWnd,但它不是 m_tabCtrl。
所以我的问题是:为什么 CDialogEx 不设置它的 parent?!以及如何处理?!
您的对话框模板位于何处?它在同一个dll中吗?如果不是,那么我认为这是你的问题。
我的猜测是,如果您的对话框模板驻留在不同的 dll 中,那么 windows 可能会在该 dll 的模块状态的 HWND=>CWnd 映射中搜索。如果发生这种情况,它将无法在映射中找到 CWnd 并将创建一个临时 CWnd 对象并将其设置为对话框的父对象。