Win32程式設計技術

//2002/2/21 酷小毅於永和
(1).Win32的記憶體管理
image
各位若有經過Win31時代,玩過Win31也就是Win16的應用程式應該會發現,在win16下的應用程式共用相同的記憶體位址空間,在Win31下所有被執行的應用程式(Process)他們會存取到一塊由Windows所提供的一塊記憶體空間,也就是說應用程式可能會不小心存取到被其他應用程式所使用的記憶體位址,嚴重時甚至造成系統死當.而在Win32下Windows會載入一種稱為保護模式(不是win9x當機時進去的保護模式),在這個模式下會由Windows來掌控所有的應用程式Process, Thread,所有的應用程式訊息,使用者所產生的訊息包括鍵盤滑鼠等訊息,都必須透過Windows來達成,包括應用程式之間要存取另一個應用程式的資料或存取CMOS/BIOS資訊都必須透過Windows來達成,所以Windows當然回提供一系列windows的介面來完成這些事,這個介面就是Win32 API(Application Programming Inteerface).
(2).Event driven事件驅動概念
Windows是一個充滿訊息的環境,在Windows下不斷的都有訊息流動,有時是Windows的訊息有時為System的訊息,有時是User的訊息,給應用程式的訊息經由應用程式轉換成事件,在交由應用程式相對應的事件處理常式來處裡該事件,有些則可能是某應用程式Send給其他應用程式的訊息,有些是使用者透過鍵盤滑鼠所產生的訊息,若將訊息分類則可分為:(1)Windows message (2) Application message. (3)User message.等,不過若對應用程式而言訊息就是訊息沒什麼不同,應用程式通常會有如下的一個while迴圈來接收並指派訊息給對應的處裡常式處裡
while(GetMessage(&Msg, null, null, null))
{
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);

在Windows下每一個視窗裡都會有處裡這些訊息的處裡函式來處裡執行相對應的動作,Windows的程式設計師就是要負責來完成這些動作的程式碼,判斷訊息種類在加已處裡,這也是Windows程式設計的重要觀念.
在Windows下每一個視窗裡都會有處裡這些訊息的處裡函式來處裡執行相對應的動作,Windows的程式設計師就是要負責來完成這些動作的程式碼,判斷訊息種類在加已處裡,這也是Windows程式設計的重要觀念.
(3).Win32 的多工
image
在了解Win32的多工時先了解行程(Process), 執行緒(Thread)的觀念,Process==>為Windows所分配給一個應用程式的記憶體供它執行的行程空間,這個行程的實際位址只有Windows會知道而已,當應用程式要傳遞訊息給其他應用程式時,Windows會透過所配置給應用程式的Handle得知實際的位址,Handle事時上如同一個指標一樣,若沒透過Windows API,Handle值對應用程式而言只是一個無用的4Byte的長整數而已,應用程式無法存取甚至是修改其他程序的記憶體資料,相較於Win16的機制隨時可能會跨越到不該跨越的記憶體區段來的安全許多,不過當然它也不是完全沒有缺點這我們稍後章節再討論.
Win32所採用的多工方式為先佔式多工,上圖所示在Windows系統中會在固定的時間中斷目前的程式將控制權交給目前處理的下一個程式,目前的程式必須在上圖輪完一圈之後才又輪到它執行,這種方式稱為先佔式多工,也就是說同一時間只會有一個程序被處裡,但是這個切換非常的快速,對使用者而言就好像所有的程式是同時再執行一般.
(4).Windows訊息的分派
了解了Win32的多工及訊息驅動的概念之後,我現在在來說明Windows的訊息分送大概有下面兩種方法.
PostMessage 這個API函式會將訊息存入應用程式的訊息佇列中,只有當應用程式本身事情做完有機會抓取佇列訊息時才會被處裡,你不會知道訊息何時會被處裡.
SendMessage 這個API函式則會立即將訊息傳遞給目的程序中的視窗或元件,目的程序會立即處裡該訊息,該函式還可回傳一個LongInt的值給訊息發出端,它也可以算是一種同步的方式那上一種就算是非同步的方式了.
(5).多執行緒程式設計
最後還是要讓大家了解什麼是執行緒??..何時會使用到,用執行緒會加快程式速度嗎??..Oh~No. No. No...執行緒並不會加快程式的執行速度,太多的執行緒只是讓CPU花更多時間切換而以,是不會加快程式執行速度的......不好意思先說這個觀念,因為我覺得這個觀念非常重要,所以....,好了不說廢話,Win32的執行模型還是基於最上面的行程(Process),執行緒(Thread),這屬高階的觀念,我們知道行程是一個應用程式的一個執行實體,而執行緒則是一個行程中運作處裡的一個運作實體,當一個視窗向Windows提出申請=>CreateWindow()時,Windows會建構這個視窗所需的行程虛擬記憶體空間及其他相關資源,還有建構視窗時當然必須先有一個主要的執行緒開始執行本身的初始化,接著該執行緒就會不斷的跑預設的While Loop接收並處裡Message.
你若是使用C,C++撰寫應用程式時通常需要自行撰寫這個回圈來監視訊息並判斷訊息種類加以處裡,只要應用程式開始執行後你就可以用Win32 API的CreateThread來產生其他的執行緒,通常我會利用背景執行緒來幫應用程式處裡一些可在背景執行並不是最需要馬上處裡的工作,微軟建議儘量不要使用執行緒處裡一些UI上的建立,用了執行緒最到的好處是背景處裡工作時也不會影響到前端UI的處理.如MediaPlayer撥放時即使你移動視窗他仍然在撥放,因為撥放函式交由另一個執行緒來處理.

留言

這個網誌中的熱門文章

軟體工程師 - 成長的 10 個階段

常見的程式碼壞味道(Code Smell or Bad Smell)

什麼是 gRPC ?