分类: C/C++
2006-10-25 13:18:53
“窗口类”是Windows系统的数据结构,可以把它理解为Windows系统的类型定义,而Windows窗口则是相应“窗口类”的实例。Windows使用一个结构来描述“窗口类”,其定义如下:
typedef struct _WNDCLASSEX {
UINT cbSize; //该结构的字节数
UINT style; //窗口类的风格
WNDPROC lpfnWndProc; //窗口过程
int cbClsExtra;
int cbWndExtra;
HANDLE hInstance; //该窗口类的窗口过程所属的应用实例
HICON hIcon; //该窗口类所用的像标
HCURSOR hCursor; //该窗口类所用的光标
HBRUSH hbrBackground; //该窗口类所用的背景刷
LPCTSTR lpszMenuName; //该窗口类所用的菜单资源
LPCTSTR lpszClassName; //该窗口类的名称
HICON hIconSm; //该窗口类所用的小像标
} WNDCLASSEX;
从“窗口类”的定义可以看出,它包含了一个窗口的重要信息,如窗口风格、窗口过程、显示和绘制窗口所需要的信息,等等。
Windows系统在初始化时,会注册(Register)一些全局的“窗口类”,例如通用控制窗口类。应用程序在创建自己的窗口时,首先必须注册自己的窗口类。在MFC环境下,有几种方法可以用来注册“窗口类”,下面分别予以讨论。
(1) 调用AfxRegisterClass注册
AfxRegisterClass函数是MFC全局函数。AfxRegisterClass的函数原型:
BOOL AFXAPI AfxRegisterClass(WNDCLASS *lpWndClass);
参数lpWndClass是指向WNDCLASS结构的指针,表示一个“窗口类”。
首先,AfxRegisterClass检查希望注册的“窗口类”是否已经注册,如果是则表示已注册,返回TRUE,否则,继续处理。
接着,调用::RegisterClass(lpWndClass)注册窗口类;
然后,如果当前模块是DLL模块,则把注册“窗口类”的名字加入到模块状态的域m_szUnregisterList中。该域是一个固定长度的缓冲区,依次存放模块注册的“窗口类”的名字(每个名字是以“\n\0”结尾的字符串)。之所以这样做,是为了DLL退出时能自动取消(Unregister)它注册的窗口类。最后,返回TRUE表示成功注册。
(2) 调用AfxRegisterWndClass注册
AfxRegisterWndClass函数也是MFC全局函数。AfxRegisterWndClass的函数原型:
LPCTSTR AFXAPI AfxRegisterWndClass(UINT nClassStyle,
HCURSOR hCursor, HBRUSH hbrBackground, HICON hIcon)
参数1指定窗口类风格;
参数2、3、4分别指定该窗口类使用的光标、背景刷、像标的句柄,缺省值是0。
此函数根据窗口类属性动态地产生窗口类的名字,然后,判断是否该类已经注册,是则返回窗口类名;否则用指定窗口类的属性(窗口过程指定为缺省窗口过程),调用AfxRegisterCalss注册窗口类,返回类名。
动态产生的窗口类名字由以下几部分组成(包括冒号分隔符):
如果参数2、3、4全部为NULL,则由三部分组成。
“Afx”+“:”+模块实例句柄”+“:”+“窗口类风格”
否则,由六部分组成:
“Afx”+“:”+模块实例句柄+“:”+“窗口类风格”+“:”+光标句柄+“:”+背景刷句柄+“:”+像标句柄。比如:“Afx:400000:b:13de:6:32cf”。
该函数在MFC注册主边框或者文档边框“窗口类”时被调用。