關(guān)于Windows程序模型的最重要之處在于,程序是在Windows面向?qū)ο蟮捏w系結(jié)構(gòu)中運(yùn)行的。
在WinMain()函數(shù)中,程序所進(jìn)行的最重要工作是注冊(cè)窗口類(lèi),從而把自定義的窗口過(guò)程提供給Windows。然后程序調(diào)用Windows創(chuàng)建和顯示窗口,由此啟動(dòng)同用戶(hù)的交互過(guò)程。在消息循環(huán)中,程序不斷取得消息,但并不進(jìn)行處理,而是將其發(fā)回Windows,由Windows將消息發(fā)給相應(yīng)的窗口過(guò)程。消息循環(huán)的作用在于控制生命期,如果沒(méi)有消息循環(huán),進(jìn)程將立即結(jié)束。
在較高層次上來(lái)看,一個(gè)可擴(kuò)展的系統(tǒng)會(huì)給模塊提供資源和自由,而模塊應(yīng)當(dāng)配合系統(tǒng)的整體結(jié)構(gòu)。程序執(zhí)行時(shí),Windows會(huì)為其創(chuàng)建進(jìn)程,分配資源,并調(diào)用WinMain()。WinMain()是進(jìn)程入口,也是進(jìn)程出口,在此期間進(jìn)程可以做任何事情,但是為了使用Windows提供的各種便利,它必須符合Windows程序模型,將自己的運(yùn)行結(jié)合到Windows環(huán)境中。作為進(jìn)程出口,WinMain()決定著程序生命期。一個(gè)提供窗口過(guò)程而等待Windows調(diào)用的程序如何維持和結(jié)束自己的生命期呢,應(yīng)該由消息來(lái)決定。當(dāng)進(jìn)程沒(méi)有要處理的消息時(shí),它應(yīng)該等待,所以WinMain()必須知道有沒(méi)有消息,Windows發(fā)給窗口過(guò)程的消息不能繞過(guò)WinMain();當(dāng)進(jìn)程收到特定的消息時(shí),它結(jié)束生命期,所以WinMain()還應(yīng)該了解消息的內(nèi)容。這正是GetMessage()所做的,如果取不到消息就阻塞,如果取到WM_QUIT消息就返回0,結(jié)束消息循環(huán)。那么如果取到普通的消息呢,由WinMain()直接調(diào)用窗口過(guò)程不可以嗎?這種做法有悖于程序由Windows調(diào)用的基本思想,而實(shí)際上也會(huì)出現(xiàn)問(wèn)題。一個(gè)窗口程序可能有很多窗口類(lèi),一些窗口類(lèi)及其窗口過(guò)程是程序自定義的,另一些則是在Windows內(nèi)部定義的,程序看不到其窗口過(guò)程,比如各種控件窗口。窗口程序運(yùn)行起來(lái)以后,這些窗口類(lèi)互相配合,它們通信的方式就是消息。由于消息指向的窗口過(guò)程可能是自定義的,也可能是Windows內(nèi)部的,只有Windows才能把它們都送到目的地,并保持發(fā)送方式的一致性。所以WinMain()取到消息后,通過(guò)DispatchMessage()將其發(fā)回Windows,由Windows為其調(diào)用適當(dāng)?shù)拇翱谶^(guò)程,直到窗口過(guò)程調(diào)用后返回Windows,DispatchMessage()才返回。(Windows調(diào)用窗口過(guò)程之后控制首先返回Windows,由WinMain()調(diào)用窗口過(guò)程之后控制保持在程序中,這種區(qū)別是否也有作用?不過(guò)經(jīng)我試驗(yàn),在一個(gè)Win32 SDK的Hello程序中改由WinMain()調(diào)用窗口過(guò)程,沒(méi)有發(fā)現(xiàn)什么問(wèn)題)
參考資料:
1.《Windows程序設(shè)計(jì)》/Charles Petzold 著 北京博彥科技發(fā)展有限公司 譯 北大出版社