这篇主要讲下MyRegisterClass和InitInstance
MyRegisterClass
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_HELLOWINDOWS));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_HELLOWINDOWS);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
首先,我们要知道,WNDCLASSEXW和WNDCLASSEX是同一个东西
我们来看下WNDCLASSEXW的结构
typedef struct tagWNDCLASSEXW {
UINT cbSize;
/* Win 3.x */
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCWSTR lpszMenuName;
LPCWSTR lpszClassName;
/* Win 4.0 */
HICON hIconSm;
} WNDCLASSEXW, *PWNDCLASSEXW, NEAR *NPWNDCLASSEXW, FAR *LPWNDCLASSEXW;
cbsize:该结构体大小
style:窗口的风格
WNDPROC:该窗口的消息处理程序
cbWndExtra和CBClsExtra:暂时不用管它,是提供给窗口和类的额外内存,我们默认为0
hInstance:包含类的窗口过程的实例的句柄。即包含这个窗口消息处理程序的程序实例句柄。
hIcon:类图标的句柄。此成员必须是图标资源的句柄。如果为空,则系统提供默认句柄。
hCursor:类游标的句柄。此成员必须是游标资源的句柄。如果此成员为空,则每当鼠标移到应用程序的窗口中时,应用程序必须显式设置光标形状。
hbrBackground:类背景画笔的句柄。此成员可以是用于绘制背景的画笔的句柄,也可以是颜色值。
lpszMenuName:指向以空结尾的字符串的指针,该字符串指定类菜单的资源名称,该名称显示在资源文件中。如果使用整数标识菜单,请使用makeintresource宏。如果该成员为空,则属于该类的窗口没有默认菜单。
lpszClassName:指向以空结尾的字符串或原子的指针。如果此参数是一个原子,则它必须是由先前对registerclass或registerclassex函数的调用创建的类原子。原子必须在lpszclassname的低位字中;高位字必须为零。
如果lpszclassname是字符串,则指定窗口类名。类名可以是用registerclass或registerclassex注册的任何名称,也可以是任何预定义的控件类名。
hIconsm:与窗口类关联的小图标的句柄。如果此成员为空,系统将搜索hicon成员指定的图标资源,以查找大小合适的图标用作小图标。
即使看了参数解释,我相信很多人跟我一样对代码依然有不懂的地方。
问题一:CS_HREDRAW | CS_VREDRAW 什么意思?
首先|表示将两边数据进行或操作,结果是两者兼并的效果。然后我们来了解class style里的各个宏定义的意义
/*
* Class styles
*/
#define CS_VREDRAW 0x0001 //如果移动或大小调整更改了工作区的高度,则重新绘制整个窗口。
#define CS_HREDRAW 0x0002 //如果移动或大小调整更改了工作区的宽度,则重新绘制整个窗口。
#define CS_DBLCLKS 0x0008 //当用户在属于该类的窗口中双击鼠标时,向窗口过程发送双击消息。
#define CS_OWNDC 0x0020 //为类中的每个窗口分配唯一的设备上下文。
#define CS_CLASSDC 0x0040 //分配一个要由类中所有窗口共享的设备上下文。
#define CS_PARENTDC 0x0080 //将子窗口的剪切矩形设置为父窗口的剪切矩形,以便子窗口可以在父窗口上绘制。
#define CS_NOCLOSE 0x0200 //禁用“窗口”菜单上的“关闭”。
#define CS_SAVEBITS 0x0800 //将被此类窗口遮挡的屏幕图像部分保存为位图。删除窗口时,系统使用保存的位图还原屏幕图像
#define CS_BYTEALIGNCLIENT 0x1000//在字节边界(X方向)上对齐窗口的工作区。此样式影响窗口的宽度及其在显示中的水平位置。
#define CS_BYTEALIGNWINDOW 0x2000//在字节边界(X方向)上对齐窗口。此样式影响窗口的宽度及其在显示中的水平位置。
#define CS_GLOBALCLASS 0x4000//指示窗口类是应用程序全局类。
我们不需要把每个宏定义都搞明白,只需要知道个大概。
那么答案显而易见就是如果移动或改变了窗口大小就会重绘窗口
问题二:RegisterClassExW函数干了什么呢?为什么需要注册窗口类?
https://zhidao.baidu.com/question/196021427.html
InitInstance
我们只需要了解一个函数:CreateWindowW
HWND CreateWindowExW(
DWORD dwExStyle,
LPCWSTR lpClassName,
LPCWSTR lpWindowName,
DWORD dwStyle,
int X,
int Y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
dwExStyle:正在创建的窗口的扩展窗口样式。默认为0,之所以在CreateWindowW没有出现是因为被宏定义默认为0了。
lpClassName:窗口类名
lpWindowName:窗口名,也是本程序中的标题栏文本
dwStyle:正在创建的窗口的样式。此参数可以是窗口样式值和“备注”部分中指示的控件样式的组合。
x:窗口的初始水平位置。
y:窗口的初始竖直位置。
nWidth:窗口宽度
nHeight:窗口高度
hWndParent:正在创建的窗口的父窗口或所有者窗口的句柄。
hMenu:菜单句柄
hInstance: 与窗口关联的模块实例的句柄
lpParam:指向要通过wm_create消息的lparam参数指向的createstruct结构(lpcreateparams成员)传递给窗口的值的指针。
同样,我们直接看问题
问题一:第三个参数WS_OVERLAPPEDWINDOW是什么意思?
#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | \
WS_CAPTION | \
WS_SYSMENU | \
WS_THICKFRAME | \
WS_MINIMIZEBOX | \
WS_MAXIMIZEBOX)
根据宏定义我们可以看到这是一个窗口样式的组合,这个叫做层叠式窗口,虽然我也不知道为什么要层叠式(捂脸)
问题二:为什么窗口的初始x位置指定为CW_USEDEFAULT后,y指定为0但窗口的y方向位置并不是0。对于后面的两个参数同理。
MSDN文档规定了它的规则:
The initial horizontal position of the window. For an overlapped or pop-up window, the x parameter is the initial x-coordinate of the window's upper-left corner, in screen coordinates. For a child window, x is the x-coordinate of the upper-left corner of the window relative to the upper-left corner of the parent window's client area. If this parameter is set to CW_USEDEFAULT, the system selects the default position for the window's upper-left corner and ignores the y parameter. CW_USEDEFAULT is valid only for overlapped windows; if it is specified for a pop-up or child window, the x and y parameters are set to zero.
描粗的句子说明了一切 :如果此参数设置为CW U USEFAULT,系统将选择窗口左上角的默认位置并忽略Y参数。
至此,所有的win32初始代码解析就结束了。