Windows编码约定
如果你不熟悉Windows编程,则当你第一次看到Windows程序时,它可能会令人不安。 代码充满了奇怪的类型定义 ,如 DWORD_PTR 和 LPRECT,变量的名称如 hWnd 和 pwsz (称为匈牙利表示法) 。 需要一些时间了解一些Windows编码约定。
绝大多数Windows API 由函数或组件对象模型 (COM) 接口组成。 很少Windows API 作为 C++ 类提供。 (一个值得注意的异常是GDI+,这是二维图形 API 之一。)
Typedef
Windows标头包含大量 typedefs。 其中许多是在头文件 WinDef.h 中定义的。 以下是经常遇到的一些操作。
整数类型
数据类型 | 大小 | 签署? |
---|---|---|
BYTE | 8 位 | 无符号 |
DWORD | 32 位 | 无符号 |
INT32 | 32 位 | 有符号 |
INT64 | 64 位 | 有符号 |
LONG | 32 位 | 有符号 |
LONGLONG | 64 位 | 有符号 |
UINT32 | 32 位 | 无符号 |
UINT64 | 64 位 | 无符号 |
ULONG | 32 位 | 无符号 |
ULONGLONG | 64 位 | 无符号 |
WORD | 16 位 | 无符号 |
正如你所看到的,这些 typedefs 中有一定数量的冗余。 其中一些重叠只是由于Windows API 的历史。 此处列出的类型具有固定大小,并且大小在 32 位和 64 应用程序中相同。 例如, DWORD 类型始终宽 32 位。
布尔类型
BOOL 是 int 的类型别名,不同于 C++ 的 布尔值,与表示 布尔 值的其他类型不同。 头文件 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
这些类型在整数可能强制转换为指针的情况下使用。 它们还用于定义指针算术的变量,并定义循环计数器,循环访问内存缓冲区中整个字节范围。 更通常,它们出现在现有 32 位值在 64 位Windows上扩展到 64 位的位置。
匈牙利表示法
匈牙利表示法 是向变量名称添加前缀的做法,用于提供有关变量的其他信息。 (表示法的发明家查尔斯·西蒙伊是匈牙利人,因此它的名字) 。
在原始形式中,匈牙利表示法提供有关变量 的语义 信息,告知预期用途。 例如, i 表示索引, cb 表示字节大小 (“字节计数”) , rw 和 col 平均值行和列号。 这些前缀旨在避免在错误的上下文中意外使用变量。 例如,如果看到表达式 rwPosition + cbTable
,你会知道正在向大小添加行号,这几乎肯定是代码中的 bug
更常见的匈牙利表示法形式使用前缀来提供类型信息,例如,DWORD的 dw和WORD 的 dw。
注意
C++ 核心准则禁止前缀表示法 (,例如匈牙利表示法) 。 请参阅 NL.5:避免在名称中编码类型信息。 在内部,Windows团队不再使用它。 但它的使用仍保留在示例和文档中。