大写字母标识符
读者可能注意到,HELLOWIN.C中有几个大写的标识符,这些标识符是在Windows表头文件中定义的。有些标识符含有两个字母或者三个字母的前缀,这些前缀后头接着一个底线:
这些是简单的数值常数。前缀指示该常数所属的类别,如表3-1所示。
表3-1 |
前缀 | 类别 |
CS | 窗口类别样式 |
CW | 建立窗口 |
DT | 绘制文字 |
IDI | 图示ID |
IDC | 游标ID |
MB | 消息框 |
SND | 声音 |
WM | 窗口消息 |
WS | 窗口样式 |
奉劝程序写作者不要费力气去记忆Windows程序设计中的数值常数。实际上,Windows中使用的每个数值常数在表头文件中均有相应的标识符定义。
新的数据型态
HELLOWIN.C中的其它标识符是新的数据型态,也在Windows表头文件中使用typedef叙述或者#define叙述加以定义了。最初是为了便于将Windows程序从原来的16位系统上移植到未来的使用32位(或者其它)技术的操作系统上。这种作法并不如当时每个人想象的那样顺利,但是这种概念基本上是正确的。
有时这些新的数据型态只是为了方便缩写。例如,用于WndProc的第二个参数的UINT数据型态只是一个unsigned int (无正负号整数),在Windows 98中,这是一个32位的值。用于WinMain的第三个参数的PSTR数据型态是指向一个字符串的指针,即是一个char *。
其它数据型态的含义不太明显。例如,WndProc的第三和第四个参数分别被定义为WPARAM和LPARAM,这些名字的来源有点历史背景:当Windows还是16位系统时,WndProc的第三个参数被定义为一个WORD,这是一个16位的 无正负号短(unsigned short)整数,而第四个参数被定义为一个LONG,这是一个32位有正负号长整数,从而导致了文字「PARAM」前面加上了前置前缀「W」和「L」。当然,在32位的Windows中,WPARAM被定义为一个UINT,而LPARAM被定义为一个LONG(这就是C中的long整数型态),因此窗口消息处理程序的这两个参数都是32位的值。这也许有点奇怪,因为WORD数据型态在Windows98中仍然被定义为一种16位的 无正负号整数,因此「PARAM」前的「W」就有点误用了。
WndProc函数传回一个型态为LRESULT的值,该值简单地被定义为一个LONG。WinMain函数被指定了一个WINAPI型态(在表头文件中定义的所有Windows函数都被指定这种型态),而WndProc函数被指定一个CALLBACK型态。这两个标识符都被定义为_stdcall,表示在Windows本身和使用者的应用程序之间发生的函数呼叫的呼叫参数传递方式。
HELLOWIN还使用了Windows表头文件中定义的四种数据结构(我们将在本章稍后加以讨论)。这些数据结构如表3-2所示。
表3-2 |
结构 | 含义 |
MSG | 消息结构 |
WNDCLASS | 窗口类别结构 |
PAINTSTRUCT | 绘图结构 |
RECT | 矩形结构 |
前面两个数据结构在WinMain中使用,分别定义了两个名为msg和wndclass的结构,后面两个数据结构在WndProc中使用,分别定义了ps和rect结构。
句柄简介
最后,还有三个大写标识符(见表3-3),用于不同型态的「句柄」:
表3-3 |
标识符 | 含义 |
HINSTANCE | 执行实体(程序自身)句柄 |
HWND | 窗口句柄 |
HDC | 设备内容句柄 |
句柄在Windows中使用非常频繁。在本章结束之前,我们将遇到HICON(图标句柄)、HCURSOR(鼠标光标句柄)和HBRUSH(画刷句柄)。
句柄是一个(通常为32位的)整数,它代表一个对象。Windows中的句柄类似传统C或者MS-DOS程序设计中使用的文件句柄。程序几乎总是通过呼叫Windows函数取得句柄。程序在其它Windows函数中使用这个句柄,以使用它代表的对象。代号的实际值对程序来说是无关紧要的。但是,向您的程序提供代号的Windows模块知道如何利用它来使用相对应的对象。
匈牙利表示法
读者可能注意到,HELLOWIN.C中有一些变量的名字显得很古怪。如szCmdLine,它是传递给WinMain的参数。
许多Windows程序写作者使用一种叫做「匈牙利表示法」的变量命名通则。这是为了纪念传奇性的Microsoft程序写作者Charles Simonyi。非常简单,变量名以一个或者多个小写字母开始,这些字母表示变量的数据型态。例如,szCmdLine中的sz代表「以0结尾的字符串」。在hInstance和hPrevInstance中的h前缀表示「句柄」;在iCmdShow中的i前缀表示「整数」。WndProc的后两个参数也使用匈牙利表示法。正如我在前面已经解释过的,尽管wParam应该更适当地被命名为uiParam(代表「无正负号整数」),但是因为这两个参数是使用数据型态WPARAM和LPARAM定义的,因此保留它们传统的名字。
在命名结构变量时,可以用结构名(或者结构名的一种缩写)的小写作为变量名的前缀,或者用作整个变量名。例如,在HELLOWIN. C的WinMain函数中,msg变量是MSG型态的结构;wndclass是WNDCLASSEX型态的一个结构。在WndPmc函数中,ps是一个PAINTSTRUCT结构,rect是一个RECT结构。
匈牙利表示法能够帮助程序写作者及早发现并避免程序中的错误。由于变量名既描述了变量的作用,又描述了其数据型态,就比较容易避免产生数据型态不合的错误。
表3-4列出了在本书中经常用到的变量前缀。
表3-4 |
前缀 | 数据型态 |
c | char或WCHAR或TCHAR |
by | BYTE (无正负号字符) |
n | short |
i | int |
x, y | int分别用作x坐标和y坐标 |
cx, cy | int分别用作x长度和y长度;C代表「计数器」 |
b或f | BOOL (int);f代表「旗标」 |
w | WORD (无正负号短整数) |
l | LONG (长整数) |
dw | DWORD (无正负号长整数) |
fn | function(函数) |
s | string(字符串) |
sz | 以字节值0结尾的字符串 |
h | 句柄 |
p | 指标 |