如果你刚刚接触 Windows 编程开发,有些很多东西会让人看起来莫名其妙。在很多代码中充斥着奇怪的类型标识,类似 DWORD_PTR 或者 LPRECT 等等,并且大多数的变量名的定义都是按照匈牙利的命名规范定制的,例如 hWnd 或者 pwsz 等等,你可能需要花费一些时间来熟悉这些东西。

绝大多数的 Windows API 都是以普通函数或者 组件对象模型 (COM) 接口的形式提供的,少数的接口以 C++ 类的形式提供(如:GDI+)。

1. 类型列表

Windows 头文件中包含了很多独特的类型定义,大多数的定义都在 WinDef.h 文件中,下面是常用的类型列表:

数据类型 大小 有符号?
BYTE 8 bits Unsigned
DWORD 32 bits Unsigned
INT32 32 bits Signed
INT64 64 bits Signed
LONG 32 bits Signed
LONGLONG 64 bits Signed
UINT32 32 bits Unsigned
UINT64 64 bits Unsigned
ULONG 32 bits Unsigned
ULONGLONG 64 bits Unsigned
WORD 16 bits Unsigned

如上表所示,为了兼容一些历史的程序,所以列表中的类型存在一定的冗余。这些类型在32位和64位程序中的大小都是固定的。例如:DWORD 类型在32位和64位程序中都是32位大小。

2. Boolean 类型

在 Windows 编程中存在一种 BOOL 类型。该类型是整形的别名,并不是 C++ 中的 bool 类型。

WinDef.h 头文件中,定义两个 BOOL 类型的值:

#define FALSE    0
#define TRUE     1

如果有函数返回一个 BOOL 类型,其真实的结果可能返回的是一个非0值,所以下面这种方式判断是错误的:

// Wrong!
if (result == TRUE)
{
    ...
}

应该使用如下代码:

// Right way.
BOOL result = SomeFunctionThatReturnsBoolean();
if (result)
{
    ...
}

BOOL 类型并不等价于C++中的 bool 类型!

3. 指针类型

Windows 定义了很多指针类型,通常都是以 P- 或者 LP- 开始的类型名称。如:LPRECT 代表指向 RECT 类型的指针。

RECT 类型代表一个矩形结构体, 下面几种定义方式是等价的:

RECT*  rect;  // Pointer to a RECT structure.
LPRECT rect;  // The same
PRECT  rect;  // Also the same.

历史上,P 前缀的指针叫 pointer ,LP 前缀的指针叫 long pointer。二者是16位操作系统向32位操作系统过渡时期遗留的产物,如今二者已经没有区别了。

虽然如今已经不分“长短”了,但是依然会出现一个兼容问题,特别是在程序逻辑中存在指针和整形的转化关系的时候。为了解决这个问题,Windows 定义了几种明确的指针类型:

  • DWORD_PTR
  • INT_PTR
  • LONG_PTR
  • ULONG_PTR
  • UINT_PTR

如果在程序逻辑上存在32位值扩展到64位值的情况,请使用上述类型。

4. 匈牙利标记法

匈牙利标记法这是为了纪念具有传奇色彩的微软程序员 Charles Simonyi。这种标记法非常简单,即变量名表明该变量数据类型的小写字母开始。例如,szCmdLine 的前缀 sz 表示“以零结束的字符串”。

  • p 指针
  • h 句柄
  • sz 字符串
  • b BYTE
  • ul ULOGN
  • l LONG
  • i INT
  • ui UINT
  • ch CHAR
  • dw DWORD
  • hr HRESULT