我有一个基于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
)被调用两次。在我的对话框变为可见之前,它第一次(意外)被调用。第二次 - 正如预期的那样 - 当用户切换页面或点击" OK"按钮。对于其他页面,仅在单击“确定”或切换页面时才会调用OnKillActive()
。
问题是,在第一次m_FirstPage.OnKillActive()
通话期间,第一页上还没有数据。所以我的代码显示了一条错误消息。
第一页调用OnKillActive()
两次是正常的吗?它总是被称为两次吗?
目前,我在IsWindowVisible()
中呼叫OnKillActive()
,如果不可见,我就不会检查网页上的数据。这种方法是否正确?
(代码是用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应用程序调用的
答案 0 :(得分:0)
我打赌它是因为在CPropertySheet派生类的OnInitDialog中调用了SetActivePage或与PSM_SETCURSEL的等效SendMessage()调用功能
您应该(a)删除对SetActivePage或SendMessage(PSM_SETCURSEL)的调用,只需将所需的初始选项卡设置为第一个,或者(b)在CPropertyPage派生类的构造函数中设置有效的初始数据,或者(c)设置一个标志以禁止在CPropertyPage派生类中进行验证,直到它被正确初始化为止。