如果你是编写windows程序的新手,当你第一次看到windows程序源码时,它会令人感到不安。这些代码充满了奇怪的定义,如 DWORD,LPRECT等等;以及变量的名称,如 “hWnd”,“pwsz”(匈牙利表示法)。值得花点时间来了解一些windows编程的编码约定。
绝大多数的Windows API 是由 函数或者组件对象模型(COM)接口组成。很少的Windows API 是提供C++ 类的(有一个显著的例外是GDI+中,一个2D图形API)。
Windows头文件包含大量的类型定义,大多是在WinDef.h中定义的。这里是经常会遇到的一些类型定义。
Integer(整数)类型
数据类型 |
数据大小 |
有无正负符号 |
BYTE |
8位二进制 |
Unsigned无符号 |
DWORD |
32位二进制 |
Unsigned无符号 |
INT32 |
32位二进制 |
Signed有符号 |
INT64 |
64位二进制 |
Signed有符号 |
LONG |
32位二进制 |
Signed有符号 |
LONGLONG |
64位二进制 |
Signed有符号 |
UINT32 |
32位二进制 |
Unsigned无符号 |
UINT64 |
64位二进制 |
Unsigned无符号 |
ULONG |
32位二进制 |
Unsigned无符号 |
ULONGLONG |
64位二进制 |
Unsigned无符号 |
WORD |
16位二进制 |
Unsigned无符号 |
正如你所看到的,这些数据类型定义有一定的冗余,这些重叠的部分是因为兼顾旧版Windows API 。这里列出的类型都有固定的大小,并且在这些类型的大小在32位和64位应用程序中都是相同的。例如:DWORD类型,在32位或64位应用程序中始终是32位宽。
Boolean 类型(布尔)
BOOL 是一个整数值,用于在布尔上下文的类型定义,头文件WinDef.h还定义了两个值与BOOL一起使用:
#define FALSE 0
#define TRUE 1
尽管这一定义为 TRUE,然而,大多数返回BOOL值的函数是可以返回任何非零值来表示布尔真值。因此,布尔类型的应用应该这样写:
//正确的写法
BOOL result=SomeFunctionThatReturnsBoolean();
If (result)
{
...
}
并且不应该这样:
//错误的写法
If (result == TRUE)
{
...
}
请注意 BOOL 是一个整数类型,与C++的bool类型是不可互换的。
Pointer类型(指针)
Windows定义了许多形式如 Pointer-to-X的数据类型,这些数据类型通常以P或LP作为名称的前缀,例如:LPRECT是一个指向RECT的指针,RECT是一个描述矩形的结构。以下的变量声明是等效的:
RECT* rect; //指向RECT结构的指针
LPRECT rect; //同上
PRECT rect; //一样同上
从历史来讲,P代表指针,LP代表长指针;长指针(也称为远指针)是16位Windows的延续,当需要当前段的内存地址范围之外。这个LP前缀被保留了下来,以使其更易于16位代码连接在32位Windows。如今已没有区别,一个指针就是一个指针而已。
Pointer Precision类型(指针精度)
下面的数据类型都是指针的大小——确切的说,在32位应用程序是32位宽,64位应用程序是64位宽。大小是在编译是确定的。当一个32位程序运行在64位Windows上,这些数据类型仍然是4个字节宽(一个64位程序无法在32位Windows上运行,所以不会发生相反的情况)。
l DWORD_PTR
l INT_PTR
l LONG_PTR
l ULONG_PTR
l UINT_PTR
在使用这些类型情况下,一个整数可能会转换为指针。它们还用来定义指针算法的变量,和定义循环计数器全方位的遍历这内存缓冲区中的字节。更普遍的,它们出现的地方,在64位Windows上,现有的32位值扩展到64位。
匈牙利表示法
匈牙利表示法的做法是将前缀添加到变量名,给变量附加信息(这个表示法的发明者查尔斯-西蒙是匈牙利人,故以此命名)。
在它最初的形式,匈牙利表示法赋予一个变量语义信息,告诉你预期的用途。例如,i的语义是索引,cb的语义是以字节为单位的大小(字节的计数),以及rw和col语义是行和列的数。这些前缀的目的在于避免意外使用在错误上下文的一个变量。例如,你看到一个表达式rwPointer + cbTable 你就会知道一个行号加到一个大小,几乎可以肯定这是代码中的bug。
更常见的匈牙利表示法形式是使用前缀来给类型信息。例如,dw表示DWORD,w表示WORD。
如果你在网络上搜索匈牙利表示法,你将会发现很多有关匈牙利表示法是好还是坏的意见,一些程序员强烈的反感匈牙利表示法,其他人发现很好用。不论如何,许多人在MSDN上的代码示例是使用匈牙利表示法。但你不需要记住前缀理解代码。