本笔记源自windows游戏编程大师技巧第二版2.6章,记做学习随笔。
使用vs2017环境编译。
Windows是一个面向对象的操作系统,Windows大量概念都源自于C++,其中一个概念就是Window类。
类描述了窗口的基本信息,比如窗口的图标,鼠标进入窗口的图标,和一些可定制的东西。
window的数据类有两个,WNDCLASS和WNDCLASSEX两个,WNDCLASS比较古老,可能要被弃用,我们使用WNDCLASSEX。
我们只需要创建一个这样的类,然后填写所有的字段。
#include <Windows.h>
#include <windowsx.h>
#define WIN32_LEAN_AND_MEAN
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline,int ncmdshow)
{
WNDCLASSEX winclass; //创建Windows类,这样创建就可以了
return 0;
}
来看WNDCLASSEX类的原型吧。
typedef struct WNDCLASSEX {
UINT cbSize; //WNDCLASSEX 的大小。我们可以用sizeof(WNDCLASSEX)来获得准确的值。
UINT style; //从这个窗口类派生的窗口具有的风格。您可以用“or”操作符来把几个风格或到一起。
WNDPROC lpfnWndProc; //窗口处理函数的指针。
int cbClsExtra; //指定紧跟在窗口类结构后的附加字节数。
int cbWndExtra; //指定紧跟在窗口实例的附加字节数。如果一个应用程序在资源中用CLASS伪指令注册一个对话框类时,则必须把这个成员设成DLGWINDOWEXTRA。
HINSTANCE hInstance; //本模块的实例句柄。
HICON hIcon; //图标的句柄。
HCURSOR hCursor; //光标的句柄。
HBRUSH hbrBackground; //背景画刷的句柄。
LPCTSTR lpszMenuName; //指向菜单的指针。
LPCTSTR lpszClassName; //指向类名称的指针。
HICON hIconSm; //和窗口类关联的小图标。如果该值为NULL。则把hIcon中的图标转换成大小合适的小图标。
} WNDCLASSEX;
第一个:cbSize,填写WNDCLASSEX类本身的大小。因为这个结构被像指针一样传递,别的函数会检查他的大小,以确定数据块最低限度多大,这样你写入,别的函数就无需计算,我们这样写即可:
winclass.cbSize = sizeof(WNDCLASSEX);
第二个:style,包含描述窗口属性的样式(style)信息标志。
CS_HREDRAW | 若移动或改变窗口宽度,则刷新整个窗口 |
CS_VREDRAW | 若移动或改变窗口高度,则刷新整个窗口。 |
CS_OWNDC | 为该类中每窗口分配一个单值的设备描述表(稍后再说) |
CS_DBLCLKS | 当用户双击鼠标时向窗口程序发送一个双击的信息,同时光标位于该类的窗口里 |
CS_PARENTDC | 在父窗口中设定一个子窗口的剪切区,以便子窗口能够在父窗口中。 |
CS_SAVEBITS | 在一个窗口中保存用户图像,以便于该窗口被遮住,移动时不必每次刷新屏幕,但是会占用更多内存 |
CS_NOCLOSE | 禁用系统菜单上的关闭命令 |
winclass.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC | CS_DBLCLKS;
我们的窗口只需要这样选择参数即可,其他的参数后边再记录具体用途。
第三个:lpfnWndProc,他是一个回调函数,当你的窗口有消息后,比如用户要点击按钮,或者输入什么,win就会替你调用这个函数。
当然,这个回调函数是自己写的。
winclass.lpfnWndProc = WndProc; //WndProc不是window提供的东西,我们一会要自己写一个。
等到下一章来写WndProc回调函数,当然不喜欢WndProc这个名字的话,也可以取自己喜欢的回调函数名字。
第四五个:cbClsExtra,bWndExtra,为软件或窗口添加附件内存,绝大数人都是简单的设为0,默认值也是0。
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
第六个:hInstance,他就填写WinMain()函数中的hinstance,也就是应用程序的句柄。可以看上一篇笔记有对这个做出详细解释。
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline,int ncmdshow)//第一个实参
{
.
.
.
winclass.hInstance = hinstance; //WinMain实参的第一个参数,是程序的句柄。
return 0;
}
说明一下:句柄有很多,比如窗口句柄,上边的程序句柄,还有图标,菜单等等。。句柄起到类似指针的效果,任何前缀h的类型通常就是句柄,关于句柄的详细信息自行搜索。
第七个:hIcon,他装载一个标准程序的应用图标
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
LoadIcon()原型如下:
HICON LoadIcon(HINSTANCE hInstance,LPCTSTR lpIconName);
第一个值是程序句柄类,他可以调用程序包含的图片资源,LPCTSTR是字符串,可以填入资源名字或字符串,我们这个用一个win提供的默认图标。
第八个:hCursor,是设置应用程序的鼠标样式
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
还是使用Ladlcom函数,这里用一个win提供的默认标准箭头。
第九个,hbrBackground,这是默认填充窗口,也就是设置窗口的背景颜色。
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
GetStockObject()参数为预设画刷,之后强制转换为HBRUSH即可。
第十个,lpszMenuName,用于加载和选用窗口,暂时设为NULL,后边会用到。
winclass.lpszMenuName = NULL;
十一个,lpszClassName,他的作用是为你的WNDCLASSEX类取一个别名,是一个标识符,之后你就可以用这个新名字来引用这个类了。
winclass.lpszClassName = "WINCLASS1";
这里取名为“WINCLASS1”。
十二个, LoadIcon,他是小应用图标,用于在任务栏和窗口标题栏现实的图标。
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
依然是使用LoadIcon()设置.
来回顾一下我们的设置:
#include <Windows.h>
#include <windowsx.h>
#define WIN32_LEAN_AND_MEAN
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline,int ncmdshow)
{
WNDCLASSEX winclass;
winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC | CS_DBLCLKS;
winclass.lpfnWndProc = WndProc; //WndProc还没有定义。
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = "WINCLASS1";
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
return 0;
}
这段代码目前不能运行的,因为我们还没有写lpfnWndProc的回调函数。