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对象很多,需要一个类似索引的表。