关于子线程中销毁主线程窗口的问题

来源:互联网 发布:汽车油耗计算器软件 编辑:程序博客网 时间:2024/06/10 03:13



关于子线程中销毁主线程窗口的问题通常销毁或者关闭窗口会用如下函数:[1] CWnd::DestroyWindow()[2] CFrameWnd::OnClose()[3] ::SendMessage(hWnd,WM_SYSCOMMAND,SC_CLOSE,0);    或者::SendMessage(hWnd,WM_CLOSE,NULL,NULL);    之间的关系如下:  After runing the function sendMessage(),thefunction OnClose() will be excuted;  in the function OnClose() , DestroyWindow() will be called in the end    /////////////////////////////////////////////////////////////////////////////// CFrameWnd closing downvoid CFrameWnd::OnClose(){if (m_lpfnCloseProc != NULL){// if there is a close proc, then defer to it, and return// after calling it so the frame itself does not close.(*m_lpfnCloseProc)(this);return;}// Note: only queries the active documentCDocument* pDocument = GetActiveDocument();if (pDocument != NULL && !pDocument->CanCloseFrame(this)){// document can't close right now -- don't close itreturn;}CWinApp* pApp = AfxGetApp();if (pApp != NULL && pApp->m_pMainWnd == this){CDataRecoveryHandler *pHandler = pApp->GetDataRecoveryHandler();if ((pHandler != NULL) && (pHandler->GetShutdownByRestartManager())){// If the application is being shut down by the Restart Manager, do// a final autosave.  This will mark all the documents as not dirty,// so the SaveAllModified call below won't prompt for save.pHandler->AutosaveAllDocumentInfo();pHandler->SaveOpenDocumentList();}// attempt to save all documentsif (pDocument == NULL && !pApp->SaveAllModified())return;     // don't close itif ((pHandler != NULL) && (!pHandler->GetShutdownByRestartManager())){// If the application is not being shut down by the Restart Manager,// delete any autosaved documents since everything is now fully saved.pHandler->DeleteAllAutosavedFiles();}// hide the application's windows before closing all the documentspApp->HideApplication();// close all documents firstpApp->CloseAllDocuments(FALSE);// don't exit if there are outstanding component objectsif (!AfxOleCanExitApp()){// take user out of control of the appAfxOleSetUserCtrl(FALSE);// don't destroy the main window and close down just yet//  (there are outstanding component (OLE) objects)return;}// there are cases where destroying the documents may destroy the//  main window of the application.if (!afxContextIsDLL && pApp->m_pMainWnd == NULL){AfxPostQuitMessage(0);return;}}// detect the case that this is the last frame on the document and// shut down with OnCloseDocument instead.if (pDocument != NULL && pDocument->m_bAutoDelete){BOOL bOtherFrame = FALSE;POSITION pos = pDocument->GetFirstViewPosition();while (pos != NULL){CView* pView = pDocument->GetNextView(pos);ENSURE_VALID(pView);if (pView->GetParentFrame() != this){bOtherFrame = TRUE;break;}}if (!bOtherFrame){pDocument->OnCloseDocument();return;}// allow the document to cleanup before the window is destroyedpDocument->PreCloseFrame(this);}// then destroy the windowDestroyWindow();}//////////////////////BOOL CWnd::DestroyWindow(){CWnd* pWnd;CHandleMap* pMap;HWND hWndOrig;BOOL bResult;if ((m_hWnd == NULL) && (m_pCtrlSite == NULL))return FALSE;bResult = FALSE;pMap = NULL;pWnd = NULL;hWndOrig = NULL;if (m_hWnd != NULL){pMap = afxMapHWND();ENSURE(pMap != NULL);pWnd = (CWnd*)pMap->LookupPermanent(m_hWnd);#ifdef _DEBUGhWndOrig = m_hWnd;#endif}#ifdef _AFX_NO_OCC_SUPPORTif (m_hWnd != NULL)bResult = ::DestroyWindow(m_hWnd);#else //_AFX_NO_OCC_SUPPORTif ((m_hWnd != NULL) || (m_pCtrlSite != NULL)){if (m_pCtrlSite == NULL)bResult = ::DestroyWindow(m_hWnd);elsebResult = m_pCtrlSite->DestroyControl();}#endif //_AFX_NO_OCC_SUPPORTif (hWndOrig != NULL){// Note that 'this' may have been deleted at this point,//  (but only if pWnd != NULL)if (pWnd != NULL){// Should have been detached by OnNcDestroy#ifdef _DEBUGASSERT(pMap->LookupPermanent(hWndOrig) == NULL);#endif}else{#ifdef _DEBUGASSERT(m_hWnd == hWndOrig);#endif// Detach after DestroyWindow called just in caseDetach();}}return bResult;}在子线程里面想关闭或销毁主窗口,不能用方法[1][2],因为在子线程中调用DestroyWindow()的时候 ,pMap = afxMapHWND()会出现问题:pMap = 0.而正常情况下要保证ENSURE(pMap != NULL);而方法[3]会是正确的销毁窗口的方法。

0 0
原创粉丝点击