如图1是单文档应用程序的窗口,是由MFC向导程序帮我们创建和设计的,如果我们想自己创建一个类似的窗口,我们该怎么办呢?就像汽车公司想生产汽车,他们就要解决两个问题。
图1 单文档窗口样式
问题1:
汽车形状是什么样子,汽车是什么颜色的等外观问题,这个问题可以由汽车设计图来解决,有了设计图我们就可以知道汽车长什么样子了。
问题2:
有了汽车设计图,还要有人去生产加工才行,工厂就是车辆创建的角色,工厂会按照设计图纸生产出符合预期的车辆。
按照这个思路,一个窗口的创建需要以下几个步骤:
第一:需要窗口的设计图(比如标题栏是什么图标,鼠标是什么形状,窗口背景是什么颜色)
第二:我们需要将窗口的设计图纸提交给(注册)windows系统,
第三:如果提交成功了,windows就会按照这个图纸去创建我们需要的窗口
第四:如果有必要,我们还要把它显示出来,默认窗口仅存在于内存中。
关于设计图纸
微软给我们提供了WNDCLASS结构体,这个结构体指示了我们要创建怎样的窗口,lpszClassName是这个窗口的唯一标识,如下是具体内容:
typedef struct { UINT style; //这一类型窗口的样式 WNDPROC lpfnWndProc; //指向窗口过程的函数指针 int cbClsExtra; //类附加内存 int cbWndExtra; //窗口附加内存 HINSTANCE hInstance; //实例句柄 HICON hIcon; //窗口类的图标句柄 HCURSOR hCursor; //窗口类的光标句柄 HBRUSH hbrBackground; //窗口类的背景 LPCTSTR lpszMenuName; //菜单名字 LPCTSTR lpszClassName; //窗口类名字,是窗口类的唯一标识 } WNDCLASS;
关于注册窗口信息
微软给我们提供了RegisterClass函数,它的入参是WNDCLASS对象指针,也就是告诉系统我要创建窗口的具有的特征,其函数声明如下:
ATOM RegisterClass(const WNDCLASS* lpWndClass);
关于创建窗口
系统有了窗口的设计图纸,就开始生成这个窗口,微软提供了CreateWindow函数,第一个参数是窗口类的名称,也就是WNDCLASS结构体中的lpszClassName,第二个是当前这个窗口的名字,具体函数声明见如下代码:
HWND CreateWindow(LPCTSTR lpClassName, //指定窗口类的名称,需要和WNDCLASS的className一样。 LPCTSTR lpWindowName, //窗口的名字 DWORD dwStyle, //创建的窗口样式 int x, //窗口左上角的x坐标 int y, //窗口左上角的y坐标 int nWidth, //窗口宽度 int nHeight, //窗口高度 HWND hWndParent, //父窗口句柄 HMENU hMenu, //窗口菜单的句柄 HANDLE hInstance, //应用程序句柄 PVOID lpParam ); //附件参数,多文档窗口为CLIENTCREATESTRUCT结构体,其余多是NULL
关于显示
当我们把窗口按照设计图纸给创建后,我们还可以调用ShowWindow函数来展示我们设计的窗口,其函数声明如下:
BOOL ShowWindow(HWND hWnd, int nCmdShow) hWnd 指示要显示哪个窗口 nCmdShow 指示要窗口的状态,有如下取值范围,具体含义见MSDN SW_HIDE SW_SHOW SW_SHOWNA SW_SHOWNORMAL
从以上内容可以知道,一个窗口的最终外观由两部分决定:
一个是WNDCLASS结构体中的部分参数比如光标,图标,窗口背景;另一部分是CreateWindow接口中的部分参数,比如宽度、高度,位置信息,以及这个窗口的名字。
如果想修改窗口的外观也是从这两个反向进行修改。
参考以下两篇文章也有助于理解窗口类的注册和创建,链接如下:
http://blog.csdn.net/c_base_jin/article/details/52263627
http://blog.sina.com.cn/s/blog_520f749201009bgi.html