Windows程序设计02:永恒的Hello World

  同其他的编程语言教材一样,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      基本数据类型定义

  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              0x00000005L
10 #if(WINVER >= 0x0500)
11 #define MB_CANCELTRYCONTINUE        0x00000006L
12 #endif /* WINVER >= 0x0500 */

  其式样如图2所示。

图2 按钮式样

2.3.2默认按钮

  同样在头文件winuser.h中定义下列一些宏定义,通过使用按位或运算(|),可以把一个上述按钮式样与下列宏定义组合起来,来描述哪一个按钮是默认按钮。

1 #define MB_DEFBUTTON1               0x00000000L
2 #define MB_DEFBUTTON2               0x00000100L
3 #define MB_DEFBUTTON3               0x00000200L
4 #if(WINVER >= 0x0400)
5 #define MB_DEFBUTTON4               0x00000300L
6 #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                 0x00000010L
2 #define MB_ICONQUESTION             0x00000020L
3 #define MB_ICONEXCLAMATION          0x00000030L
4 #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            0x00010000L
10 #define MB_DEFAULT_DESKTOP_ONLY     0x00020000L
11 
12 #if(WINVER >= 0x0400)
13 #define MB_TOPMOST                  0x00040000L
14 #define MB_RIGHT                    0x00080000L
15 #define MB_RTLREADING               0x00100000L
16 #endif /* WINVER >= 0x0400 */

 

 

相关博客:

我的第一个Windows程序 http://www.cnblogs.com/mr-wid/archive/2012/10/06/2713249.html

 

posted @ 2013-01-23 22:16  依旧淡然  阅读(1145)  评论(1编辑  收藏  举报