Windows头文件中定义的四种数据结构体
结构体 | 含义 |
---|---|
MSG | Message structure |
WNDCLASS | Window class structure |
PAINTSTRUCT | Paint structure |
RECT | Rectangle structure |
三个不同类型的 “ 句柄 ” ,使用大写标识符
标识符 | 含义 |
---|---|
HINSTANCE | 程序本身的“实例”句柄 |
HWND | 窗口的句柄 |
HDC | 设备上下文的句柄 |
常用的变量名前缀
前缀 | 数据类型 |
---|---|
c | char or WCHAR or TCHAR |
by | BYTE (unsigned char) |
n | short |
i | int |
x, y | int used as x−coordinate or y−coordinate |
cx, cy | int used as x or y length; c stands for “count” |
b or f | BOOL (int); f stands for “flag” |
w | WORD (unsigned short) |
l | LONG (long) |
dw | DWORD (unsigned long) |
fn | function |
s | string |
sz | string terminated by 0 character |
h | handle |
p | pointer |
注册窗口类
窗口始终基于窗口类创建。窗口类标识处理窗口消息的窗口过程。
可以基于一个窗口类创建多个窗口。例如,所有按钮窗口(包括按钮、复选框和单选按钮)都是基于同一个窗口类创建的。窗口类定义了窗口过程和基于该类创建的窗口的其他一些特征。当您创建一个窗口时,您将定义该窗口特有的附加特征。
在创建应用程序窗口之前,必须通过调用RegisterClass注册窗口类。这个函数需要一个参数,它是一个指向WNDCLASS类型结构的指针。该结构包含两个指向字符串的指针字段,因此在WINUSER.H头文件中以两种不同的方式定义该结构。首先是ASCII版本,WNDCLASSA:
typedef struct tagWNDCLASSA
{
UINT style ;
WNDPROC lpfnWndProc ;
int cbClsExtra ;
int cbWndExtra ;
HINSTANCE hInstance ;
HICON hIcon ;
HCURSOR hCursor ;
HBRUSH hbrBackground ;
LPCSTR lpszMenuName ;
LPCSTR lpszClassName ;
}
WNDCLASSA, * PWNDCLASSA, NEAR * NPWNDCLASSA, FAR * LPWNDCLASSA ;
注意这里使用的一些匈牙利表示法:lpfn前缀表示“指向函数的长指针”。(回想一下,在Win32 API中,长指针和近指针之间没有区别。这是16位Windows的残余。)cb前缀表示“字节数”,通常用于表示字节大小的变量。前缀h是一个句柄,而前缀hbr表示“刷子的句柄”。lpsz前缀是一个“指向以0结尾的字符串的长指针”。
该结构的Unicode版本定义如下:
typedef struct tagWNDCLASSW
{
UINT style ;
WNDPROC lpfnWndProc ;
int cbClsExtra ;
int cbWndExtra ;
HINSTANCE hInstance ;
HICON hIcon ;
HCURSOR hCursor ;
HBRUSH hbrBackground ;
LPCWSTR lpszMenuName ;
LPCWSTR lpszClassName ;
}
WNDCLASSW, * PWNDCLASSW, NEAR * NPWNDCLASSW, FAR * LPWNDCLASSW ;
唯一的区别是,最后两个字段被定义为指向常量宽−字符串的指针,而不是指向常量ASCII字符串的指针。
在WinMain中,通常像这样定义了一个 WNDCLASS
类型的结构体:
WNDCLASS wndclass;
然后初始化结构的10个字段并调用RegisterClass。
WNDCLASS
结构体中两个最重要的字段是第二个和最后一个。第二个字段(lpfnWndProc)是用于基于该类的所有窗口的窗口过程的地址。最后一个字段是窗口类的文本名称。这可以是任何你想要的。在只创建一个窗口的程序中,窗口类名通常设置为程序的名称。
接下来的两个字段用于在Windows内部维护的类结构和窗口结构中保留一些额外的空间:
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;