樓主 發(fā)表于: 2003-02-20 20:09:45 我曾在VCHLEP發(fā)過此帖,可惜,沒人能夠幫我找到問題所在………… 以下是帖子正文: 因程序較復雜,不得不貼出一大段源代碼: void CMainFrame::OnSwitchView(WPARAM wParam, LPARAM lParam) { int nPaneID, nView ; nView = (int)lParam ; //根據(jù)不同的lParam參數(shù)值, 切換到不同的視圖 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) ; // 調(diào)試到這里發(fā)現(xiàn)pNewActiveView構造成功 // 建立新視圖與文檔的關聯(lián) CCreateContext context ; context.m_pCurrentDoc = pOldActiveView->GetDocument() ; pNewActiveView->Create(NULL, NULL, 0L, CFrameWnd::rectDefault, &m_wndSplitter, nView, &context) ; // 調(diào)試到這里發(fā)現(xiàn),當Create()調(diào)用返回后,pNewActiveView對象的m_hWnd成員 值為:0xdddddddd,導致下一句OnInitialUpdate()調(diào)用出現(xiàn)非法操作,也就 是說,創(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) ; } 我在另一個程序里也曾使用過相同的方法來切換(需要時創(chuàng)建)視圖,未出現(xiàn)任何問題,但現(xiàn)在這個方法卻 不管用了,整整一個晚上,我都在這個地方停滯不前,沒辦法,只好向VCHELP的朋友求助了,希望你能認 真看看我的源代碼,幫我找出問題之所在。小弟在此感激不盡………… 后來,VCHLEP一位叫Sam的人給過一個回復: 我認為你應該檢查一下Create函數(shù)的返回值,如果Create不成功它的m_hWnd會為0xDDDDDDDD在VC中malloc一個內(nèi)存,它的內(nèi)容會被賦成0 xDD你的m_hWnd看樣子還沒有被Create函數(shù)賦值!! 獻丑了??! 可惜,沒能解決問題。 后來,我又把我在等待回復時的一些調(diào)試經(jīng)歷寫了出來: 等待了這么長時間,只有Sam朋友對我的帖子作出了回復,雖然沒有解決問題,但我仍然要向你表示感謝。 另外,在我心目中的幾位高手,卻未對我提出一點點尋求解決方法的意見或建議,這讓我非常失望。 在等待答案的這段時間里,我也在孜孜不倦的尋找著問題的所在?,F(xiàn)把我的一些調(diào)試經(jīng)歷寫出來,希望能給你一點啟發(fā),幫我解決這個問題。 因為在執(zhí)行到: pNewActiveView->OnInitialUpdate() ; 時出現(xiàn)非常操作,我初步判斷是 pNewActiveView->Create(NULL, NULL, 0L, CFrameWnd::rectDefault, this, nView, &context) ; 調(diào)用未成功。于是我在調(diào)試器中跳入這個函數(shù)繼續(xù)跟蹤:(Create()函數(shù)的實現(xiàn)在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風格后,Create()繼續(xù)調(diào)用CreateEx() 函數(shù),于是,我又跳入這個函數(shù)中繼續(xù)跟蹤: 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()函數(shù)調(diào)用了WIN32 API函數(shù)CreateWindowEx()來創(chuàng)建這個窗口,返回的窗口句柄被賦給了hWnd,CreateWindowEx()的返回值為0,接著hWnd == NULL條件成立,TRACE1()語句被執(zhí)行,GetLastError()的返回值為:0x00000578,換算成10進制是1400。MSDN中,錯誤代碼1400的注釋是: 1400 Invalid window handle. ERROR_INVALID_WINDOW_HANDLE 窗口句柄無效!請問各位大蝦,我要創(chuàng)建窗口,怎么會窗口句柄無效呢? 這個問題折磨了我這么長的時間,我的頭都大了。如果那位朋友認為你有能力幫我解決這個問題,請留下你的EMAIL地址,我將把源程序發(fā)給你,請你幫我調(diào)試調(diào)試。我將對你表示最高謝意! 希望這里能有人可以幫助我。 |