3.1消息队列

消息队列概念

  • 消息队列是用于存放消息的队列
  • 消息在队列中先入后出
  • 所有窗口程序都具有消息队列
  • 程序(GetMessage)可以从队列中获取消息

消息队列分类

  • 系统消息队列
    由系统维护的消息队列。存放系统产生的消息,例如鼠标、键盘等。
  • 程序消息队列
    属于每一个应用程序(线程)的消息队列。由应用程序(线程)维护。

消息和队列关系

  1. 消息和消息队列的关系
  2. 当鼠标、键盘等产生消息时,会将消息存放到系统消息队列。 系统会根据存放的消息,找到对应程序的消息队列。 (操作系统会根据消息的目标窗口句柄(hwnd),将消息从系统消息队列分发到相应的线程消息队列。每个GUI线程都有一个独立的消息队列,用于存储和处理该线程创建的窗口的消息)
  3. 将消息投递到程序的消息队列中。

根据消息和消息队列之间使用关系,将消息分成两类:

  • 队列消息:消息的发送和获取,都是通过消息队列完成。
    消息发送后,首先放入系统队列,再由系统转发到进程队列,然后通过消息循环,从队列当中获取。
    GetMessage:从队列中获取消息
    PostMessage:将消息投递到消息队列
    常见的队列消息:WM_PAINT、键盘、鼠标、定时器
    WM_QUIT消息是极少数必须进队列的消息,否则程序无法结束进程。

  • 非队列消息:消息的发送和获取,是直接调用消息的窗口处理完成。
    消息发送后,首先查找消息接收窗口的窗口处理函数,直接调用处理函数,完成消息。
    SendMessage:直接调用消息发送给窗口的处理函数,并等候处理结果。
    常见的非队列消息:WM_CREATE、WM_SIZE等

消息本质上没有队列消息和非队列消息之分,我们想让它进队列就进队列,想让它不进队列就不进队列,只有极少数的消息才必须进队列或者必须不进队列。

深谈GetMessage原理

  1. 在程序(线程)消息队列查找消息,如果队列有消息,检查消息是否满足指定条件(HWND,ID范围),不满足条件就不会取出消息,否则从队列取出消息返回。
  2. 如果程序(线程)消息队列没有消息,向系统消息队列获取属于本程序的消息。如果系统队列的当前消息属于本程序,系统会将消息转发到程序消息队列中。
  3. 如果系统消息队列也没有消息,检查当前进程的所有窗口的需要重新绘制的区域,如果发现有需要绘制的区域,产生WM_PAINT消息丢到系统队列,系统将该消息分发给程序的消息队列,程序的GetMessage取得消息返回处理。
  4. 如果没有重新绘制区域,检查定时器如果有到时的定时器:,产生WM_TIMER,返回处理执行。
  5. 如果没有到时的定时器,整理程序的资源、内存等等。
  6. GetMessage会继续等候下一条消息,阻塞。如果是PeekMessage会直接返回FALSE,交出程序的控制权。

注意:GetMessage如果获取到是WM_QUIT,函数会返回FALSE。

WM_PAINT消息

  • 产生时间:当窗口需要绘制时,或GetMessage无事可做时。

需要绘制是指:

  1. 窗口首次创建时:当窗口第一次显示时,需要绘制初始内容。
  2. 窗口大小改变时:当用户调整窗口大小时,需要重新绘制窗口内容。
  3. 窗口从被覆盖状态变为可见时:当窗口从其他窗口的覆盖下变为可见时,需要重绘被覆盖的部分。
  • 附带信息:
    wParam:0
    lParam:0
  • 专职用法:用于绘图。

窗口首次显示时,这个绘制窗口的消息时是由ShowWindow发出的
在这里插入图片描述
当用户调整窗口大小时,需要重新绘制窗口内容
在这里插入图片描述

既然讲到了绘图消息,就简单绘图看看

InvalidateRect函数是Windows编程中的一个重要函数,用于标记窗口的某个区域为“无效”,从而触发重新绘制该区域。

BOOL InvalidateRect(
  [in] HWND hWnd,	//窗口句柄
  [in] const RECT *lpRect,	//区域的矩形坐标
  [in] BOOL bErase		//重绘前是否先擦除
);

返回值:
如果函数成功,返回值为非零值;如果函数失败,返回值为零。
在这里插入图片描述
消息处理步骤:
1.开始绘图

HDC BeginPaint(
	HWND hwnd, //绘图窗口
	LPPAINTSTRUCT lpPaint //绘图参数的BUFF
	);	//返回绘图设备句柄HD

2.正式绘图
3.结束绘图

BOOL EndPaint(
	HWND hWnd, //绘图窗口
	CONST PAINTSTRUCT *lpPaint	//绘图参数的指针BeginPaint返回

在这里插入图片描述

  • 32
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦里捡到一只猫丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值