| 樓主 發(fā)表于: 2003-02-20 20:09:45 我曾在VCHLEP發(fā)過(guò)此帖,可惜,沒(méi)人能夠幫我找到問(wèn)題所在………… 以下是帖子正文: 因程序較復雜,不得不貼出一大段源代碼: void CMainFrame::OnSwitchView(WPARAM wParam, LPARAM lParam) { int nPaneID, nView ; nView = (int)lParam ; //根據不同的lParam參數值, 切換到不同的視圖 CView *pOldActiveView = (CView *)m_wndSplitter.GetPane(0, 0) ; // m_wndSplitter是主框架的成員變量,主框架被折分為一行兩列的折分窗口 CView *pNewActiveView = (CView *)m_wndSplitter.GetDlgItem(nView) ; // 基于視圖ID,獲得視圖對象的指針 nPaneID = m_wndSplitter.IdFromRowCol(0, 0) if(pNewActiveView == NULL) { // 如果即將切換到的視圖還未創(chuàng )建,就創(chuàng )建它 switch (nView) { case 100: pNewActiveView = (CView*)new CByNameView ; break ; case 101: pNewActiveView = (CView*)new CMyListView ; break ; case 102: pNewActiveView = (CView*)new CPriceView ; break ; case 103: pNewActiveView = (CView*)new CDocterView ; break ; case 104: pNewActiveView = (CView*)new CJzksView ; break ; } ASSERT(pNewActiveView) ; // 調試到這里發(fā)現pNewActiveView構造成功 // 建立新視圖與文檔的關(guān)聯(lián) CCreateContext context ; context.m_pCurrentDoc = pOldActiveView->GetDocument() ; pNewActiveView->Create(NULL, NULL, 0L, CFrameWnd::rectDefault, &m_wndSplitter, nView, &context) ; // 調試到這里發(fā)現,當Create()調用返回后,pNewActiveView對象的m_hWnd成員 值為:0xdddddddd,導致下一句OnInitialUpdate()調用出現非法操作,也就 是說(shuō),創(chuàng )建窗口失敗 pNewActiveView->OnInitialUpdate() ; } m_wndSplitter.SetActivePane(0, 0, pNewActiveView) ; // 將新創(chuàng )建的視圖在折分窗格的0行0列顯示 pNewActiveView->ShowWindow(SW_SHOW) ; pOldActiveView->ShowWindow(SW_HIDE) ; if(pOldActiveView->GetRuntimeClass() == RUNTIME_CLASS(CByNameView)) pOldActiveView->SetDlgCtrlID(100) ; else if(pOldActiveView->GetRuntimeClass() == RUNTIME_CLASS(CMyListView)) pOldActiveView->SetDlgCtrlID(101) ; else if(pOldActiveView->GetRuntimeClass() == RUNTIME_CLASS(CPriceView)) pOldActiveView->SetDlgCtrlID(102) ; else if(pOldActiveView->GetRuntimeClass() == RUNTIME_CLASS(CDocterView)) pOldActiveView->SetDlgCtrlID(103) ; else if(pOldActiveView->GetRuntimeClass() == RUNTIME_CLASS(CJzksView)) pOldActiveView->SetDlgCtrlID(104) ; pNewActiveView->SetDlgCtrlID(nPaneID) ; } 我在另一個(gè)程序里也曾使用過(guò)相同的方法來(lái)切換(需要時(shí)創(chuàng )建)視圖,未出現任何問(wèn)題,但現在這個(gè)方法卻 不管用了,整整一個(gè)晚上,我都在這個(gè)地方停滯不前,沒(méi)辦法,只好向VCHELP的朋友求助了,希望你能認 真看看我的源代碼,幫我找出問(wèn)題之所在。小弟在此感激不盡………… 后來(lái),VCHLEP一位叫Sam的人給過(guò)一個(gè)回復: 我認為你應該檢查一下Create函數的返回值,如果Create不成功它的m_hWnd會(huì )為0xDDDDDDDD在VC中malloc一個(gè)內存,它的內容會(huì )被賦成0 xDD你的m_hWnd看樣子還沒(méi)有被Create函數賦值??! 獻丑了??! 可惜,沒(méi)能解決問(wèn)題。 后來(lái),我又把我在等待回復時(shí)的一些調試經(jīng)歷寫(xiě)了出來(lái): 等待了這么長(cháng)時(shí)間,只有Sam朋友對我的帖子作出了回復,雖然沒(méi)有解決問(wèn)題,但我仍然要向你表示感謝。 另外,在我心目中的幾位高手,卻未對我提出一點(diǎn)點(diǎn)尋求解決方法的意見(jiàn)或建議,這讓我非常失望。 在等待答案的這段時(shí)間里,我也在孜孜不倦的尋找著(zhù)問(wèn)題的所在?,F把我的一些調試經(jīng)歷寫(xiě)出來(lái),希望能給你一點(diǎn)啟發(fā),幫我解決這個(gè)問(wèn)題。 因為在執行到: pNewActiveView->OnInitialUpdate() ; 時(shí)出現非常操作,我初步判斷是 pNewActiveView->Create(NULL, NULL, 0L, CFrameWnd::rectDefault, this, nView, &context) ; 調用未成功。于是我在調試器中跳入這個(gè)函數繼續跟蹤:(Create()函數的實(shí)現在WINCORE.CPP中) BOOL CWnd::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { // can't use for desktop or pop-up windows (use CreateEx instead) ASSERT(pParentWnd != NULL); ASSERT((dwStyle & WS_POPUP) == 0); return CreateEx(0, lpszClassName, lpszWindowName, dwStyle | WS_CHILD, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, pParentWnd->GetSafeHwnd(), (HMENU)nID, (LPVOID)pContext); } 在測試了pParentWnd的有效性和創(chuàng )建的視圖窗口不能擁有WS_POPUP風(fēng)格后,Create()繼續調用CreateEx() 函數,于是,我又跳入這個(gè)函數中繼續跟蹤: BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam) { // allow modification of several common create parameters CREATESTRUCT cs; cs.dwExStyle = dwExStyle; ... ... ... HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass, cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy, cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams); #ifdef _DEBUG if (hWnd == NULL) { TRACE1("Warning: Window creation failed: GetLastError returns 0x%8.8X\n", GetLastError()); } #endif ... ... } CWnd::CreateEx()函數調用了WIN32 API函數CreateWindowEx()來(lái)創(chuàng )建這個(gè)窗口,返回的窗口句柄被賦給了hWnd,CreateWindowEx()的返回值為0,接著(zhù)hWnd == NULL條件成立,TRACE1()語(yǔ)句被執行,GetLastError()的返回值為:0x00000578,換算成10進(jìn)制是1400。MSDN中,錯誤代碼1400的注釋是: 1400 Invalid window handle. ERROR_INVALID_WINDOW_HANDLE 窗口句柄無(wú)效!請問(wèn)各位大蝦,我要創(chuàng )建窗口,怎么會(huì )窗口句柄無(wú)效呢? 這個(gè)問(wèn)題折磨了我這么長(cháng)的時(shí)間,我的頭都大了。如果那位朋友認為你有能力幫我解決這個(gè)問(wèn)題,請留下你的EMAIL地址,我將把源程序發(fā)給你,請你幫我調試調試。我將對你表示最高謝意! 希望這里能有人可以幫助我。 |
聯(lián)系客服