windows消息处理机制, SendMessage, DispatchMessage

windows消息处理机制是这样的:

首先系统(也就是windows)把来自硬件(鼠标,键盘等消息)和来自应用程序的消息
 放到一个系统消息队列中去.
而应用程序需要有自己的消息队列,也就是线程消息队列,没一个线程有自己的消息队列,对于多线程的应用程序就有和线程数目相等的线程消息队列.
winsows消息队列把得到的消息发送到线程消息队列,
线程消息队列每次取出一条消息发送到指定窗口,不断循环直到程序退出.这个循环就是靠消息环(while(GetMessage()) TranslateMessage();DispatchMessage(); 实现的.GetMessage()只是从线程消息中取出一条消息,而DispatchMessage
则把取出的消息发送到目的窗口.如果收到WM_CLOSE消息则结束循环,发送postqiutmessage(0),处理WM_DESTROY销毁窗口!

 

SendMessage

实现sendmessage发送消息的接收,在消息的接收方,覆写DefWindowProc(),在该方法中即可接收到sendmessage方法发送来的消息。因为sendmessage发送的消息,不再经过消息队列,而是直接发送给指定对象。所以一般的消息响应,包括PreTranslateMessage方法都无法接收到该信息,只能通过覆写DefWindowProc方法,来接收信息。

函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。而和函数PostMessage不同,PostMessage是将一个消息寄送到一个线程的消息队列后就立即返回。

LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam)

hWnd:其窗口程序将接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。Msg:指定被发送的消息。

wParam:指定附加的消息特定信息。

IParam:指定附加的消息特定信息。

返回值:返回值指定消息处理的结果,依赖于所发送的消息。

备注:需要用HWND_BROADCAST通信的应用程序应当使用函数RegisterWindowMessage来为应用程序间的通信取得一个唯一的消息。

如果指定的窗口是由正在调用的线程创建的,则窗口程序立即作为子程序调用。如果指定的窗口是由不同线程创建的,则系统切换到该线程并调用恰当的窗口程序。线程间的消息只有在线程执行消息检索代码时才被处理。发送线程被阻塞直到接收线程处理完消息为止。

Windows CE:Windows CE不支持Windows 桌面平台支持的所有消息。使用SendMesssge之前,要检查发送的消息是否被支持。

速查:Windows NT:3.1及以上版本:Windows:95及以上版本;Windows CE:1.0及以上版本;头文件:winuser.h;输入库:user32.lib;Unicode:在Windows NT环境下以Unicode和ANSI方式实现。

SendMessage函数使用实例

程序控制拉下或收起 组合框的下拉列来。

一般情况下,为了拉下或收起组合框的下拉列表,需要用键盘或鼠标进行操作,而有时我们希望程序运行的某个时刻自动拉出下拉列表(比如在一些演示程序中),为了实现这个目的,我们也只有借助于SendMessage函数,方法是发一个CB_SHOWDROPDOWN(&H14F)消息给组合框。

在发CB_SHOWDROPDOWN消息时,wParam参数决定了是拉下列表(=True时)还是收起列表(=False时),lParam无用(设为0)。

 

DispatchMessage

函数功能:该函数分发一个消息给窗口程序。通常消息从GetMessage函数获得。消息被分发到 回调函数 (过程函数),作用是消息传递给操作系统,然后操作系统去调用我们的回调函数,也就是说我们在 窗体 的过程函数中处理消息

函数原型:LONG DispatchMessage(CONST MSG*lpmsg);

参数:

lpmsg:指向含有消息的MSG结构的 指针

返回值:返回值是窗口程序返回的值。尽管返回值的含义依赖于被调度的消息,但返回值通常被忽略。

备注:MSG结构必须包含有效的消息值。如果参数lpmsg指向一个WM_TIMER消息,并且WM_TIMER消息的参数IParam不为NULL,则调用IParam指向的函数,而不是调用窗口程序。

速查:Windows NT:3.1及以上版本;Windows:95及以上版本;Windows CE:1.0及以上版本;头文件:winuser.h;输入库:user32.lib;Unicode:在Windows NT环境下以Unicode和ANSI方式实现。

头文件:Winuser.h, Windows.h

库文件:User32.lib

 

PeekMessage与GetMessage的对比
相同点:
PeekMessage函数与GetMessage函数都用于查看应用程序消息队列,有消息时将队列中的消息派发出去。

不同点:
无论应用程序消息队列是否有消息,PeekMessage函数都立即返回,程序得以继续执行后面的语句(无消息则执行其它指令,有消息时一般要将消息派发出去,再执行其它

指令)。
GetMessage函数只有在消息对立中有消息时返回,队列中无消息就会一直等,直至下一个消息出现时才返回。在等的这段时间,应用程序不能执行任何指令。

 

(从他们的不同点上来看,PeekMessage函数有点像“乞丐行乞”,有你就施舍点,没有也不强求。GetMessage函数有点像“强盗打劫”,有你得给,没有我就等你什么时

候有了再给,这段时间我什么都不干,我就等你。)

 

PeekMessage和函数GetMessage不一样的是,GetMessage:从系统获取消息,将消息从系统中移除,属于阻塞函数。当系统无消息时,GetMessage会等待下一条消息。而函数PeekMesssge是以查看的方式从系统中获取消息,可以不将消息从系统中移除,是非阻塞函数;当系统无消息时,返回FALSE,继续执行后续代码。

PeekMesssge只得到那些与参数hWnd标识的窗口相联系的消息或被lsChild确定为其子窗口相联系的消息,并且该消息要在由参数wMsgFiterMin和wMsgFiherMax确定的范围内。如果hWnd为NULL,则PeekMessage接收属于当前调用线程的窗口的消息(PeekMessage不接收属于其他线程的窗口的消息)。如果hWnd为-1,PeekMessage只返回hWnd值为NULL的消息,该消息由函数PostThreadMessage寄送。如果wMsgFilterMin和wMsgFilterMax都为零,PeekMessage返回所有可得的消息(即,无范围过滤)。

常数WM_KEYFIRST和WM_KEYLAST可作为过滤值取得所有键盘消息;常数WM_MOUSEFIRST和WM_MOUSELAST可用来接收所有的鼠标消息。

PeekMessage通常不从队列里清除WM_PAINT消息。该消息将保留在 队列 里直到处理完毕。但如果WM_PAINT消息有一个空更新区,PeekMessage将从队列里清除WM_PAINT消息。[1]

Windows CE:有一个NULL更新区的WM_PAINT消息不从队列里清除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值