关于子线程中销毁主线程窗口的问题
2016-10-30 22:47
225 查看
关于子线程中销毁主线程窗口的问题
通常销毁或者关闭窗口会用如下函数:
[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 down
void 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 document
CDocument* pDocument = GetActiveDocument();
if (pDocument != NULL && !pDocument->CanCloseFrame(this))
{
// document can't close right now -- don't close it
return;
}
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 documents
if (pDocument == NULL && !pApp->SaveAllModified())
return; // don't close it
if ((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 documents
pApp->HideApplication();
// close all documents first
pApp->CloseAllDocuments(FALSE);
// don't exit if there are outstanding component objects
if (!AfxOleCanExitApp())
{
// take user out of control of the app
AfxOleSetUserCtrl(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 destroyed
pDocument->PreCloseFrame(this);
}
// then destroy the window
DestroyWindow();
}
//////////////////////
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 _DEBUG
hWndOrig = m_hWnd;
#endif
}
#ifdef _AFX_NO_OCC_SUPPORT
if (m_hWnd != NULL)
bResult = ::DestroyWindow(m_hWnd);
#else //_AFX_NO_OCC_SUPPORT
if ((m_hWnd != NULL) || (m_pCtrlSite != NULL))
{
if (m_pCtrlSite == NULL)
bResult = ::DestroyWindow(m_hWnd);
else
bResult = m_pCtrlSite->DestroyControl();
}
#endif //_AFX_NO_OCC_SUPPORT
if (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 _DEBUG
ASSERT(pMap->LookupPermanent(hWndOrig) == NULL);
#endif
}
else
{
#ifdef _DEBUG
ASSERT(m_hWnd == hWndOrig);
#endif
// Detach after DestroyWindow called just in case
Detach();
}
}
return bResult;
}
在子线程里面想关闭或销毁主窗口,不能用方法[1][2],因为在子线程中调用DestroyWindow()的时候 ,
pMap = afxMapHWND()会出现问题:pMap = 0.而正常情况下要保证ENSURE(pMap != NULL);
而方法[3]会是正确的销毁窗口的方法。
通常销毁或者关闭窗口会用如下函数:
[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 down
void 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 document
CDocument* pDocument = GetActiveDocument();
if (pDocument != NULL && !pDocument->CanCloseFrame(this))
{
// document can't close right now -- don't close it
return;
}
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 documents
if (pDocument == NULL && !pApp->SaveAllModified())
return; // don't close it
if ((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 documents
pApp->HideApplication();
// close all documents first
pApp->CloseAllDocuments(FALSE);
// don't exit if there are outstanding component objects
if (!AfxOleCanExitApp())
{
// take user out of control of the app
AfxOleSetUserCtrl(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 destroyed
pDocument->PreCloseFrame(this);
}
// then destroy the window
DestroyWindow();
}
//////////////////////
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 _DEBUG
hWndOrig = m_hWnd;
#endif
}
#ifdef _AFX_NO_OCC_SUPPORT
if (m_hWnd != NULL)
bResult = ::DestroyWindow(m_hWnd);
#else //_AFX_NO_OCC_SUPPORT
if ((m_hWnd != NULL) || (m_pCtrlSite != NULL))
{
if (m_pCtrlSite == NULL)
bResult = ::DestroyWindow(m_hWnd);
else
bResult = m_pCtrlSite->DestroyControl();
}
#endif //_AFX_NO_OCC_SUPPORT
if (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 _DEBUG
ASSERT(pMap->LookupPermanent(hWndOrig) == NULL);
#endif
}
else
{
#ifdef _DEBUG
ASSERT(m_hWnd == hWndOrig);
#endif
// Detach after DestroyWindow called just in case
Detach();
}
}
return bResult;
}
在子线程里面想关闭或销毁主窗口,不能用方法[1][2],因为在子线程中调用DestroyWindow()的时候 ,
pMap = afxMapHWND()会出现问题:pMap = 0.而正常情况下要保证ENSURE(pMap != NULL);
而方法[3]会是正确的销毁窗口的方法。
相关文章推荐
- 关于窗口Qt线程停止的问题
- Unity关于有些代码不能在除主线程外的线程使用的问题
- 关于android 线程的销毁问题
- MFC:关于MFC窗口对象(CWnd对象)与Window对象(HWND所指对象)的销毁问题
- windows游戏开发中一个关于Visual Studio的编译链接成功,输出窗口却显示线程已退出。无法运行项目的问题
- 关于调用系统照相机等,onActivityResult之后Activity被销毁问题解决
- 关于线程的终止问题
- android有关线程的销毁问题
- 关于同步线程安全问题
- 看了IBM上关于轻便线程的内容,对其中轻便线程的效率问题有疑惑。
- 关于java线程的停止问题(转载至 http://dev.21tx.com 2005年05月03日 Matrix-与Java共舞 )
- 关于在线程中使用AfxGetMainWnd()出错的问题,终于找到了
- 关于模态窗口,子窗口刷新父窗口的问题
- 关于OS中第一线程的问题解决.
- java高级多线程编程(一)--关于线程的停止问题
- 关于线程中显示toast等操作问题
- 补充说明:关于Beaglebone black上debian无图形界面的问题及QT的窗口示例
- 关于iPhone/iPad的iOS系统自动弹出认证窗口问题
- 工作线程中调用UI线程创建的窗口的UpdateData会导致Assert的问题及解决办法
- 关于asp.net和iis的进程/线程问题,假如网站有1000个人访问,会产生多少个进程/线程啊