同其他的程式設計語言教材一樣,Charles Petzold同樣選擇了使用“Hello World”作為這部堪稱經典的《Windows程式設計》的第一個Windows程式範例。
我把它稱為永恒的“Hello World”。
在開始學習如何編寫Windows應用程式之前,我們有必要先瞭解一下Windows工作原理的中心思想——動態連結。
1.動態連結
Windows工作原理的中心思想是動態連結。
何為動態連結呢?
Windows自身帶有一大套函數,應用程式就是通過調用這些函數來實現它的使用者介面和在螢幕上顯示文本與圖形的。這種調用並不會像C語言庫函數的機器碼一樣將這些函數代碼直接連結到你的應用程式代碼中,而是通過調用動態連結程式庫來實現的。
Windows內建的這一大套函數都是在動態連結程式庫裡實現的。這些動態連結程式庫檔案的名稱都帶有尾碼.dll或.exe。
那麼動態連結是如何?的呢?
當Windows應用程式運行時,它通過一個叫做“動態連結”(dynamic linking)的進程與Windows應用程式進行互動,每個Windows的exe檔案包含它所要用的各個動態連結程式庫以及庫中的函數的引用地址。當一個Windows應用程式被裝入記憶體之後,程式中的函數調用都被解析成dll函數入口指標,同時這些被調用的函數也會被裝入記憶體。
使用編譯環境編譯Windows程式時又是怎樣的呢?
當編譯Windows程式以產生執行檔案時,需要連結編譯環境所提供的特殊的“匯入庫”,這些匯入庫包含所有Windows函數調用所碰到的動態連結程式庫的名字以及引用資訊。編譯Windows程式時則需要用到這些資訊來構建exe檔案中的表格。當裝入程式時,Windows則可以靠這些表格來解析Windows函數調用了。
2.解析Hello World
在我們建立的源檔案“helloworld_msgBox.c”中輸入如下原始碼:
View Code
1 #include <windows.h> 2 3 int WINAPI WinMain (HINSTANCE hInstance, 4 HINSTANCE hPrevInstance, 5 LPSTR lpCmdLine, 6 int nShowCmd) 7 { 8 MessageBox(NULL, TEXT("Hello,World!"), TEXT("helloworld_msgBox"), MB_OK); 9 return 0;10 }
運行之後的效果,1所示。
圖1 helloworld
下面從標頭檔、程式入口、MessageBox三個方面來簡單分析一下這段原始碼。
2.1標頭檔
對於Windows應用程式來說,windows.h是一個極為重要的標頭檔,因為它囊括了若干其他Windows標頭檔。
常用的幾個標頭檔如下:
windef.h 基礎資料型別 (Elementary Data Type)定義
winnt.h 支援Unicode的類型定義
winbase.h 核心功能
winuser.h 使用者介面函數
wingdi.h 圖形裝置介面函數
這些標頭檔定義了Windows的所有資料類型、函數調用、資料結構以及常量標識符。
2.2程式入口
Windows程式的入口是WinMain。該函數原型為:
1 int WINAPI WinMain (HINSTANCE hInstance, 2 HINSTANCE hPrevInstance, 3 LPSTR lpCmdLine, 4 int nShowCmd)
其中,第一個參數hInstance是指程式的執行個體控制代碼,用來唯一的標識當前啟動並執行程式。而第二個參數則用來判斷是否有其他的執行個體正在運行(在32位Windows中,這一參數通常定義為NULL)。第三個參數lpCmdLine是用來運行程式的命令列(LPSTR表示指向字串的長指標)。第四個參數nShowCmd用來指明程式最初應該如何顯示(正常顯示、最大化到全屏、最小化顯示在工作列等)。
2.3MessageBox函數
MessageBox函數是用來顯示簡訊息的。該函數原型為:
1 int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
其中,第一個參數hWnd通常是一個視窗控制代碼。第二個參數lpText是指要顯示在資訊框中的文言資訊。第三個參數lpCaption是指要顯示在資訊框的標題列的文言資訊(即資訊框的標題)。第四個參數則用來設定資訊框中的按鈕類型。
2.3.1按鈕式樣
在標頭檔winuser.h中定義一些按鈕的類型,如下:
1 /* 2 * MessageBox() Flags 3 */ 4 #define MB_OK 0x00000000L 5 #define MB_OKCANCEL 0x00000001L 6 #define MB_ABORTRETRYIGNORE 0x00000002L 7 #define MB_YESNOCANCEL 0x00000003L 8 #define MB_YESNO 0x00000004L 9 #define MB_RETRYCANCEL 0x00000005L10 #if(WINVER >= 0x0500)11 #define MB_CANCELTRYCONTINUE 0x00000006L12 #endif /* WINVER >= 0x0500 */
其式樣2所示。
圖2 按鈕式樣
2.3.2預設按鈕
同樣在標頭檔winuser.h中定義下列一些宏定義,通過使用按位或運算(|),可以把一個上述按鈕式樣與下列宏定義組合起來,來描述哪一個按鈕是預設按鈕。
1 #define MB_DEFBUTTON1 0x00000000L2 #define MB_DEFBUTTON2 0x00000100L3 #define MB_DEFBUTTON3 0x00000200L4 #if(WINVER >= 0x0400)5 #define MB_DEFBUTTON4 0x00000300L6 #endif /* WINVER >= 0x0400 */
比如,當我們使用按鈕式樣MB_OKCANCEL時,其有“確定”和“取消”兩個按鈕。在預設情況下,預設按鈕為“確定”。如果我們想改變其預設按鈕為“取消”,這時候就可以使用MB_OKCANCEL與MB_DEFBUTTON2的組合來實現。
修改後的代碼如下所示:
View Code
1 #include <windows.h> 2 3 int WINAPI WinMain (HINSTANCE hInstance, 4 HINSTANCE hPrevInstance, 5 LPSTR lpCmdLine, 6 int nShowCmd) 7 { 8 MessageBox(NULL, TEXT("Hello,World!"), TEXT("helloworld_msgBox"), MB_OKCANCEL | MB_DEFBUTTON2); 9 return 0;10 }
2.3.3資訊框中顯示的表徵圖
如果想在資訊框中顯示一些表徵圖,可以通過使用以下一些宏定義來實現。這些宏定義同樣在標頭檔winuser.h中,如下:
1 #define MB_ICONHAND 0x00000010L2 #define MB_ICONQUESTION 0x00000020L3 #define MB_ICONEXCLAMATION 0x00000030L4 #define MB_ICONASTERISK 0x00000040L
這四個宏定義同樣可以通過與按鈕式樣做按位或運算(|)來使用。
這四種表徵圖的式樣3所示。
圖3 表徵圖式樣
2.3.4其他式樣
在標頭檔winuser.h中還有一些關於資訊框顯示的宏定義,比如增加一個“協助”按鈕等。
1 #define MB_APPLMODAL 0x00000000L 2 #define MB_SYSTEMMODAL 0x00001000L 3 #define MB_TASKMODAL 0x00002000L 4 #if(WINVER >= 0x0400) 5 #define MB_HELP 0x00004000L // Help Button 6 #endif /* WINVER >= 0x0400 */ 7 8 #define MB_NOFOCUS 0x00008000L 9 #define MB_SETFOREGROUND 0x00010000L10 #define MB_DEFAULT_DESKTOP_ONLY 0x00020000L11 12 #if(WINVER >= 0x0400)13 #define MB_TOPMOST 0x00040000L14 #define MB_RIGHT 0x00080000L15 #define MB_RTLREADING 0x00100000L16 #endif /* WINVER >= 0x0400 */
相關部落格:
我的第一個Windows程式 http://www.cnblogs.com/mr-wid/archive/2012/10/06/2713249.html