天天看點

遊戲程式設計之二 windows程式設計基礎

  第二章 windows程式設計基礎

    第一節 引言

    為了跟上潮流,我們抛棄了已快被淘汰的DOS作業系統,所有的講解和例程都是基于微

軟的Windows作業系統的。考慮到很多的使用者并沒有Windows程式設計基礎,是以我們設定了這

一專門講述、讨論Windows的術語、概念的部分,以使這部分使用者能較快地了解和掌握我們

所講述、讨論的程式設計思想和程式設計方法。這一部分中主要講述的是Windows中十分基本的東西

,是以使用者應根據自己的情況有選擇的進行學習。好!現在就讓我們進入艱苦而又精彩有

趣的遊戲程式設計之路吧! 

    第二節 windows的介紹

    Windows應用程式可以采用面向過程的實作方法。也可以使用面向對象的結構。所有的實作方法都內建了點選控制和彈出菜單,能夠運作特别為Windows編寫的應用程式。

    Windows是一種基于圖形界面的多任務作業系統。為這個環境開發的程式(那些專門為Windows設計的)有着相同的外觀和指令結構。對使用者來說,這使得學習使用Windows應用程式變得容易了。為了幫助開發Windows應用程式,Windows提供了大量的内建函數以友善地使用彈出菜單、滾動條、對話框、圖示和其他一些友好的使用者界面應該具有的特性。

  Windows運作應用程式以硬體無關的方式來處理視訊顯示、鍵盤、滑鼠、列印機、串行口以及系統時鐘。

    最值得注意的Windows特性就是其标準化的圖形使用者界面。統一的界面使用圖檔或圖示來代表磁盤驅動器、檔案、子目錄以及其它作業系統的指令和動作。 統一的使用者界面也為程式員帶來了好處。例如,你可以很友善地使用常見菜單和對話框的内建函數。所有的菜單都具有相同風格的鍵盤和滑鼠接口,因為是Windows而不是程式員在實作它。

    Windows的多任務環境允許使用者在同一時刻運作多個應用程式或同一個應用程式的多個執行個體。一個應用程式可能處于激活狀态。激活的應用程式是指它正接收使用者的輸入。因為每一個瞬間僅有一個程式能夠被處理,是以同一時間也隻能有一個應用程式處于激活狀态。但是,可以有任意個數的并行運作的任務。

  

    第三節 windows的基本概念

    Windows消息和面向對象程式設計

  Windows實作了一種仿OOP(面向對象程式設計)環境。Windows下的消息系統負責在多任務環境中分解資訊。從應用程式的角度來看,消息是關于發生的事件的通知。使用者可以通過按下或移動滑鼠來産生這些事件,也可以是通過改變視窗大小或選擇一個菜單項等。這些事件也可以由應用程式本身産生。Windows本身也能産生消息。如“關閉Windows”消息,Windows通過這個消息來通知所有的應用程式,Windows将被關閉。

  記憶體管理

  在Windows系統中系統記憶體是最重要的共享資源之一。當同一時刻有多個應用程式在運作時,為了不耗盡系統資源,每個應用程式必須合作以共享記憶體。同時,當啟動新的程式和關閉老的程式時,記憶體會變得碎片化。通過移動記憶體中的代碼和資料塊,Windows能夠使記憶體空閑空間連起來。在Windows下也有可能超量使用記憶體。例如,應用程式可以比記憶體容量大。Windows能夠廢棄目前不使用的代碼,在以後需要時再從應用程式中将之讀入記憶體。Windows應用程式可以共享可執行檔案中的例程。包含可共享的例程的檔案稱為動态連結庫(DLL)。Windows包括了運作時将DLL例程鍊入程式的機制。

    硬體無關性

  Windows同時提供了硬體或裝置無關性,使你免于在生成程式的時候不得不考慮所有可能使用的顯示器、列印機或輸入裝置。在Windows下面,每種硬體裝置的驅動程式隻編寫一次。硬體無關性使程式設計對應用程式開發者來說更為簡單。應用程式與Windows而不是各種裝置打交道。

    動态鍵接庫

  動态鍵接庫提供了更多的Windows功能。它們通過一個有力而靈活的圖形使用者界面增強了基本的作業系統。動态鍵接庫包括一些預定義的函數,它們可以在一個應用程式被調入時與之鍵接(動态地),而不是在應用程式被建立時(靜态地)。動态鍵接庫使用DLL字尾。函數庫将每一個程式員從重複開發諸如讀取字元或格式化輸出之類的通用例程中解放出來。程式員可以友善地構造它們自己的庫以包含更多的功能,比如改變字型或檢驗文本。把函數變為通用工具減少了備援設計,這是OOP的一個關鍵特性。

       Windows的庫是被動态地鍵接的。或者說,鍵接器并不把函數拷貝到程式的可執行檔案中去。相反,當程式運作時,它産生對庫函數的調用。自然,這樣做節約了記憶體。不管有多少應用程式在運作,在RAM中總是隻有庫的一份考貝,而這個庫可以被共享。

    Windows的可執行檔案格式 

    Windows具有一種新的可執行檔案的格式,稱為New Excutable格式。它包括新型的檔案頭,能夠儲存有關DLL函數的資訊。

  第四節 windows的視窗

  Windows的視窗

  視窗看起來就是顯示裝置中的一個矩形區域,它的外觀與特定的應用程式無關,可是,對于一個應用程式來說,視窗是螢幕上應用程式能夠直接控制的矩形區域。應用程式能夠建立并控制主視窗的一切,如大小和形狀。當使用者啟動一個程式時,一個視窗就被建立了。使用者每次單擊視窗,應用程式作出響應。關閉一個視窗會使應用程式結束。多視窗帶給使用者Windows的多任務能力。通過将螢幕分為不同的視窗,使用者能夠使用鍵盤或滑鼠選擇一個并行運作的應用程式,以此對多任務環境中的一個特定程式進行輸入,Windows截取了使用者的輸入并配置設定必要的資源(例如微處理器)。

Windows的布局

  所有的Windows應用程式都具有諸如邊框、控制菜單、About對話框之類的共同特征。這些特征使得各個Windows應用程式非常類似。

邊框

    Windows的視窗被邊框所包圍。邊框由圍出視窗的線條組成。對于新手而言,邊框看起來僅僅是為了将一個應用程式的螢幕視口與其它的差別開。但是,對于熟練者,邊框有着不同的作用。例如,如果将滑鼠指針放在邊框上并按下滑鼠的左鍵,使用者就可以改變視窗的大小。

标題條

    應用程式的名字顯示在視窗頂部的标題條中。标題條總是在相關視窗頂部的中央。标題條非常有用,它可以幫助你記住正在運作哪個應用程式。活動應用的标題條以不同于非活動應用程式的顔色顯示。

控制圖示

    控制圖示是每個視窗左上方的小圖檔,每個應用程式都使用它。在控制圖示上單擊滑鼠鍵會使Windows顯示系統菜單。

系統菜單

    當用滑鼠單擊控制圖示時就打開了控制菜單。它提供了諸如Restore,Move,Size,Minimize,Maximize以及Close這樣的标準操作。

最小化圖示

    每個Windows 95或Windows NT應用程式都在視窗的右上角顯示三個圖示。最左邊的圖示是一段短下劃線,這就是最小化圖示。它可以使用程式被最小化。

最大化圖示

    最大化圖示是三個圖示中中間的那一個,看起來象兩個小視窗。使用最大化圖示可以使用應用程式占滿整個螢幕。如果選擇了這個圖示,其它應用程式視窗都會被蓋住。

垂直滾動條

    如果有必要,應用程式可以顯示一個垂直滾動條。垂直流動條顯示在應用程式視窗的右邊,在兩端有兩個方向相反的箭頭。它還有一個着色的棒和一個透明的視窗塊。後者被用于顯示目前顯示内容與整個文檔(着色的棒)的關系。你可以用滾動條來選擇顯示哪一頁。一般在任何一個箭頭上單擊一下會使顯示内容移動一行。單擊向上箭頭下方的視窗塊并拖動它會使螢幕輸出快速更新到應用程式螢幕輸出的任意位置。

水準滾動條

    也可以顯示一個水準滾動條。水準滾動條顯示在視窗的底部,具有與垂直滾動條類似的功能。你用它來選擇要顯示哪些列。一般在任何一個箭頭上單擊一個會使顯示内容移動一列。單擊向左箭頭右邊的視窗塊并拖動它會使螢幕輸出快速更新到應用程式螢幕輸出的任意位置。

菜單條

    一個可選擇的菜單條可以顯示在标題條的下方。通過菜單條來選擇菜單和子菜單。這種選擇可以通過用滑鼠單擊,也可以用熱鍵組合來實作。熱鍵組合經常是ALT與指令中帶下劃線的字母的組合,比如File指令中的“F”。

使用者區

    通常使用者區占據了視窗最大的部分。這是應用程式的基本輸出區域。應當由應用程式來複雜管理使用者區。另外,應用程式可以輸出到使用者區。

    第五節 windows的類

    視窗的基本元件有助于說明應用程式的外觀。有的時候應用程式需要建立兩個外觀和表現都相似的視窗。Windows的Paint就是一個例子。借助于同時運作Paint的兩個執行個體(或拷貝),Paint允許使用者剪貼或拷貝圖檔的一部分。然後資訊就可以從一個執行個體拷貝到另一個執行個體。Paint的每個運作執行個體的外觀和表現都與其他的相同。這就需要每個執行個體建立自己的外觀和功能類似的視窗。

    在這種情況下被建立的外觀和功能都很類似的視窗被稱為是屬于同一個視窗類的。但是,你建立的視窗可以有不同的特征。它們可以有不同的大小,不同的位置,不同的顔色或不同的标題,也可以使用不同的光标。

    每個被建立的窗都基于一個視窗類。在用C語言開發撕于的基于傳統的函數調用方式的應用程式中,一些視窗為在Windows應用程式初始化的進修注冊。你的應用程式可以注冊屬于自己的視窗類。為了能夠使幾個視窗在同一個視窗類的基礎上建立,Windows定義了一些視窗特征,如CreateWindows()的參數,另一些定義的視窗類的結構。當你注冊一個視窗類的時候,這個類可以被Windows下運作着的任何程式所使用。對于使用MFC的應用程式來說,多數注冊工作已經由預定義的對象完成了。

    具有相似的外觀和表現的視窗可以被組合成一個類,以此來減少需要維護的資訊。因為每個視窗類都有自己的可共享的類結構,不需要複制不必要的視窗類參數。同時,同類的兩個視窗使用相同的函數以及相關的例程。這樣可以節省時間和空間,因為不存在代碼複制。

    第六節 windows中的面向對象程式設計

    在Windows下傳統的C程式吸收了一些面向對象程式設計的特性。對象是一種包含資料結構和對這些資料結構進行操作的函數的抽象資料類型。而且,對象接收會引起它們不同動作的消息。

    比如,一個Windows的圖形對象是可以被作為一個實體來操縱的一些資料的集合,對于使用者它是可視界面的一部分。特别地,一個對象意味這資料和資料的功能。菜單、标題條、控制塊以及滾動條等都是圖形對象的例子。下一部分描述一些影響應用程式外觀的新的圖形對象。

    圖示

  圖示是用來使用記住特定操作、想法或産品的小圖形對象。比如,一個電子表格程式被最小化時可以顯示一個很小的柱狀圖以提醒使用者這個程式還在運作之中。在柱狀圖上輕按兩下滑鼠會使Windows激活這個應用程式。圖示是非常有力的工具。它很适合用來引起使用者的注意,比如在發出錯誤警告或者是向使用者提供選擇時。

    光标

  光标是Windows用來跟蹤指點裝置的運動的圖形符号。這種圖形符号可以改變形狀以指明特定的Windows操作。比如,當标準的箭頭光标變為沙漏光标時說明Windows正在執行一個指令,需要暫停。

    編輯光标

  應用程式在視窗中顯示編輯光标以告訴使用者在哪兒輸入。編輯光标與其他螢幕符号顯然不同,因為它是閃爍的。多數時候,滑鼠輸入與光标相連,而鍵盤輸入與編輯光标相連。但是,可以用滑鼠來改變編輯光标的輸入點。

    消息框

  消息框是另一類Windows圖形對象。消息框是一種包含标題、圖示和消息的彈出式視窗。圖(?)是關閉Windows Notepad程式時出現的一個标準的消息框。

  -------------------------------------------------------------------------

|                                                                          |  

    ------------------------------------------------------------------------

      Windows的對話框

  對話框與消息框相似的地方在于它也是一種彈出式視窗。但是對話框主要用于接受使用者輸入而不僅僅是顯示一些輸出。對話框允許應用程式接受輸入,每次一個域或是一個框的内容,而不是每次一個字元。圖(?)顯示了一個典型的Windows對話框。對知框的圖形設計由Windows為你自動完成。對話框的布局通常用編譯器中的資源編輯器完成。

    -----------------------------------------------------------------------           

   |                                                                       |

    -----------------------------------------------------------------------      

    字型

  字型是一種圖形對象或資源,它定義了完整的字元集合的字樣。這些字元都有一個特定的大小和風格,可以使文本具有不同的外觀。字樣是字元的一種基本屬性,它定義了字元的襯線和筆畫寬度。

    位圖

    位圖是一種顯示圖檔(按像素組織),存儲于記憶體。當應用程式需要快速顯示圖檔時可以使用位圖。因為位圖直接從記憶體中傳送,是以它比用程式重新畫出圖檔要快得多。位圖有兩個基本用途。首先,它可以在螢幕上顯示圖檔。其次位圖也用于建立刷子。刷子使你可以在螢幕上畫出并填充對象。

  使用位圖有兩個缺點。首先,與其尺寸有關,位圖會占據難以預估的大量記憶體。每個被顯示的像素都要在記憶體中占據相應的空間。在彩色顯示器上顯示一個像素會比在單色顯示器上占據更多的記憶體。在單色顯示器上,隻需一位(bit)就可以表示出像素的狀态。可是在可以顯示16種顔色的彩色顯示器上,需要四位才能表示一個像素的特征。同樣地,随着顯示裝置分辨率的增加,位圖對記憶體的需求也增加了。位圖的另一個缺點是它隻包括靜态的圖檔。比如,如果用位圖來代表一輛汽車,就沒有辦法來通路圖檔的不同部分,如輪踏、頂蓋、窗等。但是,如果汽車是有一系列基本繪圖例程來生成的,應用程式就可以改變向這些例程傳送的資料進而改變圖檔的不同部分。例如,應用程式可以修飾頂蓬線并把一輛轎車變為敞蓬車。

    畫筆

  當Windows在螢幕上顯示一個圖形時,它使用目前畫筆的資訊。畫筆用于畫出線條或輪廊。畫筆具有三個基本特征:線寬、線型(虛線、短線、實線)以及顔色。Windows永遠保留着用于畫白線和黑線的畫筆,任何應用程式可以使用它。你也可以建立自己的畫筆。

   刷子

  Windows用刷子來畫出顔色并以預定義的樣式來填充一個區域。刷子至少有8×8個像素大小。刷子有三個基本特征:樣式和顔色。由于它們至少有8×8的大小,刷子被稱作具有樣式而不象畫筆,稱為線型。樣式可以是純的顔色,也可以是陰影線、斜線或其它使用者自定義的組合 

  第七節 windows的消息

    Windows的消息

  在Windows中,應用程式并不直接寫螢幕、處理硬體中斷或直接對列印機輸出。相反,應用程式使用合适的Windows函數或者等待一個适當的消息被發出。

  Windows消息系統負責在多任務環境中分派消息。從應用程式的角度來看,消息可以看作是發生的事件的通知,有些需要作出特定的反應,有些就不需要。這些事件可能由使用者産生,比如按下了滑鼠或移動了滑鼠,改變了視窗的大小或者選擇了一個菜單。同時,這些事件也可能由應用程式本身所産生。

  這個過程使你的應用程式必須完全面向消息處理。當接收到消息時,應用程式必須能激活并決定正确的動作,完成這個動作之後回到等待狀态。

  通過檢查消息的格式和來源,下一部分将更仔細地讨論消息系統。

消息的格式

  消息通知一個應用程式發生了一個事件。從技術上來講,消息不僅僅是與應用程式相關,而且是與應用程式的某一特定視窗有關。是以,所有的消息都被發往視窗。

  在Windows下隻有一個消息系統-即系統消息隊列。但是,每個正在Windows下運作的應用程式都有它自己的消息隊列。系統消息隊列中的每個消息最終都要被USER子產品傳送到應用程式的消息隊列中去。應用程式的消息隊列中存儲了程式的所有視窗的全部消息。

  不管消息具有什麼類型,它們都有四個參數:一個視窗句柄,一個消息類型,兩個附加的32位參數。視窗消息中定義的第一個參數是消息所關聯的視窗句柄。

  在編寫Windows應用程式的時候經常使用句柄。句柄是一個唯一的數字,它被用于辨別許多類型的對象,如菜單、圖示、畫筆和刷子、記憶體配置設定、輸出裝置甚至視窗執行個體。在Windows 95和Windows NT下面,程式的每個運作着的拷貝叫做執行個體。

  因為Windows 95和Windows NT允許你同時運作一個程式的多個執行個體,作業系統就有必要保持對這些執行個體的追蹤。這是通過賦予每個運作執行個體一個唯一的執行個體句柄來實作的。

  執行個體句柄通常被用作一個内部維護着的表的索引。通過引用表中的元素而不是實際的記憶體位址,Windows 95和Windows NT可以動态地調整所有的資源,而隻需在此資源所對應的表格位置中插入一個新的位址。

  根據一個應用程式的多個執行個體被處理的方式,記憶體資源由Windows 95和Windows NT儲存。

  應用程式的執行個體具有很重要的作用。應用程式的執行個體定義了程式的函數所需的所有對象。這包括控件、菜單、對話框以及更多的新Windows類。

  消息中的第二個參數是消息類型。這是在Windows獨有的一些頭檔案中定義的辨別符。這些頭檔案可以通過WINDOWS.H來使用。在Windows下,每個消息由兩個字元的助記符開始,跟着是下劃線,最後是一個描述符。

  最後的兩個參數提供了解釋消息所需的附加資訊。是以最後兩個參數的内容依賴于消息的類型。

    産生消息

  消息傳送概念使Windows能夠實作多任務。消息有四個基本來源。應用程式可以從使用者那兒接受消息,也可以是Windows本身,應用程式本身或者是其它應用程式。

  使用者消息包括按鍵消息、滑鼠移動、滑鼠指點或單擊、菜單選擇、滾動條的定位等。應用程式必須花費大量的時間來處理使用者消息。使用者産生的消息表明運作程式的人希望改變應用程式的表現方式。

  無論何時,如果狀态發生改變,将會有一個消息被發往應用程式。一個例子是使用者單擊了應用程式的圖示,表明他們想要将此應用程式變為活動的應用程式。在這種情況下,Windows告訴應用程式它的主視窗被打開了,它的大小和位置被改變了等等Windows産生的消息可以被處理,也可以被忽略,這跟應用程式目前的狀态有關。

    相應消息

    在傳統的面向過程的C語言Windows應用程式中,對于遇到的每一種消息,它都有一個相應的過程來處理這消息。不同的視窗對相同的消息會産生不同的響應。Windows把每個消息發送到應用程式的不同視窗,而不同的視窗對相同的消息會有不同解釋。不令應用程式需要不同的過程來處理每一種消息,每一個視窗也應有不同的過程來處理不同的消息。視窗過程集合了應用程式的所有消息處理過程。

    消息循環

    所有Windows應用程式的一個基本組成就是消息處理循環。每一個C應用程式都在内部執行這個操作。C應用程式包含了建立并初始化視窗的過程,随後是消息處理循環,最後是結束應用程式所需的一些代碼。消息循環負責處理Windows發給主程式的消息。在這兒,程式知道有了消息,并且要求Windows将消息發送到合适的視窗過程以供處理。當消息被接受時,視窗過程就執行希望的動作。

    第八節 windows的函數

    Windows向應用程式開發人員提供了數以百計的函數。這些函數的例子包括DispatchMes-sage(),PostMessage(),RegisterWindowMessage()以及SetActiveWindow()。對于使用基礎類庫的C++程式員,許多函數自動被運作。

    在16位的Windows 3.x下的函數聲明包括一個pascal修飾符,這在DOS下更為有效Windows95和Windows NT下的32位應用程式不再使用這個修飾符。如你所知,所有Windows函數的參數是通過系統來傳遞的。函數的參數從最右邊的參數開始向左壓入棧,這是标準的C方式。在從函數傳回之前,調用過程必須按原來壓入棧的位元組數調整棧指針。

    第九節 windows應用程式架構

    Windows頭檔案:WINDOWS.H

    WINDOWS.H頭檔案(以及其它相關檔案)是所有程式的内在部分。傳統上,WINDOWS.H是所有C語言編寫的Windows應用程式必需的一部分。當在C++中使用基礎類庫時,WINDOWS.H包括在AFXWIN.H頭檔案中。

     Windows應用程式的組成

   在開發Windows應用程式的過程中有一些重要的步驟:

  *用C語言編寫WinMain()函數和相關的視窗函數,或者在C++中使用基礎類,比如CWinApp等。

    *建立菜單、對話框和其它資源并把它們放入資源描述檔案。

    *(可選)使用Vinsual C++編譯器中的企業編輯器來建立對話框。

    *用項目檔案來編譯并連結所有的C/C++源程式和資源檔案  

    Windows應用程式中的組成部分

    1. WinMain()函數

    Windows 95和Windows NT需要一個WinMain()函數。這是應用程式開始執行和結束的地方。

    從Windows向WinMain()傳遞四個參數。下面的代碼段示範了這些參數的使用:

     int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPreInst,

          LPSTR 1pszCmdLine, int nCmdShow)

    第一個參數hInst包含了應用程式的執行個體句柄。當應用程式在Windows下運作時,這個數字唯一辨別了應用程式。

    第二個參數hPreInst将始終是一個NULL值,表明沒有這個應用程式的其它執行個體正在運作,因為在Windows 95和Windows NT下每個應用程式都在它自己單獨的位址空間中運作。

    第三個參數1pszCmdLine是指向一個以'/0'結尾的字元串的長指針,這個字元串代表了應用程式的指令行參數。

    WinMain()的第四個參數是nCmdShow。在nCmdShow中存儲的整數代表了Windows預定義的許多常量中的一個,它決定了視窗顯示的方式。

    2. WNDCLASS

    WinMain()負責注冊應用程式的主視窗類。每個視窗類都建立在一些使用者選擇的風格、字型、标題字、圖示、大小、位置等的基礎上。視窗類實際上是定義這些屬性的一個模闆。

  基本上,所有的Windows類定義都使用相同的标準C/C++結構。下面的例子是一個說明WNDCLASSW結構的typedef語句,WNDCLASS是從這兒繼承的:

     typedef struct tagWNDCLASSW

          UINT      style;

          WNDPROC   1pfnWndProc;

          int       cbClsExtra;

          int       cbWndExtra;

          HANDLE    hInstance;

          HICON     hIcon;

          HCURSOR   hCursor;

          HBR8USH   hbrBackground;

          LPCWSTR   1pszMenuName;

          LPCWSTR   1pszClassName;

          WNDCLASSW,*PWNDCLASSW,NEAR*NPWNDCLASSW,            FAR*LPWNDCLASSW;

    下面的部分讨論了WNDCLASS結構中的不同的域。其中有些域可以被賦予NULL,告訴Windows使用預設的預定義值。

    style:style域指明了類風格。

  1pfnWndProc:接受一個指向視窗函數的指針,它将執行所有的視窗任務。

  cbClsExtra:指定了必須在視窗類結構後面配置設定的位元組數,它可以是NULL。

  cbWndExtra:指定了必須在視窗執行個體後面配置設定的位元組數,它可以是NULL。

  hInstance:定義了注冊視窗類的應用程式執行個體。它必須是一個執行個體句柄,不得是NULL。

  hIconhIcon:劃定利用視窗最小化時顯示的圖示。它可以是NULL。

  hCursorhCursor:定義了應用程式使用的光标。這個句柄可以是NULL。

    hbrBackground:提供了背景刷子的辨別符。

    1pszMenuName:是指向一個以空字元結尾的字元串的指針。這個字元串是菜單的資源名。這一項可以為NULL。

    1pszClassName:是指向一個以空字元結尾的字元串的指針。這個字元串是視窗類的名字。

    3.WNDCLASSEX

    Windows提供了一種擴充的WNDCLASS定義,名為WNDCLASSEX,它允許應用程式使用小圖示。下面是WNDCLASSEX結構的定義:

     typedef struct WNDCLASSEX

          HCURSOR   hbrBackground;

          LPCTSTR   1pszMenuName;

          LPCTSTR   1pszClassName;

          HICON     hIconSm;

       WNDCLASSEX;

    你可以看到這兩個結構是相同的,除了WNDCLASSEX包括了hIconSm成員,這是與視窗類有關的小圖示的句柄。

    4.定義視窗類

    應用程式可以定義它們自己的視窗類,隻要先定義一個合适類型的結構,然後用視窗類的資訊來填充結構的域。

    下面的代碼示範了如何定義并初始化一個WNDCLASS結構。

     char szProgName[]="ProgName";

          .

     WNDCLASS wcApp;

     wcApp.1pszClassName=szProgName;

     wcApp.hInstance=hInst;

     wcApp.1pfnWndProc=WndProc;

     wcApp.hCursor=LoadCursor(NULL,IDC-ARROW);

     wcApp.hIcon=NULL;

     wcApp.1pszMenuName=szAppIName;

     wcApp.hbrBackground=GetStockObject(WHITE-BRUSH);

     wcApp.style=CS-HREDRAW| CS-VREDRAW;

     wcApp.cbClsExtra=0;

     wcApp.cbWndExtra=0;

     if(!RegisterClass (&wcApp))

          return 0;

    WNDCLASS結構中的第二個域是wcApp.hInstance,它被賦予了WinMain()被激活後傳回的hInst的值。這指明了應用程式的目前執行個體。1pfnWndProc被賦予執行所有視窗任務的視窗函數的指針位址。對于大部分應用程式,這個函數叫做WndProc()。

  注意:WndProc()是一個使用者定義而不是預定義的函數名。在指派語句之前必須給出函數原型。

       wcApp.hCursor域被賦予執行個體的光标句柄。

    當wcApp.1pszMenuName被賦予NULL值的時候,Windows就認為這個視窗類沒有菜單。  如果有,菜單必須有一個名字,它必須出現在引号裡面。GetStockOject()函數傳回一個刷子句柄,用于在這個類建立的視窗使用者區中畫出背景色。

    wcApp.style視窗類風格被設為CS-HREDRAW或CS-VREDRAW。

    最後的兩個域,weApp.cbClsExtra以及wcApp.cbWndExtra經常被設為0。這些域可以被選用以指明視窗結構和視窗資料結構後面應該保留的附加位元組數。

   下面這段代碼用于注冊視窗類:

     if(!hpreInst)

     if(! RegisterClass(&wcApp))

          return FALSE;

    Windows 95和Windows NT通過檢查hPreInst的值來确定多少個執行個體,而hPreInst總是NULL,是以就注冊視窗類.

    5.建立視窗

    視窗通過調用CreateWindow()函數來建立。這個過程對所有版本的Windows都是一樣的。視窗類定義了視窗的一般特征,允許同一個視窗類被用于多個不同的視窗,CreateWin-dow()函數的參數指明了關于視窗的更詳細的資訊。

 CreateWindow()函數的參數資訊包括以下内容:視窗類、視窗标題、視窗風格、幕位置、視窗的父句柄、菜單句柄、執行個體句柄以及32位的附加資訊。在大部分應用程式中 ,這個函數會是下面這個樣子:

     hWnd=CreateWindow(szProgName,"Simple Windows Program",

          WS-OVERLAPPEDWINDOW,CW-USEDEFAULT,

          CW-USEDEFAULT,CW-USEDEFAULT,

          CW-USEDEFAULT,(HWND)NULL,(HMENU)NULL,

          (HANDLE)hInst,(LPSTR)NULL);

    第一個域szProgName(已賦過值)定義了視窗的類,後面是視窗标題條上使用的标題。視窗的風格是第三個參數

    下面的六個參數代表了視窗的x、y坐标和x、y方向的大小,然後是父視窗句柄和視窗菜單句柄。每個域都被賦予一個預設值。hInst域包含了程式的執行個體句柄,後面是一個附加參數(NULL)。

    顯示和更新視窗

  在Windows下,ShowWindow()函數被用來實際顯示一個視窗。下面的代碼示範了這個函數:

     Show Window(hWnd,nCmdShow);

    在調用CreateWindow()時生成的視窗句柄被用作hWnd參數。ShowWindow()的第二個參數是nCmdShow,決定了視窗被如何顯示。這個顯示狀态也被稱為視窗的可視狀态。

    顯示視窗的最後一步是調用Windows的Update Window()函數。

     UpdateWindow(hWnd);

    6.消息循環

     一旦調用Win-Main()函數并顯示了視窗,應用程式就需要一個消息處理循環。最常用的實作方法是使用一個标準的while循環:

     while (GetMessage (&lpMsg,NULL,0,0))

     {

          TranslateMessage(&lpMsg);

          DispatchMessage(&lpMsg);

     }

       GETMESSAGE()函數:應用程式要處理的下一個消息可以通過調用Windows的GetMessage()函數來取得。

       NULL參數訓示函數取回這個應用程式的任何視窗的任何消息。最後兩個參數0和0告訴GetMessage()不要使用任何消息過濾器。消息過濾器能夠将接收到的消息限制在一個明确的範圍之内,如鍵盤消息或滑鼠消息等。

    一般應用程式應該确認通向消息循環的所有步驟都已經正确地執行過了。這包括确認每個視窗類都已經注冊過,都已經被建立。否則,一旦進入了消息循環,隻有一個消息能夠結束這個循環。無論何時處理了WM-QUIT消息,傳回值是FALSE。這會引發主循環關閉例程。WM-QUIT消息是應用程式退出消息循環的唯一途徑。

    TRANSLATEMESSAGE()函數:通過TranslateMessage()函數,虛拟消息可以被轉換為字元消息。

    DISPATCHMESSAGE()函數:Windows通過DispatchMessage()函數将目前的消息發送到正确的視窗過程。

*******    視窗函數

       所有的應用程式都必須包括一個WinMain()函數和一個回調視窗函數。因為一Win-dows應用程式從不直接通路任何視窗函數,每個應用程式都必須向Windows提出請求以執行規定的操作。

       一個回調函數在Windows中注冊,當Windows要對一個視窗進行操作時,它就被調用。各個應用程式的回調函數的實際代碼長度會大不相同。視窗函數本身可以非常小,隻處理一個或兩個消息,也可以非常大而且複雜。

    下面的代碼段(不完整的應用程式說明語句)顯示了在應用程式中的回調視窗函數WndProc()的一個範例:

     LRESULT CALLBACK WndProc(HWND hWnd,UNIT messg,

               WPARAM wParam,LPARAM 1Param)

          HDC hdc;

          PAINTSTRUCT ps;

          switch(messg)

               case WM-PAINT:

                    hdc=BeginPaint(hWnd,&ps);

                         .

                    ValidateRect(hWnd,NULL);

                    EndPaint(hWnd,&ps);

                    break;

               case WM-DESTROY:

               postQuitMessage(0);

               break;

          default:

               return(DefWindowProc(hWnd,messg,wParam,1param));

          return(0);

    Windows希望視窗類結構定義中wcApp,1pfnWndProc域的名字能夠與回調函數的名

字比對。後面用這個視窗類建立的所有視窗的回調函數都應該用WndProc()的名字。

    下面的代碼段讨論一個視窗類結構中回調函數名的位置和指派:

               .

          wcApp.1pszClassName=szProgName;

          wcApp.hInstance=hInst;

          wcApp.1pfnWndProc=WndProc;

        Windows有向百個消息可以發送給視窗函數。這些消息用“WM-”打頭的辨別符來

辨別。

       WndProc()的第一個參數是hWnd。hWnd包含了Windows發送消息的視窗句柄。

        函數的第二個參數messg按WINUSER.H中的定義指明了即将被處理的實際消息。最後的兩個參數wParam以及1Param,指明了處理每個消息所需的附加資訊。

    WndProc()函數繼續定義了兩個變量:hdc指明了顯示裝置句柄,ps指明了存儲使用者區

資訊所需的一個PAINTSTRUCT結構。

    回調函數被用于檢查将被處理的消息并選擇執行适當的動作。這個選擇過程通常在一個标準的C語言的switch語句中完成。

子產品定義檔案

    正如你在前面學到的,LINK提供了所有Windows應用程式需要的子產品定義檔案在指令行方式下的替代品。子產品定義檔案向連結器提供有關的定義和描述資訊,這樣連結器就可以知道如何來組織Windows應用程式的可執行檔案。這些資訊已經成為新執行檔案格式的檔案頭的一部分。

    注意:在Windows 95和Windows NT下面,你不太可能需要建立一個子產品定義檔案。這些資訊是為了完整性和向後相容。

  第十節 VC++提供的windows程式設計工具

  Visual C++編譯器包含幾個資源編輯器。單獨的編輯器可以通過編譯器主菜單中的Insert Resource菜單來運作。圖形對象都是資源,象圖示、光标、消息框、對話框、字型、位圖、畫筆、刷子等。資源代表應用程式的可執行檔案中包含的資料。

  資源編譯器RC.EXE是一個Windows資源的編譯器。。

  資源以及附加的編譯器的使用增加了應用程式開發的複雜性。但是它容易在項目工具中使用。

    項目檔案

  項目檔案提供了概覽資源和程式代碼編譯過程的手段,同時也可以使應用程式的可執行版本保持最新。它們跟蹤源檔案的日期和時間以實作這些增強的功能。項目檔案包含了有關特定程式的編譯鍊過程的資訊。項目檔案是在內建的C或C++編輯環境中建立的。項目檔案還支援增強的編譯和連結。

    資源

  當你使用VisualC++編譯器提供的資源編輯器時,用自己的圖示、指針和位圖來定制Windows應用程式非常容易。這些編輯器給你提供了一個開發圖形資源的完整環境。這些編輯器同時也能幫助你開發菜單和對話框-Windows下資料輸入的基本手段。這些編輯器還能幫你操縱單獨的位圖、加速鍵和字元串。。

    資源編輯器

  每一種編輯器都在VisualC++環境中提供,都是編譯器的一個內建的部分。這樣,每種編輯器都是在Windows下運作的完全內建的資源開發工具。你可以通過選擇Insert Resource來啟動每一種編輯器。

    下面我們将通過教程示範資源編輯器的使用。請單擊傳回,然後運作教程。

?  第十一節 MFC的基本概念

  基礎類庫為你提供了易于使用的對象。将Windows與C++聯系起來是很自然的,這樣就可以充分利用面向對象技術的優點。MFC開發組實作了大量的Windows應用程式程式設計接口(API)。這個C++庫在一些可重用的類中封裝了最重要的資料結構和API函數調用。

  類似MFC這樣的類庫比起前面兩章讨論的C程式員使用的函數庫有很多優點。

    下面列出了C++類的一些優點,比如:

  *用類對資料和代碼進行封裝

  *繼承性

  *消除函數和變量名的沖突

  *類是語言的自然擴充

  *通常,精心設計的庫減少了代碼量

  利用基礎類庫,建立一個視窗所需的代碼大約隻占傳統應用程式的三分之一。這就可以使程式員隻用花很少的時間與Windows打交道,把更多的精力集中在開發自己的程式代碼上。

22.2 MFC的設計考慮

  基礎類庫設計小組定義了嚴格的設計規則,在設計MFC庫時必須遵循這些規則。這些規則和方針如下:

  *利用C++的威力,但不能把程式員吓倒

  *使從标準API調用到類庫的轉換盡可能簡單

  *允許混合使用傳統的函數調用和新的類庫

  *在設計類庫的時候綜合考慮功能和效率

  *建成的類庫必須能夠友善地在不同平台間移植,如Windows 95和Windows NT

    設計小組感到要開發高品質的代碼必須從MFC庫本身開始。C++基礎類庫必須又小又快。它的簡單性使它易于使用,而執行速度與龐大的C函數庫接近。

  這些類的設計方式應該讓熟練的Windows程式員不必重新學習各種函數的名字。通過仔細的命名和設計可以實作這一點。Microsoft認為這一點是MFC差別于其它類庫的一個特征。

    MFC小組還把基礎類庫設計為是允許以混合方式程式設計的。這就是說,在同一個源檔案裡,既可以使用類也可以使用傳統的函數調用。即使是在使用MFC時,類似SetCursor()和GetSystemMetrics()這樣的函數還是需要直接調用。

    Microsoft也知道類庫必須友善使用。其它廠商提供的一些類庫設計得太抽象。按Microsoft的說法,這些笨重的類企圖生成又大又慢的應用程式。MFC庫提供了合理的抽象,保證代碼很小。

    開發小組将原始的MFC庫設計為動态的而不是靜态的。動态的結構是這些類可以适應我們現在使用的Windows 95和Windows NT環境。

22.3 MFC庫的關鍵特性

    從其它編譯器廠商那兒也可以獲得Windows類庫,但Microsoft宣稱他們的MFC類庫具有許多真正的優點:

  *全面支援所有的Windows函數、控件、消息、GDI(圖形裝置接口)繪圖原語、菜單以及對話框。

  *使用與Windows API相同的命名約定。是以,從名字上就可以直接知道類的功能。

  *消除了一個錯誤源,即大量的switch/case語句。所有的消息都被映射到類的成員函數。這種消息-方法的映射方法應用于所有的消息。

  *能夠把對象的資訊輸出到檔案,這提供了更好的診斷支援。同時還提供了驗證成員變量的能力。

  *增強的例外處理設計,使得程式代碼失敗的可能性更小。能夠解決“記憶體不足”以及其它一些問題。

  *可以在運作時決定資料對象的類型。這允許對類的域進行動态操縱。

  *小而快速的代碼。前面已經提到,MFC庫隻添加了很少一些代碼,執行起來幾乎與傳統的C語言Windows應用程式一樣快。

    *對元件對象模型(COM)的支援。

    有經驗的Windows程式員會立刻喜歡上其中的兩個特性:熟悉的命名約定和消息-方法映射機制。如果你重新檢查一下在第二十一章中開發的應用程式的源代碼,你會看到大量用于處理錯誤的switch/case語句。還應該注意這些應用程式調用了大量的API函數。當你使用MFC庫的時候,這兩種現象都消失或減少了。

    專業程式員肯定會欣賞在MFC庫中實作的更好的診斷和很小的代碼。現在程式員就可以利用MFC庫的好處而不必擔心他們的應用程式的代碼大小了。

    最後,MFC是唯一真正有用的類庫。

22.4 一切從CObject類開始

    類似MFC這樣的類庫通常都來自很少的幾個基類。然後,另外的類就可以從這些基類中繼承而來。CObject是在開發Windows應用程式時大量使用的一個基類。在MFC/INCLUDE子目錄下提供的MFC庫頭檔案包括了許多類定義資訊。

    我們來簡單地看一下,CObject,它在頭檔案AFX。H中有定義:

     ///

     //class CObject is the root of all compliant objects

     class CObject

     public:

     //Object model(types,destruction,allocation)

          virtual CRuntimeClass*GetRuntimeClass () const;

          virtual~CObject();//virtual destructors are necessary

     //Diagnostic allocations

     void*PASCAL operator new(size-t nSize);

     void*pascal operator new(size-t,void*p);

     void PASCAL operator delete(void*p);

     #if defined(-DEBUG)&&!defined(-AFX-NO-DEBUG-CRT)

     //for file name/line number tracking using DEBUG-NEW

     void* PASCAL operator new(size-t nSize,

               LPCSTR 1pszFileName,

               int nLine);

     //Disable the copy constructor and assignment by default

     //so you will get compiler errors instead of unexpected

     //behavior if you pass objects by value or assign objects.

     protected:

          CObject();

     private:

          CObject(const CObject& objectSrc);//no implementation

          void operator=(const CObject& objectSrc);

     //Attributes

          BOOL IsSerializable()const;

          BOOL IsKindOf(const CRuntimeClass*pClass)const;

     //Overridables

          virtual void Serialize (CArchive& ar);

          //Diagnostic Support

          virtual void AssertValid()const;

          virtual void Dump(CDumpContext& dc)const;

     //Implementation

          static const AFX-DATA CRuntimeClass classCObject;

     #ifdef-AFXDLL

          static CRuntimeClass*PASCAL-GetBaseClass();

     #endif

     ;

    為了清楚起見,對這段代碼作了一些細微的改動。但和你在頭檔案AFX.H可以找到的代碼基本一樣。

    檢查CObject的代碼,注意構成這個類定義的成分。首先,CObject被分為公有、保護和私有三個部分。CObject還提供了一般的和動态的類型檢查以及串行化的功能。回憶一下,動态類型檢查使你可以在運作時确定對象的類型。借助于永久性的概念,對象的狀态可以被儲存到存儲媒體中,比如磁盤。對象的永久性使對象成員函數也可以是永久的,允許對象資料的恢複。

    子類從基類繼承而來。例如,CGdiObject是一個從CObject類繼承來的類。這兒是AFXWIN。H中找到的CGdiObject類定義。同樣,為了清楚起見,對其作了一些改動。

     //

     //CGdiObjet abstract class for CDC SelectObject

     class CGdiObject:public CObject

     DECLARE-DYNCREATE(CGdiObject)

          HGDIOBJ m-hObject;//must be first data member

          operator HGDIOBJ()const;

          static CGdiObject*PASCAL FromHandle(HGDIOBJ hObject);

          static void PASCAL Delete TempMap();

          BOOL Attach (HGDIOBJ hObject);

          HGDIOBJ Detach();

     //Constructors

          CGdiobject();//must create a derived class object

          BOOL DeleteObject();

     //Operations

          int GetObject (int nCount,LPVOID 1pObject)const;

          UINT GetObjectType()const;

          BOOL CreateStockObject(int nIndex);

          BOOL UnrealizeObject();

          BOOL operator==(const CGdiObject& obj)const;

          BOOL operator!=(const CGdiObject& obj)const;

          virtual~CGdiObject();

     #ifdef-DEBUG

    CGdiObject和它的成員函數允許在Windows應用程式中建立并使用繪畫對象,如自定義畫筆、刷子和字型等。諸如CPen之類的類是進一步從CGdiObject類繼承而來的。

    Microsoft提供了MFC庫的全部源代碼,以盡可能地增加程式設計的靈活性。但是,對于初學者,沒有必要去了解不同的類是如何定義的。

    例如,在傳統的C語言Windows應用程式中,DeleteObject()函數按下面的文法調用:

     DeleteObject(hBRUSH);/*hBRUSH is the brush handle*/

    在C++中,利用MFC庫,可以按下面的文法通路類成員函數以實作同樣的目的:

     newbrush.DeleteObject();//new brush is current brush

    正如你可以看到的,從C語言Windows函數調用轉向類庫對象是簡單的。Microsoft在開發所有Windows類的時候都使用這種方法,使得從傳統函數調用到繼承類庫對象的轉移非常簡單。

 第二章 windows程式設計基礎

  第一節 引言

 為了跟上潮流,我們抛棄了已快被淘汰的DOS作業系統,所有的講解和例程都是基于微軟的Windows作業系統的。考慮到很多的使用者并沒有Windows程式設計基礎,是以我們設定了這一專門講述、讨論Windows的術語、概念的部分,以使這部分使用者能較快地了解和掌握我們所講述、讨論的程式設計思想和程式設計方法。這一部分中主要講述的是Windows中十分基本的東西,是以使用者應根據自己的情況有選擇的進行學習。好!現在就讓我們進入艱苦而又精彩有趣的遊戲程式設計之路吧! 

  第二節 windows的介紹

       Windows應用程式可以采用面向過程的實作方法。也可以使用面向對象的結構。所有的實作方法都內建了點選控制和彈出菜單,能夠運作特别為Windows編寫的應用程式。

       Windows是一種基于圖形界面的多任務作業系統。為這個環境開發的程式(那些專門為Windows設計的)有着相同的外觀和指令結構。對使用者來說,這使得學習使用Windows應用程式變得容易了。為了幫助開發Windows應用程式,Windows提供了大量的内建函數以友善地使用彈出菜單、滾動條、對話框、圖示和其他一些友好的使用者界面應該具有的特性。

       最值得注意的Windows特性就是其标準化的圖形使用者界面。統一的界面使用圖檔或圖示來代表磁盤驅動器、檔案、子目錄以及其它作業系統的指令和動作。 統一的使用者界面也為程式員帶來了好處。例如,你可以很友善地使用常見菜單和對話框的内建函數。所有的菜單都具有相同風格的鍵盤和滑鼠接口,因為是Windows而不是程式員在實作它。

       Windows的多任務環境允許使用者在同一時刻運作多個應用程式或同一個應用程式的多個執行個體。一個應用程式可能處于激活狀态。激活的應用程式是指它正接收使用者的輸入。因為每一個瞬間僅有一個程式能夠被處理,是以同一時間也隻能有一個應用程式處于激活狀态。但是,可以有任意個數的并行運作的任務。

  第三節 windows的基本概念

  Windows消息和面向對象程式設計

       Windows的可執行檔案格式 

       Windows具有一種新的可執行檔案的格式,稱為New Excutable格式。它包括新型的檔案頭,能夠儲存有關DLL函數的資訊。

  第五節 windows的類

      視窗的基本元件有助于說明應用程式的外觀。有的時候應用程式需要建立兩個外觀和表現都相似的視窗。Windows的Paint就是一個例子。借助于同時運作Paint的兩個執行個體(或拷貝),Paint允許使用者剪貼或拷貝圖檔的一部分。然後資訊就可以從一個執行個體拷貝到另一個執行個體。Paint的每個運作執行個體的外觀和表現都與其他的相同。這就需要每個執行個體建立自己的外觀和功能類似的視窗。

  第六節 windows中的面向對象程式設計

      在Windows下傳統的C程式吸收了一些面向對象程式設計的特性。對象是一種包含資料結構和對這些資料結構進行操作的函數的抽象資料類型。而且,對象接收會引起它們不同動作的消息。

       位圖是一種顯示圖檔(按像素組織),存儲于記憶體。當應用程式需要快速顯示圖檔時可以使用位圖。因為位圖直接從記憶體中傳送,是以它比用程式重新畫出圖檔要快得多。位圖有兩個基本用途。首先,它可以在螢幕上顯示圖檔。其次位圖也用于建立刷子。刷子使你可以在螢幕上畫出并填充對象。

   Windows的消息

       相應消息

       在傳統的面向過程的C語言Windows應用程式中,對于遇到的每一種消息,它都有一個相應的過程來處理這消息。不同的視窗對相同的消息會産生不同的響應。Windows把每個消息發送到應用程式的不同視窗,而不同的視窗對相同的消息會有不同解釋。不令應用程式需要不同的過程來處理每一種消息,每一個視窗也應有不同的過程來處理不同的消息。視窗過程集合了應用程式的所有消息處理過程。

       消息循環

       所有Windows應用程式的一個基本組成就是消息處理循環。每一個C應用程式都在内部執行這個操作。C應用程式包含了建立并初始化視窗的過程,随後是消息處理循環,最後是結束應用程式所需的一些代碼。消息循環負責處理Windows發給主程式的消息。在這兒,程式知道有了消息,并且要求Windows将消息發送到合适的視窗過程以供處理。當消息被接受時,視窗過程就執行希望的動作。

  第八節 windows的函數

  Windows向應用程式開發人員提供了數以百計的函數。這些函數的例子包括DispatchMes-sage(),PostMessage(),RegisterWindowMessage()以及SetActiveWindow()。對于使用基礎類庫的C++程式員,許多函數自動被運作。

  第九節 windows應用程式架構

  Windows頭檔案:WINDOWS.H

       WINWS.H頭檔案(以及其它相關檔案)是所有程式的内在部分。傳統上,WINDOWS.H是所有C語言編寫的Windows應用程式必需的一部分。當在C++中使用基礎類庫時,WINDOWS.H包括在AFXWIN.H頭檔案中。

        Windows應用程式的組成

  在開發Windows應用程式的過程中有一些重要的步驟:

      *建立菜單、對話框和其它資源并把它們放入資源描述檔案。

      *(可選)使用Vinsual C++編譯器中的企業編輯器來建立對話框。

      *用項目檔案來編譯并連結所有的C/C++源程式和資源檔案  

  Windows應用程式中的組成部分

      1. WinMain()函數

       Windows 95和Windows NT需要一個WinMain()函數。這是應用程式開始執行和結束的地方。

      從Windows向WinMain()傳遞四個參數。下面的代碼段示範了這些參數的使用:

      第一個參數hInst包含了應用程式的執行個體句柄。當應用程式在Windows下運作時,這個數字唯一辨別了應用程式。

      第二個參數hPreInst将始終是一個NULL值,表明沒有這個應用程式的其它執行個體正在運作,因為在Windows 95和Windows NT下每個應用程式都在它自己單獨的位址空間中運作。

       第三個參數1pszCmdLine是指向一個以'/0'結尾的字元串的長指針,這個字元串代表了應用程式的指令行參數。

       WinMain()的第四個參數是nCmdShow。在nCmdShow中存儲的整數代表了Windows預定義的許多常量中的一個,它決定了視窗顯示的方式。

       2. WNDCLASS

       WinMain()負責注冊應用程式的主視窗類。每個視窗類都建立在一些使用者選擇的風格、字型、标題字、圖示、大小、位置等的基礎上。視窗類實際上是定義這些屬性的一個模闆。

       hbrBackground:提供了背景刷子的辨別符。

       1pszMenuName:是指向一個以空字元結尾的字元串的指針。這個字元串是菜單的資源名。這一項可以為NULL。

       1pszClassName:是指向一個以空字元結尾的字元串的指針。這個字元串是視窗類的名字。

       3.WNDCLASSEX

       Windows提供了一種擴充的WNDCLASS定義,名為WNDCLASSEX,它允許應用程式使用小圖示。下面是WNDCLASSEX結構的定義:

      typedef struct WNDCLASSEX

      你可以看到這兩個結構是相同的,除了WNDCLASSEX包括了hIconSm成員,這是與視窗類有關的小圖示的句柄。

   4.定義視窗類

     應用程式可以定義它們自己的視窗類,隻要先定義一個合适類型的結構,然後用視窗類的資訊來填充結構的域。

       WNDCLASS結構中的第二個域是wcApp.hInstance,它被賦予了WinMain()被激活後傳回的hInst的值。這指明了應用程式的目前執行個體。1pfnWndProc被賦予執行所有視窗任務的視窗函數的指針位址。對于大部分應用程式,這個函數叫做WndProc()。

       當wcApp.1pszMenuName被賦予NULL值的時候,Windows就認為這個視窗類沒有菜單。如果有,菜單必須有一個名字,它必須出現在引号裡面。GetStockOject()函數傳回一個刷子句柄,用于在這個類建立的視窗使用者區中畫出背景色。

       5.建立視窗

       視窗通過調用CreateWindow()函數來建立。這個過程對所有版本的Windows都是一樣的。視窗類定義了視窗的一般特征,允許同一個視窗類被用于多個不同的視窗,CreateWin-dow()函數的參數指明了關于視窗的更詳細的資訊。

    CreateWindow()函數的參數資訊包括以下内容:視窗類、視窗标題、視窗風格、螢幕位置、視窗的父句柄、菜單句柄、執行個體句柄以及32位的附加資訊。在大部分應用程式中 ,這個函數會是下面這個樣子:

繼續閱讀