Windows消息队列学习笔记

                       

1.windows消息和消息结构

一条消息是作为一个结构传递给应用程序的,这个结构中,包含了消息号,消息的类型,字参数和长字参数等信息。结构定义如下:

typedef struct tagMSG {  HWND hwnd;  UINT message;  WPARAM wParam;  LPARAM lParam;  DWORD time;  POINT pt; } MSG;
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 第一个成员变量hwnd表示消息所属的窗口。在Windows程序中,用HWND类型的变量来标识窗口。
  • 第二个成员变量message指定了消息的标识符。在Windows中,消息是由一个数值来表示的,不同的消息对应不同的数值。但是由于数值不便于记忆,所以Windows将消息对应的数值定义为WM_XXX宏(WM是Window Message的缩写)的形式,XXX对应某种消息的英文拼写的大写形式。例如,鼠标左键按下消息是WM_LBUTTONDOWN,键盘按下消息是WM_KEYDOWN,字符消息是WM_CHAR,等等。在程序中我们通常都是以WM_XXX宏的形式来使用消息的。
       提示:如果想知道WM_XXX消息对应的具体数值,可以在Visual C++开发环境中选中WM_XXX,然后单击鼠标右键,在弹出菜单中选择goto definition,即可看到该宏的具体定义。跟踪或查看某个变量的定义,都可以使用这个方法。
  • 第三、第四个成员变量wParam和lParam,用于指定消息的附加信息。例如,当我们收到一个字符消息的时候,message成员变量的值就是WM_CHAR,但用户到底输入的是什么字符,那么就由wParam和lParam来说明。wParam、lParam表示的信息随消息的不同而不同。如果想知道这两个成员变量具体表示的信息,可以在MSDN中关于某个具体消息的说明文档查看到。读者可以在VC++的开发环境中通过goto definition查看一下WPARAM和LPARAM这两种类型的定义,可以发现这两种类型实际上就是unsigned int和long。
  • 最后两个变量分别表示消息投递到消息队列中的时间和鼠标的当前位置。

2.Windows消息类别

这里写图片描述
 当调用此函数时,参数flags将要检查的消息类型告诉函数,返回时,当前消息类型在返回值得高字节中,而低字节指出已经添加到的队列中。

5.提取消息

可以通过GetMessage函数从消息队列中提取一个消息。GetMessage函数的原型如下:

GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax);
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

参数说明:
lpMsg:指向MSG结构的指针,该结构从线程的消息队列里接收消息信息。
hWnd:取得其消息的窗口的句柄。当其值取NULL时,GetMessage为任何属于调用线程的窗口检索消    息,线程消息通过PostThreadMessage寄送给调用线程。
wMsgFilterMin: 要获取消息的最小值,通产设为0。
wMsgFilterMax:要获取消息的最大值,若wMsgFilterMin、wMsgFilterMax均为0,则接受所有消息。
GetMessage  返回 TRUE 的条件是有消息且该消息不为WM_QUIT ;返回 FALSE 的条件是有消息且该消息  为   WM_QUIT  在没有消息的时候等待消息,cpu当然低阻塞。
关于消息的深入分析,可以看这个博客。这个也推荐看看


在提取消息时,系统必须检查队列状态,下图给出消息提取过程线:
这里写图片描述
(1)如果QS_SENDMESSAGE标志位被设置,系统向相应的窗口过程发送消息。GetMessage函数在窗口过程处理完消息后不返回,要等待其他要处理的消息。
(2)如果消息再消息登记队列中,GetMessage函数填充MSG结构,并返回,这时消息循环通常调用DispatchMessage函数,让窗口过程来处理消息。
(3)如果QS_QIUT标志被设置,GetMessage函数返回一个WM_QIUT消息,并复位QS_QIUT标致。
(4)如果消息再虚拟输入队列,GetMessage函数返回硬件输入消息。
(5)如果QS_TIMER标致被设置,GetMessage函数返回一个WM_TIMER消息。
(6)虽然称为消息队列,但队列中的消息并非总是先进先出。例如只要消息队列中存在WM_QIUT,就会先取出WM_QIUT,导致程序借宿。而只有在没有其它消息时WM_PAINT和WM_TIMER才会被取出。若有多个WM_PAINT或者WM_TIMER,则可能会被合并为一个。

最后用一个简单的图来总结一下流程:
这里写图片描述
由上图可知,基于消息驱动机制设计Windows应用程序时,程序的基本流程交由Windows去处理。Windows掌握着一定的主动权,全心全意为“接受到的消息找到对应的处理函数”提供服务,而用户只需要集中精力做自己的事情,如编写自己的窗口函数等。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值