英文原版地址:https://docs.microsoft.com/zh-cn/windows/win32/learnwin32/windows-coding-conventions
如果您是Windows编程的新手,当您第一次看到Windows程序时,可能会感到不安。代码中充满了奇怪的类型定义,如DWORD_PTR和LPRECT,变量的名称如hWnd和pwsz(称为匈牙利符号)。花点时间学习一些Windows编码约定是值得的。
绝大多数的Windows api由函数或组件对象模型(COM)接口组成。很少有Windows api是作为c++类提供的。(一个值得注意的例外是GDI+,它是一个2d图形api。)
Typedefs(类型定义)
Windows头文件包含很多类型定义。其中许多都是在头文件WinDef.h中定义的。以下是一些你会经常遇到的问题。
Integer types(整型)
如您所见,这些类型定义中有一定数量的冗余。部分重叠是由于Windows api的历史。这里列出的类型具有固定的大小,32位和64位应用程序的大小都是相同的。例如,DWORD类型总是32位宽。
Boolean Type(布尔类型)
BOOL是一个用于布尔型上下文中的整数值的类型定义。头文件WinDef.h也定义了两个与BOOL一起使用的值。
#define FALSE 0
#define TRUE 1
尽管定义了TRUE,但是大多数返回BOOL类型的函数都可以返回任何非零值来表示布尔值。因此,你应该总是这样写:
// Right way.
BOOL result = SomeFunctionThatReturnsBoolean();
if (result)
{
...
}
而不是:
// Wrong!
if (result == TRUE)
{
...
}
注意BOOL是整数类型,不能与c++的BOOL类型互换。
Pointer Types(指针类型)
Windows定义了许多形式的指针-X的数据类型。这些名字通常有前缀P-或LP-。例如,LPRECT是一个指向矩形的指针,而RECT是一个描述矩形的结构体。下面的变量声明是等价的。
RECT* rect; //指向矩形结构体的指针
LPRECT rect; // 同上面一样
PRECT rect; // 也同上面一样
在历史上,P代表“pointer”,LP代表“long pointer”。long pointer(也称为远指针)是16位窗口遗留下来的,当需要它们来寻址当前段以外的内存范围时。LP前缀被保留是为了更容易地将16位代码移植到32位窗口。今天已经没有区别了——指针就是指针。
Pointer Precision Types(精确指针类型)
以下数据类型永远是指针的大小,即32位应用程序为32位,64位应用程序为64位。大小在编译时确定。当32位应用程序运行在64位Windows上时,这些数据类型仍然是4字节宽的。(64位的应用程序不能在32位的Windows上运行,所以相反的情况不会发生。)
DWORD_PTR
INT_PTR
LONG_PTR
ULONG_PTR
UINT_PTR
这些类型用于可能将整数转换为指针的情况。它们还用于定义指针算术的变量,以及定义遍历内存缓冲区中所有字节范围的循环计数器。更普遍的情况是,在64位Windows上,它们出现在将现有的32位值扩展为64位的地方。
匈牙利命名法(Hungarian Notation)
匈牙利式表示法是在变量名中添加前缀的做法,以提供关于变量的附加信息。(这种符号的发明者查尔斯·西蒙尼是匈牙利人,因此得名)。
在其原始形式中,匈牙利符号提供了关于变量的语义信息,告诉您预期的用途。例如,i表示索引,cb表示字节大小(“字节数”),rw和col表示行和列号。设计这些前缀是为了避免在错误的上下文中意外地使用变量。例如,如果您看到表达式rwPosition + cbTable,您将知道一个行号被添加到一个大小,这几乎肯定是代码中的一个错误
匈牙利符号更常见的形式是使用前缀来提供类型信息,例如,dw表示DWORD, w表示WORD。
如果你在网上搜索“匈牙利符号”,你会找到很多关于匈牙利符号是好是坏的意见。有些程序员非常不喜欢匈牙利符号。其他人则认为它很有帮助。无论如何,许多MSDN上的代码示例都使用匈牙利符号,但是您不需要记住前缀就可以理解代码。