[API档案]WNDCLASSEX
WNDCLASSEX原型
typedef struct tagWNDCLASSEXW {
UINT cbSize;
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCWSTR lpszMenuName;
LPCWSTR lpszClassName;
HICON hIconSm;
} WNDCLASSEXW, *PWNDCLASSEXW, NEAR *NPWNDCLASSEXW, FAR *LPWNDCLASSEXW;
参数:
- cbSize:
第一个参数,UINT类型的cbSize,表示该结构体的字节数大小。一般取为sizeof(WINDOWEX) - style:
第二个参数,UINT类型的style,指定这一类型窗口的风格样式,常用的样式取值在下面图片中都列举出来了,其中要取多个的话用逻辑与 " | " 来进行来连接。
比如,我们定义窗口风格为可以水平重绘,垂直重绘,那么代码方面就是这样写:
wndClassEx.style = CS_HREDRAW | CS_VREDRAW; //设置窗口样式
- lpfnWndProc:
第三个参数,WNDPROC类型的lpfnWndProc,它是一个函数指针,指向窗口过程函数。而窗口过程函数是一个回调函数。其中,回调函数就像它的名字一样,并不是由该函数的实现方法直接调用的,而是再特定的事件或条件发生时由另外一方调用的,用于对该事件或条件进行响应。
一个 Windows 程序可以包含多个窗口过程函数,一个窗口过程函数总是与某一个特定的窗口相关联(通过 WNDCLASS 结构体中的lpfnWndProc 成员变量来指定),而基于该窗口类创建的窗口使用的是同一个窗口过程。
- cbClsExtra:
第四个参数,int 类型的 cbClsExtra,表示窗口附加内存。一般我们将这个参数设置为0。
- xbWndExtra:
第五个参数,int 类型的 cbWndExtra ,通过 cbClsExtra 可以猜到,这个参数也表示附加内存,也一般设置为0。
!注意:
cbClExtra 表示窗口类附加内存
cbWndExtra 表示窗口附加内存
- hInstance:
第六个参数,HINSTANCE 类型的hInstance, 指定包含窗口过程的程序的实例句柄。我们需要将WinMain的第一个参数,也就是该程序当前运行的实例句柄传给它。
wndClassEx.hInstance = hInstance;
- hIcon:
第七个参数,HICON 类型的 hIcon,用于指定窗口类的图标句柄。这个成员变量必须是一个图标资源的句柄,如果这个成员为NULL,那么系统将提供一个默认的图标。
在为 hIcon 成员变量赋值时,我们可以调用 LoadIcon 函数来加载一个图标资源,并将 LoadIcon 的返回值赋给hIcon。我们可以在MSDN 中查到这个 LoadIcon 的原型如下:
HICON WINAPI LoadIcon(
_In_opt_ HINSTANCE hInstance,
_In_ LPCTSTR lpIconName
);
LoadIcon 函数不仅可以加载 Windows 系统提供的标准图标到内存中,还可以加载由用户自己制作的图标资源到内存中,并返回系统分给该图标的句柄。但要注意的是,如果加载的是系统的标准图标,那么第一个参数必须为 NULL。
通常我们会使用 LoadImage 函数来从文件中直接加载一个图标资源。LoadImage 函数可以加载位图,如果要加载一个名为 “icon.ico” 的图标作为我们的程序图标,那么代码可以这样写:
wndClassEx.hIcon = (HICON)::LoadImage(NULL, TEXT("icon.ico"), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE));
- hCursor:
第八个参数,HCURSOR 类型的 hCursor,与第七个参数类似,它表示窗口类的光标句柄。
同样,我们用 LoadCursor 来为其加载一个光标资源,返回系统分配给该光标的句柄,我们在 MSDN 中查到这函数的原型声明如下:
HCURSOR WINAPI LoadCursor(
_In_opt_ HINSTANCE hInstance,
_In_ LPCTSTR lpCursorName
);
一般地,可以把这个参数设为默认的箭头光标,就是这样来写:
wndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW);
- hbrBackGround:
第九个参数,HBRUSH 类型的 hbrBackGround,指定窗口类的背景画刷句柄。它的前缀 hbr 表示他是一个画刷句柄。当窗口发生重绘时,系统使用这里指定的画刷来擦除窗口的背景。我可以为 hbrBackGround 指定一个表准的系统颜色。我们可以调用 GetStockObject 函数来得到系统的标准画刷。在 MSDN 中它的原型声明如下:
HGDIOBJ GetStockObject(
__in int fnObject
);
其中唯一的一个参数 fnObject 指定要获取的对象的类型,这个函数不仅可以获取画刷的句柄,还可以获取画笔、字体和调色板的句柄。
我们给背景指定一个灰色画刷,那么代码可以这样写:
wndClassEx.hbrBackGround = (HBRUSH)GetStockObject(GRAY_BRUSH);
- lpszMenuName:
第十个参数,LPCTSTR 类型的 lpszMenuName,一个以空终止的字符串,指定菜单资源的名字,如果不需要下拉菜单(比如编辑、保存和打开)的话,就把这项设为 NULL 就好了。
wndClassEx.lpszMenuName = NULL;
- lpszClassName:
第十一个参数,LPCTSTR 类型的 lpszClassName,一个以空终止的字符串,指定窗口类的名字。这里的类名称是自定义的,名字取了之后后面会用到,就像身份证一样,用来标识我们正在定义的这个窗口类。
比如可以这样写:
wndClassEx.lpszClassName = TEXT("The first windows program");
- hIconSm:
第十二个参数,HICON 类型的 hIconSm,指定窗口类的小图标句柄。就是任务栏右下角托盘中应用程序显示的小图标。
代码可以这么写:
wndClassEx.hIconSm = LoadImage(NULL, MAKEINTRESOURCE(5), GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), R_DEFAULTCOLOR);
当然不写,也是可以的。