Windows 编码约定
如果你不熟悉 Windows 编程,当你第一次看到 Windows 程序时,它可能会令人不安。 代码用奇怪的类型定义(如 DWORD_PTR 和 LPRECT)填充,变量的名称如 hWnd 和 pwsz (称为匈牙利表示法) 。 值得花点时间了解一些 Windows 编码约定。
绝大多数 Windows API 由函数或组件对象模型 (COM) 接口组成。 很少有 Windows API 作为 C++ 类提供。 (一个值得注意的例外是 GDI+,GDI+是二维图形 API 之一)
Typedef
Windows 标头包含大量 typedef。 其中许多是在头文件 WinDef.h 中定义的。 下面是你将经常遇到的一些内容。
整数类型
数据类型 | 大小 | 签署? |
---|---|---|
BYTE | 8 位 | 无符号 |
DWORD | 32 位 | 无符号 |
INT32 | 32 位 | 有符号 |
INT64 | 64 位 | 有符号 |
LONG | 32 位 | 有符号 |
LONGLONG | 64 位 | 有符号 |
UINT32 | 32 位 | 无符号 |
UINT64 | 64 位 | 无符号 |
ULONG | 32 位 | 无符号 |
ULONGLONG | 64 位 | 无符号 |
WORD | 16 位 | 无符号 |
如你所看到的,这些 typedef 中有一定数量的冗余。 其中一些重叠只是由于 Windows API 的历史记录。 此处列出的类型具有固定大小,32 位和 64 应用程序的大小相同。 例如, DWORD 类型始终为 32 位宽。
布尔类型
BOOL 是 int 的类型别名,不同于 C++ 的 bool,也不同于表示 布尔 值的其他类型。 头文件 WinDef.h
还定义用于 BOOL 的两个值。
#define FALSE 0
#define TRUE 1
但是,尽管定义 为 TRUE,但大多数返回 BOOL 类型的函数都可以返回任何非零值来指示布尔值。 因此,应始终编写:
// Right way.
if (SomeFunctionThatReturnsBoolean())
{
...
}
// or
if (SomeFunctionThatReturnsBoolean() != FALSE)
{
...
}
而不是以下:
if (result == TRUE) // Wrong!
{
...
}
BOOL 是整数类型,不能与 C++ 的 bool 互换。
指针类型
Windows 定义指向 X 的表单 指针的许多数据类型。 名称中通常具有 前缀 P- 或 LP- 。 例如, LPRECT 是指向 RECT 的指针,其中 RECT 是描述矩形的结构。 以下变量声明是等效的。
RECT* rect; // Pointer to a RECT structure.
LPRECT rect; // The same
PRECT rect; // Also the same.
在 16 位体系结构 (16 位 Windows) 有 2 种类型的指针, P 表示“指针”, LP 代表“长指针”。 长指针 (也称为 远指针 ,) 用于处理当前段以外的内存范围。 LP 前缀已保留,以便更轻松地将 16 位代码移植到 32 位 Windows。 今天没有区别,这些指针类型都是等效的。 避免使用这些前缀;或者,如果必须使用一个,则使用 P。
指针精度类型
以下数据类型始终是指针的大小,即 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 位的位置。
匈牙利表示法
匈牙利语表示法 是向变量名称添加前缀以提供有关变量的其他信息的做法。 (符号的发明者查尔斯·西蒙尼是匈牙利人,因此它的名字) 。
匈牙利表示法在其原始形式中提供有关变量的 语义 信息,告知你预期用途。 例如, i 表示索引, cb 表示字节大小 (“字节计数”) , 以及 rw 和 col 平均行和列数。 这些前缀旨在避免在错误上下文中意外使用变量。 例如,如果看到表达式 rwPosition + cbTable
,就会知道正在向大小添加行号,这几乎可以肯定是代码中的 bug
匈牙利语表示法的更常见形式使用前缀来提供 类型 信息,例如, dw 表示 DWORD , w 表示 WORD。
注意
C++ 核心准则禁止使用前缀表示法 (例如匈牙利表示法) 。 请参阅 NL.5:避免在名称中编码类型信息。 在内部,Windows 团队不再使用它。 但它的用法仍保留在示例和文档中。