當一個視窗關閉時WM_CLOSE,WM_DESTROY,WM_QUIT

來源:互聯網
上載者:User

一般是響應WM_CLOSE,調用DestroyWindow()
DestroyWindow()又發送WM_DESTROY
響應WM_DESTROY,調用WM_QUIT
GetMessage()發現WM_QUIT,退出程式

   有三個訊息看起來差不多,都是處理關閉的事情的,它們是WM_CLOSE,WM_DESTROY,和WM_QUIT。它們的確很相似,但你需要知道它們之間的不同!一個視窗或者應用程式應該被關閉時發出WM_CLOSE訊息,當接收到WM_CLOSE訊息時,如果你願意,可以向使用者提出是否真的要退出。你知道讓使用者作確認或有錯誤出現或有什麼應該注意的事情發生的時候,往往彈出一個訊息框。
插播:訊息框
int MessageBox(
HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box
);

1. 當收到WM_CLOSE訊息,你可以做兩件事兒。一件是你接受預設的處理並返回一個值,你若這樣做了,應用程式或視窗按照計劃關閉;或者,你返回0,應用程式或視窗將保持原樣。以下是代碼的基本部分:
if (msg == WM_CLOSE)
{
if (MessageBox(hMainWindow, "Are you sure want to quit?", "Notice", MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
return(0);
// otherwise, let the default handler take care of it
}

2. WM_DESTROY訊息有點兒不同,它是視窗正在關閉時發出的。當收到WM_DESTROY訊息的時候,視窗已經從視覺上被刪除;但一個主視窗被關閉,並不意味著應用程式結束了,因為它可以在沒有視窗的條件下繼續運行。

3. 然而,當一個使用者關閉了主視窗,並希望這意味著是要結束應用程式時,如果你希望真的這麼做,那麼在收到WM_DESTROY訊息的時候,你必鬚髮出一個WM_QUIT訊息。

 4. WM_QUIT是應用程式結束髮出的訊息,一般可以看成進程被kill掉的情況。       5. PostQuitMessage是向系統發出要終止線程的請求,在終止線程前系統還要做些記憶體的清理工作。我們關閉一個程式時是發送WM_CLOSE訊息(函數SendMessage?),然後調用DestroyWindow函數,調用DestroyWindow時系統會向程式發WM_DESTROY訊息,終止整個程式。***************************************************************************************************************************************** 一個對話方塊向另一個對話方塊發視窗關閉訊息對話方塊A CADlg ; 對話方塊B CBDlg

A中聲明B為成員變數 CBDlg m_BDlg;

A發送訊息關閉B :SendMessage(m_BDlg.GetSafeHwnd(), WM_CLOSE, 0, 0);
或者直接:m_BDlg.SendMessage(WM_CLOSE);
*********************************************************************************************************************************************************************************

WM_DESTROY,WM_CLOSE   功能有什麼不同
下面程式執行時出錯
void   CMainFrame::OnClose()   
{
CMDIFrameWnd::OnClose();
CDocument   *doc;
doc=this->GetActiveDocument();
}
下面程式執行時不出錯,
void   CMainFrame::OnDestroy()   
{
CDocument   *doc;
doc=this->GetActiveDocument();
CMDIFrameWnd::OnDestroy();
}  
原因分析:
WM_CLOSE是在視窗關閉前發送的,你還可以決定是否真的關閉視窗
WM_DESTROY是在視窗關閉過程中發送的,視窗已被移出螢幕
你的程式的錯誤在於調用   CMDIFrameWnd::OnClose();   後表單已經
被Destroy掉了,this指標指向的視窗對象已經不存在了,所以出錯
也就是處理順序是先處理WM_CLOSE(視窗未關閉),後處理WM_DESTROY(視窗已關閉)
CMDIFrameWnd::OnClose();後的部分不執行,如需要執行,可放到OnDestroy()中,即你的第二段
調用父類預設處理   CMDIFrameWnd::OnClose()時,   系統又發出了
WM_DESTROY訊息將視窗destroy了,所以OnDestroy中this指標還可以用,
等出了CMDIFrameWnd::OnClose()後this指標指向的視窗對象已經不存在了同理:
void   CMainFrame::OnClose()   
{
CDocument   *doc;
doc=this->GetActiveDocument();
CMDIFrameWnd::OnClose();
}   
將不出錯
下面程式執行時出錯,
void   CMainFrame::OnDestroy()   
{
CMDIFrameWnd::OnDestroy();
CDocument   *doc;
doc=this->GetActiveDocument();
}
原因如下:
OnClose()中調用DestoryWindow(),而DestoryWindow()中發送   WM_DESTROY   和   WM_NCDESTROY;DestoryWindow()執行結束時,OnDestroy()、OnNcDestory()也都執行了,在 CMDIFrameWnd::OnClose()返回後,CMainFrame   的對象已被釋放,this指標不可再用。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.