1.注册窗口类函数
(1)RegisterClass/RegisterClassEx
ATOM RegisterClass(CONST WNDCLASS *lpWndClass);
ATOM RegisterClassEx(CONST WNDCLASSEX *lpwcx);
注册成功后,返回一个非0数字标识,失败返回0。
(2)窗口类的风格
CS_GLOBALCLASS - 应用程序全局窗口类
CS_BYTEALIGNCLIENT - 窗口客户区的水平位置8整倍数据对齐
CS_BYTEALIGNWINDOW - 窗口的水平位置8整倍数据对齐
CS_HREDRAW - 当窗口水平变化时,窗口重新绘制
CS_VREDRAW - 当窗口垂直变化时,窗口重新绘制
CS_CLASSDC - 该类型的窗口,都是有同一个绘图(DC)设备
CS_PARENTDC - 该类型的窗口,使用它的父窗口的绘图(DC)设备
CS_OWNDC - 该类型的窗口,每个窗口都是用自己的绘图(DC)设备
CS_SAVEBITS - 允许窗口保存成图(位图),提高窗口的绘图效率,但是耗费内存资源
CS_DBLCLKS - 允许窗口接收鼠标双击
CS_NOCLOSE - 窗口没有关闭按钮
下面是简单的示例代码:
#include "stdafx.h" void AppReg() { //注册窗口类 WNDCLASSEX wce = { 0 }; wce.cbSize = sizeof(wce); //大小 wce.cbClsExtra = 0; //窗口类附加数据buffer的大小 wce.cbWndExtra = 0; //窗口的附加数据buffer的大小 wce.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); //背景为白色 wce.hCursor = NULL; //默认光标 wce.hIcon = NULL; //默认大图标 wce.hIconSm = NULL; //默认小图标 wce.hInstance = g_hInstance; //当前程序实例句柄 wce.lpfnWndProc = DefWindowProc; //系统默认窗口处理函数 wce.lpszClassName = "Main"; //窗口类名 wce.lpszMenuName = NULL; //窗口菜单 wce.style = CS_HREDRAW | CS_VREDRAW; //窗口风格 //将以上赋值写入操作系统 ATOM nAtom = RegisterClassEx(&wce); if (nAtom == 0) { MessageBox(NULL, "注册失败", "Info", MB_OK); return; } HWND hWnd = CreateWindow("Main", "Window", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, g_hInstance, NULL); ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd); MSG uMsg = { 0 }; while (GetMessage(&uMsg, NULL, 0, 0)) { TranslateMessage(&uMsg); DispatchMessage(&uMsg); } } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int cCmdShow) { g_hInstance = hInstance; AppReg(); return 0; }
2.创建窗口
(1)创建窗口函数CreateWindow
(2)内部执行过程
CreateWindow用其中两个参数用来确定窗口,CreateWindow("Main", ..., g_hInstance, ...),即窗口类名和当前程序实例句柄。
a.系统根据传入的窗口类名称,在应用程序局部窗口类中查找,如果找到执行b,否则执行c。
b.比较局部窗口类与创建窗口时传入的HINSTANCE变量。如果发现相等,创建和注册的窗口在同一模块,创建窗口返回。否则执行c。
c.在应用程序全局窗口类中查找,如果找到,执行d,否则执行e。
d.使用找到的窗口类的信息,创建窗口返回。
e.在系统窗口类中查找,如果找到,创建窗口,否则窗口创建失败。
若创建窗口成功,那么CreateWindow就申请内存,将传入的参数写入到内存中,返回这块内存的句柄。