Windows开发中,经常会碰到一个常见的字眼HWND,如下 ```c++ HWND hWnd; hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); ``` HWND就是句柄,首先来看看句柄的定义。 ```c++ DECLARE_HANDLE (HWND); DECLARE_HANDLE (HHOOK); ``` 再往下看接续查找DECLARE_HANDLE的定义,如下 ```c++ #ifdef STRICT //编译级别的选项开关 typedef void *HANDLE; // void* #if 0 && (_MSC_VER > 1000) #define DECLARE_HANDLE(name) struct name##__; typedef struct name##__ *name #else #define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name #endif #else typedef PVOID HANDLE; #define DECLARE_HANDLE(name) typedef HANDLE name #endif typedef HANDLE *PHANDLE; ``` _MSC_VER含义如下 ```c++ MSVC++ 11.0 _MSC_VER = 1700 (Visual Studio 2012) MSVC++ 10.0 _MSC_VER = 1600 (Visual Studio 2010) MSVC++ 9.0 _MSC_VER = 1500 (Visual Studio 2008) MSVC++ 8.0 _MSC_VER = 1400 (Visual Studio 2005) MSVC++ 7.1 _MSC_VER = 1310 (Visual Studio 2003) MSVC++ 7.0 _MSC_VER = 1300 MSVC++ 6.0 _MSC_VER = 1200 MSVC++ 5.0 _MSC_VER = 1100 ``` 进入了宏开关的else分支 ```c++ #define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name ``` 展开上面的宏,假设传入的name为obj,展开后的结果 ```c++ #define DECLARE_HANDLE(obj) struct obj__ { int unused; }; typedef struct obj__ *obj; ``` 再将DECLARE_HANDLE (HWND);展开 ```c++ #define DECLARE_HANDLE(HWND) struct HWND__ { int unused; }; typedef struct HWND__ *HWND; ``` 那么HWND就是一个仅含有一个整型成员变量的结构体对象的地址,这样一来HWND hwnd; 其实就等价于 HWND__* hWnd; 注意:(1)句柄是跨进程可见的,而指针从来都是属于某个特定进程的,这里摘自网上还没验证,但是根据核心编程里面对内核对象的理解,那里指出内核对象是内核地址上的一块区域,应该差不多 注意:这里是参照Windows核心编程对内核对象的解释 句柄其实就是对象地址的再次封装,防止肆意破坏对象且提供了一种安全的机制权限的一个整型值,这里我们进封装,由于Windows对象很多,需要一个类似索引的表。