三個退出程序消息WM_CLOSE、WM_DESTROY、WM_QUIT

1、發送消息SendMessage、PostMessage

PostMessage將消息放入消息隊列後馬上返回,而SendMessage直到窗口過程處理完消息後才返回

2、三個消息的區別

WM_CLOSE:

  在系統菜單裏選擇了“關閉”或者點擊了窗口右上角的“X”按鈕,你的窗口過程就會收到WM_CLOSE。DefWindowProc對 WM_CLOSE的處理是調用DestroyWindow。當然,你可以不讓DefWindowProc處理,而是自己處理,例如詢問用戶是否保存更改等。如果用戶選擇“取消”,你忽略此消息,那麼程序照常運行;如果用戶確認要退出,你就調用DestroyWindow。


WM_DESTROY:

  接下來,DestroyWindow完成窗口的清理工作,最後像窗口過程發送WM_DESTROY。對於 WM_DESTROY,DefWindowProc不會處理。也就是說,你如果不處理這個消息,雖然你的窗口已經銷燬,但進程並不會結束。一般處理 WM_DESTROY時都是釋放資源(例如申請的內存等),然後調用PostQuitMessage。

 

WM_QUIT:

  PostQuitMessage會發送WM_QUIT給消息隊列。注意,WM_QUIT永遠不會到達窗口過程,因爲GetMessage得到WM_QUIT後就會返回FALSE,從而結束消息循環,最後進程結束,程序退出。

 

 

假設使用者執行HELLOWIN,並且使用者最終單擊了 Close按鈕,或者假設用鍵盤或鼠標從系統菜單中選擇了 Close, DefWindowProc處理這一鍵盤或者鼠標輸入,在檢測到使用者選擇了Close選項之後,它給窗口消息處理程序發送一條WM_SYSCOMMAND消息。WndProc將這個消息傳給DefWindowProc。 DefWindowProc給窗口消息處理程序發送一條WM_CLOSE消息來響應之。WndProc再次將它傳給DefWindowProc。 DestroyWindow呼叫DestroyWindow來響應這條WM_CLOSE消息。DestroyWindow導致Windows給窗口消息處理程序發送一條WM_DESTROY消息。WndProc再呼叫PostQuitMessage,將一條WM_QUIT消息放入消息隊列中,以此來響應此消息。這個消息導致WinMain中的消息循環終止,然後程序結束。

3、退出程序語句

exit(0);

postquitmessage(0);

onok();oncancel();

sendmessage(wm_close,0,0);

exitprocess(0);

其中以exit(0)最爲迅速,在實踐方面

 

 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

有三個消息看起來差不多,都是處理關閉的事情的,它們是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指針不可再用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章