《逐梦旅程》笔记--消息与消息队列&窗口类的设计

5,消息与消息队列

顺序(步骤)
感知事件(比如感知你的鼠标按了一下)→将事件包装成消息→投递到消息队列→程序从消息队列取出 消息并“响应”
消息的表现形式–MSG结构体 原型以及参数详解:

``typedef struct tagMSG`
`{`
	`HWND hwnd;//指定消息所属的窗口`
	`UINT message;//指定消息的标识符`
	`WPARAM wParam;//指定此msg的附加信息`
	`LPARAM lParam;//指定此msg的附加信息`
	`DWORD time;//指定投递到消息队列的时间`
	`POINT pt;//指定投递到消息队列中时鼠标的当前位置`
}MSG;`

第一个参数

HWND类型的hwnd,指定了消息所属的窗口。(通常一个消息都是与某个窗口相关联的)在Windows程序中,通常用HWND类型的变量来标识窗口。

第二个参数

UINT类型的message,指定了消息的标识符。在Windows中消息是由一个数值来表示的,不同消息对应不同数值,又因为不方便,所以Windows将对应的数值定义为WM_XXX(其中WM是Windows Message的缩写)宏的形式,XXX对应某种消息英文拼写的大写形式–例如:

1WM_RBUTTONDOWN(右键按下)
2WM_LBUTTONDBCLICK(左键双击)
3WM_KEYDOWN(键盘按下)
4WM_QUIT(退出)

第三个以及第四个参数

WPARAM类型的wParam和LPARAM类型的lParam,他们都用于指定消息的附加消息,例子:当收到一个字符消息时,message程序就按变量的值–WM_CHAR,那到底输入了什么字符呢?就由wParam和lParam来说明了。wParam和lParam表示的信息会随着消息的不同而不同。区别:WPARAM是unsigned int类型,而LPARAM是long类型

第五个参数

DWORD类型的time,表示投递到消息队列的时间

第六个参数

POINT类型的pt,表示投递到消息队列中时鼠标的当前位置

消息队列

每一个Windows程序开始执行之后,系统都会为该程序创建一个消息队列,用于存放程序创建的窗口的消息,系统会将这个消息放到窗口所属应用程序消息队列中,等待处理,而应用程序通过一个消息循环不断从消息队列中取出并进行响应,这就是Windows程序运行的机制

6,窗口创建

四个步骤

  1. 窗口类的设计
  2. 窗口类的注册
  3. 窗口的正是创建
  4. 窗口的显示与更新
1,窗口类的设计

大概包括:光标、图标、背景颜色等等

WNDCLASSEC结构体原型:

typedef struct tagWNDCLASSEX {
		UINT      cbSize;
		UINT      style;
		WNDPROC   lpfnWndProc;
		int       cbClsExtra;
		int       cbWndExtra;
		HINSTANCE hInstance;
		HICON     hIcon;
		HCURSOR   hCursor;
		HBRUSH    hbrBackground;
		LPCSTR    lpszMenuName;
		LPCSTR    lpszClassName;
		HICON     hIconSm;
	} WNDCLASSEX, * PWNDCLASSEX;

定义一个WNDCLASSEX:

WNDCLASSEX wndClass = { 0 };//用WINDCLASSEX定义了一个窗口类,即用wndClass实例化了WINDCLASSEX,用于之后窗口的各项初始化
第一个参数

UINT类型的cbSize,表示该结构体字节数的大小,一般取为sizeof (WNDCLASSEX)即可:

wndClass.cbSize = sizeof(WNDCLASSEX) ;//设置结构体字节数大小
第二个参数

UINT类型的style,指定这一类型窗口的风格样式,常用样式取值:

ID值名称描述
CS_HREDRAW当窗口水平方向上的宽度发生变化时,将重新绘制整个窗口。当窗口发生重绘时,窗口中的文字和图形将擦除。如果没有指定这一样式,那么在水平方向上调整窗口宽度时,将不会重绘窗口
CS_VREDRAW当窗口垂直方向上的高度发生变化时,将重新绘制整个窗口。如果没有指定这一个样式,那么在垂直方向上调整窗口高度时,将不会重绘窗口
CS_NOCLOSE禁用系统菜单的Close命令,这将导致窗口没有关闭按钮
CS_DBLCLKS当用户在窗口中双击鼠时,向窗口过程发送鼠标双击消息

例子:要求窗口可以水平重绘和垂直重绘

wndClass.style = CS_HREDRAW | CS_VREDRAW//设置窗口样式
第三个参数
定义:

WNDPROC类型的lpfnWndProc,是一个函数指针,指向窗口过程函数(是一个回调函数,即在特定的事件或条件发生时由另外一方调用,用于对该事件或条件响应)

过程:

①:在设计窗口类时,将窗口过程函数的地址赋值给ipfnWndProc成员变量

②:调用RegsiterClass(&wndclass)注册窗口类,那么系统就有了我们所编写的窗口过程函数的地址(WNDPROC类型的lpfnWndProc)

③:当应用程序接到消息时,调用DispatchMessage(&msg)将消息回传给系统系统利用先前注册窗口类时得到的函数指针,调用窗口过程函数对消息进行处理

注意:一个程序可以有多个窗口过程函数,一个窗口过程总是与某一个特定的窗口类相关(通过WNDCLASS结构体中的lpfnWndProc成员变量来指定),而基于该窗口类创建的窗口使用的是同一个窗口过程。

lpfnWndProc成员变量的类型是WNDPROC,定义:

typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT,WPARAM,LPARAM);

若我们定义的窗口过程函数名称是WndProc,那么对这个参数赋值的代码就是:

wndClass.lpfnWndProc = WndProc//指向窗口过程函数的指针
第四个参数

int类型的cbClsExtra,表示窗口类附加内存。一般设置为0:

wndClass.cbClsExtra = 0;
第五个参数

int类型的cbWndExtra,表示窗口附加内存,代码:

wndClass.cbWndExtra = 0; 
第六个参数

HINSTANCE类型的hInstamce,指定窗口的实例句柄,我们要把WinMain函数的第一个参数,也就是该程序当前运行的实例句柄传给他,代码:

wndClass.hInstance = hInstance;//指定包含窗口过程函数的实例句柄
第七个参数

HICON类型的hIcon,用于指定窗口类的图标句柄,必须是一个图标资源的句柄,若为NULL,那么系统将提供默认图标

为hIcon变量赋值时,可以调用LoadIcon函数来加载一个资源,并将LoadIcon的返回值赋给hIcon,也可以加载由用户自己制作的图标资源,并返回系统分配给该资源的句柄。

从工程目录加载一个名为icon.ico的图标,代码:

wndClass.hIcon = (HICON)::LoadImage(NULL,_T("icon.ico"), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);//从全局的::LoadImage函数从本地加载自定义ico图标

其中的_T(“icon.ico”)中的T("")会根据当前的字符环境智能地在宽字符和普通字符之间转换,与unicode字符集环境下的L"icon.ico"一个用法。

第八个参数

HCURSOR类型的hCursor,加载光标资源,若把他设为默认箭头光标,代码:

wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);//指定窗口类的光标句柄。
第九个参数

HBRUSH类型的hbrBackground,指定窗口类的背景画刷句柄,前缀hbr表示他是一个画刷句柄(handle to brush)。当窗口发生重绘时,系统使用这里指定的画刷来擦除窗口的背景。既可以为hbrBackground指定一个画刷的句柄,也可以把他取为一个标准颜色。可以调用GetStockObject函数来得到系统的标准画刷,原型:

HGDIOBJ GetStockObject(
	_in int fnObject
);

fnObject指定要获取的对象的类型,不仅可以获取画刷句柄,也可以获取画笔、字体和调色板的句柄。

灰色画刷,代码:

wndClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);//为hbrBackground成员指定一个灰色画刷句柄。
第十个参数

LPCTSTR类型的lpszMenuName,一个以空终止的字符串,指定菜单资源的名字,一般设为NULL就好了,代码:

wndClass.lpszMenuName = NULL;//用一个以空终止的字符串,指定菜单资源的名字。
第十一个参数

LPCTSTR类型的lpszMenuName,也是一个以空终止的字符串,指定窗口类的名字,就像身份证一样,用来表示我们定义的这个窗口类,代码:

wndClass.lpszClassName = _T("ForTheDreamofGameDeveloping!!");//用一个以空字符串终止的字符串,指定窗口类的名字
第十二个参数

不是很重要啦~~~

HICON类型的hIconSm,指定窗口类的小图标句柄

在这里插入图片描述

就是这些吧。。。。

好的

这是以上代码:

	/*typedef struct tagWNDCLASSEXA {
		UINT      cbSize;
		UINT      style;
		WNDPROC   lpfnWndProc;
		int       cbClsExtra;
		int       cbWndExtra;
		HINSTANCE hInstance;
		HICON     hIcon;
		HCURSOR   hCursor;
		HBRUSH    hbrBackground;
		LPCSTR    lpszMenuName;
		LPCSTR    lpszClassName;
		HICON     hIconSm;
	} WNDCLASSEX, * PWNDCLASSEX; -----------*/
	LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
	WNDCLASSEX wndClass = { 0 };//用WINDCLASSEX(一个结构体)定义了一个窗口类,即用wndClass实例化了WINDCLASSEX,用于之后窗口的各项初始化
	wndClass.cbSize = sizeof(WNDCLASSEX);//设置结构体字节数大小
	wndClass.style = CS_NOCLOSE| CS_VREDRAW;//设置窗口样式
	wndClass.lpfnWndProc = WndProc;//指向窗口过程函数的指针
	wndClass.cbClsExtra = 0; 
	wndClass.cbWndExtra = 0;
	wndClass.hInstance = hInstance;//指定包含窗口过程的实例句柄
	/*HICON WINAPI LoadIcon(
		_In_opt_ HINSTANCE	hInstance,
		_In_opt_ LPCTSTR lpIconName
	);*/
	wndClass.hIcon = (HICON)::LoadImage(NULL,_T("icon.ico"), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);//从全局的::LoadImage函数从本地加载自定义ico图标
	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);//指定窗口类的光标句柄。
	wndClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);//为hbrBackground成员指定一个灰色画刷句柄。
	wndClass.lpszMenuName = NULL;//用一个以空终止的字符串,指定菜单资源的名字。
	wndClass.lpszClassName = _T("ForTheDreamofGameDeveloping!!");//用一个以空字符串终止的字符串,指定窗口类的名字

最好跟着一个个敲一遍

初中生挤一点时间打这么多字不容易,谢谢大家的支持,话说5.11开学了,以后就没有这么快更新了(虽然我只有两个粉丝……)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值