【发布时间】:2017-12-10 21:26:57
【问题描述】:
我有一个基于CMFCPropertySheet 类的对话框。我在 CMFCPropertySheet 后代的构造函数中添加了第一页,并设置了外观 (PropSheetLook_Tree) 和一些标志:
// constructor code
m_psh.dwFlags|=PSH_NOAPPLYNOW|PSH_NOCONTEXTHELP;
m_psh.hwndParent=hwndParent; // hwndParent - parameter passed to the constructor
m_psh.hInstance=GetModuleHandle(L"mydll");
AddPage(&m_FirstPage);
SetLook(CMFCPropertySheet::PropSheetLook_Tree,190);
m_FirstPage 是CMFCPropertyPage 的后代。
我还有其他页面,稍后在CMFCPropertySheet::InitNavigationControl()中添加
我为每个页面覆盖了CMFCPropertyPage::OnKillActive(),以检查页面上输入的数据是否正确。
问题是第一页的CMFCPropertyPage::OnKillActive()(m_FirstPage)被调用了两次。第一次(意外)它在我的对话框甚至变得可见之前被调用。第二次 - 正如预期的那样 - 当用户切换页面或单击“确定”按钮时调用它。对于其他页面,OnKillActive() 仅在单击确定或切换页面时调用。
问题是在第一次m_FirstPage.OnKillActive() 调用期间,第一页上还没有数据。所以我的代码显示了一条错误消息。
OnKillActive() 在第一页被调用两次是否正常?它总是这样调用两次吗?
目前,我在我的OnKillActive() 中调用IsWindowVisible(),如果它不可见,我不会检查页面上的数据。这种方法正确吗?
(代码用Visual Studio 2008编写)
更新:
第一次意外 OnKillActive() 调用的调用堆栈
CFirstPage::OnKillActive()
CPropertyPage::OnNotify(unsigned int wParam=0, long lParam=1196668, long * pResult=0x00123fc4)
CWnd::OnWndMsg(unsigned int message=78, unsigned int wParam=0, long lParam=1196668, long * pResult=0x00123ffc)
CWnd::WindowProc(unsigned int message=78, unsigned int wParam=0, long lParam=1196668)
AfxCallWndProc(CWnd * pWnd=0x00129370, HWND__ * hWnd=0x000a0348, unsigned int nMsg=78, unsigned int wParam=0, long lParam=1196668)
AfxWndProc(HWND__ * hWnd=0x000a0348, unsigned int nMsg=78, unsigned int wParam=0, long lParam=1196668)
// many calls that look like user32.dll!7e368734()
ATL::CTraceFileAndLineInfo::operator()(unsigned long dwCategory=272, unsigned int nLevel=590706, const wchar_t * pszFmt=0x001d4008, ...)
// many calls that look like user32.dll!7e368734()
CComCtlWrapper::_PropertySheetW(const _PROPSHEETHEADERW_V2 * unnamed1=0x00124f30)
AfxPropertySheetW(const _PROPSHEETHEADERW_V2 * unnamed1=0x00124f30)
CPropertySheet::DoModal()
OpenSettingsDlgBox(HWND__ * hwndParent=0x00040346)
// many calls that look like user32.dll!7e368734()
OpenSettingsDlgBox() 是一个 dll 函数。它是从另一个非 MFC 应用程序调用的
【问题讨论】:
-
或者可以针对 NULL 测试 GetSafeHwnd()。
-
给我们第一个意外 OnKillActive 调用的调用堆栈!
-
@xMRi 我已经添加了调用堆栈
-
必须更多...最后导致 OnKillActive 的一切都很有趣...
-
@xMRi 我已经更新了这个问题。显示所有构造函数代码。扩展调用堆栈。并展示了我如何创建和打开对话框