2017-12-10 21 views
0

CMFCPropertySheet 클래스를 기반으로하는 대화 상자가 있습니다. 내 CMFCPropertySheet 자손의 생성자에서 첫 페이지를 추가하고 또한 모양 (PropSheetLook_Tree) 및 일부 플래그 설정 :CMFCPropertyPage :: 대화 상자가 표시되기 전에 OnKillActive()가 호출됩니다.

// 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_FirstPageCMFCPropertyPage의 후손입니다.

나는 또한 내가 입력 한 데이터가 페이지에 올바른지 확인하려면 각 페이지에 CMFCPropertyPage::OnKillActive()를 오버라이드 CMFCPropertySheet::InitNavigationControl()

나중에 추가 할 다른 페이지가 있습니다.

첫 번째 페이지의 CMFCPropertyPage::OnKillActive() (m_FirstPage)을 두 번 호출하는 것이 문제입니다. 처음 (예기치 않은) 대화 상자가 표시되기 전에 호출됩니다. 두 번째로 - 예상대로 - 사용자가 페이지를 전환하거나 "확인"버튼을 클릭 할 때 호출됩니다. 다른 페이지의 경우 확인을 클릭하거나 페이지를 전환 할 때만 OnKillActive()이 호출됩니다.

첫 번째 m_FirstPage.OnKillActive() 호출 중에 첫 번째 페이지에는 아직 데이터가 없습니다. 그래서 내 코드는 오류 메시지를 보여줍니다.

OnKillActive()이 첫 번째 페이지에 대해 두 번 호출되는 것이 정상입니까? 항상 두 번 그렇게 부르니?

현재 OnKillActive()IsWindowVisible()을 호출하고 표시되지 않으면 페이지의 데이터를 확인하지 않습니다. 이 접근법이 맞습니까?

업데이트 (코드는 비주얼 스튜디오 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 함수입니다 . 다른 non-MFC 응용 프로그램에서 호출했습니다

+0

또는 NULL에 대해 GetSafeHwnd()를 테스트하십시오. –

+0

예기치 않은 첫 번째 OnKillActive 호출에 대한 호출 스택을 제공하십시오! – xMRi

+0

@xMRi 호출 스택을 추가했습니다 – CITBL

답변

0

SetActivePage에 대한 호출이거나 CPropertySheet 파생 클래스의 OnInitDialog 함수에서 PSM_SETCURSEL과 동등한 SendMessage() 호출을 할 것입니다.

(a) SetActivePage 또는 SendMessage (PSM_SETCURSEL) 호출을 제거하고 원하는 초기 탭을 첫 번째 페이지로 만들거나 (b) CPropertyPage 파생 클래스의 생성자에서 유효한 초기 데이터를 설정해야합니다. 또는 (c) 올바르게 초기화 될 때까지 CPropertyPage 파생 클래스에서 유효성 검사를 금지하는 플래그를 설정합니다.

+0

나는'CMFCPropertySheet'와'CMFCPropertyPage' 자손에서 내가 오버라이드 한 모든 메소드를 주석 처리했다.생성자를 제외하고, 이제는 단 하나의 페이지 만 추가하고, 'OnKillActive'는 제외합니다. 'DoModal '을 호출 할 때 여전히'OnKillActive'가 호출됩니다. 또한'CMFCPropertySheet' 생성자는 기본 매개 변수로'UINT iSelectPage = 0'을 가지고 있다는 것을 알았습니다. 그래서 아마도'SetActivePage' MFC에 의해 설계에 의해 호출됩니다 ... 당신이 옵션 (C)에서 제안한대로 유효성을 억제하는 플래그를 설정하는'CPropertyPage'의 가장 좋은 방법은 무엇입니까 말해 주시겠습니까? – CITBL