第一个windows窗口程序
窗口版的hello world
//HelloMsg.c #include<Windows.h> int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) { MessageBox(NULL,TEXT(hello,Windows!),TEXT(HelloMsg),0); return 0; }
分析
头文件
类似命令行的#include<stdio.h>
,不过更像C++的#include<iostream>
,包含了其他许多的头文件。窗口版也包含了一个头文件,它包含了其他Windows表头文件
其中:
- windef.h:基本类型定义
- winnt.h:支持Unicode的类型定义(但是我在里面并没有找到)
- winbase.h:Kernel函数。定义了32位Windows的基本APIs
- winuser.h:USER接口函数。用户过程声明,常量定义和宏。
- wingdi.h : 图形设备接口函数。GDI过程声明,常量定义和宏
程序进入点
正如在C程序中的进入点是函数main一样,Windows程序的进入点是WinMain,总是像这样出现:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
由操作系统为WinMain传入参数
在winbase.h中WinMain的声明如下:
WinMain ( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd );
_In_表示为输入参数,_In_opt_表示可选输入参数,指示参数可能为NULL,参见批注函数参数和返回值
WinMain的声明与HelloMsg.c中的第三个参数稍有不同,LP前缀表示长指针,是16位Windows下的产物。HelloMsg.c中还改变了两个变量的名称,Windows程序变量名使用【匈牙利表示法】命名变量,i表示整数,sz表示以0结尾的字符串
WINAPI标识符定义在minwindef.h中(书上写定义在windef.h中,时间太长Windows某些东西变了?)语句如下:
#define WINAPI __stdcall
__stdcall表示由被调用方清理堆栈,参数从右向左传递。参见参数传递和命名约定
WinMain的第一个参数被称为执行实体句柄,在Windows中句柄指唯一标识某些东西的数字。
在Windows的早期版本中,当同时运行同一程序多次时,您便创建了该程序的「多个执行实体(multiple instances)」。同一应用程序的所有执行实体共享程序和只读的内存(通常是例如菜单和对话框模板的资源)。程序通过检查hPrevInstance参数就能够确定自身的其它执行实体是否正在运行。然后它可以略过一些繁杂的工作并从前面的执行实体将某些数据移到自己的数据区域。在32位Windows版本中,该概念已被抛弃。传给WinMain的第二个参数总是NULL(定义为0)。
WinMain的第三个参数是用于执行程序的命令列。某些Windows应用程序利用它在程序启动时将文件加载内存。
WinMain的第四个参数指出程序最初显示的方式,可以是正常的或者是最大化地充满整个画面,或者是最小化显示在工作列中。
MessageBox函数
MessageBox函数用于显示短信息。虽然,MessageBox显示的小窗口不具有什么功能,实际上它被认为是一个对话框。
MessageBox的第一个参数通常是窗口句柄(将在后面介绍,可能是附加在指定的窗口上?)
第二个参数是在消息框主体中显示的字符串。
第三个参数是出现在消息框标题列上的字符串。TEXT()是一个宏,作用是将字母'L'添加到字符串前,变成LHelloMsg,转换成Unicode字符串,每个字符占用两个字节
第四个参数控制消息框的按钮类型。见Win APIs