windows消息处理机制详解

        消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。消息本身是作为一个记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息。例如,对单击鼠标所产生的消息来说,这个记录(结构体)中包含了单击鼠标的消息号(WM_LBUTTONDOWN)、单击鼠标时的坐标(由X,Y值连接而成的一个32位整数)。这个记录类型叫做MSG。

typedef struct tagMSG
    {
    HWND hwnd;/ /窗口句柄
    UINT message;//消息常量标识符
    WPARAM wParam;// 16位消息的特定附加信息
    LPARAM lParam;// 32位消息的特定附加信息
    DWORD time;/ /消息创建时的时间
    POINT pt;/ /消息创建时的鼠标位置
    }  MSG;

typedef struct tagPOINT
    {
    LONG x;
    LONG y;
    }  POINT;

 

hwnd
32位的窗口句柄。窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。
message
用于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也可以是自定义的常量。
wParam
通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。
lParam
通常是一个指向内存中数据的指针。
由于WParam、lParam和Pointer都是32位的,即等同于DWORD。因此,它们之间可以相互转换。
 
Windows的消息系统是由3个部分组成的:
 
·消息队列。Windows能够为所有的应用程序维护一个消息队列。应用程序必须从消息队列中获取
消息,然后分派给某个窗口。
 
·消息循环。通过这个循环机制 应用程序消息队列中检索消息,再把它分派给适当的窗口,然
后继续从 消息队列中检索下一条消息,再分派给适当的窗口,依次进行。
 
· 窗口过程。每个窗口都有一个窗口过程来接收传递给窗口的消息,它的任务就是获取消息然后
响应它。窗口过程是一个 回调函数;处理了一个消息后,它通常要返回一个值给Windows。
 
      注意 回调函数是程序中的一种函数,它是由Windows或外部模块调用的。
一个消息从产生到被一个窗口响应,其中有5个步骤:
1) 系统中发生了某个事件。
2) Windows把这个事件翻译为消息,然后把它放到 消息队列中。
3) 应用程序消息队列中接收到这个消息,把它存放在TMsg记录中。
4) 应用程序把消息传递给一个适当的窗口的窗口过程。
5) 窗口过程响应这个消息并进行处理。
 
       步骤3和4构成了 应用程序消息循环消息循环往往是Windows 应用程序的核心,因为消息循环使一个 应用程序能够响应外部的事件。 消息循环的任务就是从 消息队列中检索消息,然后把消息传递给适当的窗口。如果 消息队列中没有消息,Windows就允许其他 应用程序处理它们的消息。
 
 
       Windows消息控制中心一般是 三层结构,其顶端就是Windows内核。Windows内核维护着一个 消息队列,第二级控制中心从这个消息队列中获取属于自己管辖的消息,后做出处理,有些消息直接处理掉,有些还要发送给下一级 窗体(Window)或控件(Control)。第二级控制中心一般是各Windows 应用程序的Application对象。第三级控制中心就是Windows 窗体对象,每一个窗体都有一个默认的窗体过程,这个过程负责处理各种接收到的消息。
 
Windows 操作系统中包括以下几种消息:
1、标准Windows消息:
这种消息以WM_打头。
2、通知消息
通知消息是针对标准Windows控件的消息。这些控件包括:按钮(Button)、 组合框(ComboBox)、编辑框(TextBox)、列表框(ListBox)、 ListView控件、Treeview控件、 工具条(Toolbar)、 菜单(Menu)等。每种消息以不同的字符串打头。
3、自定义消息
 

消息传送

1、从 消息队列获取消息:
 
可以通过PeekMessage或GetMessage函数从Windows 消息队列中获取消息。Windows保存的 消息队列是以 线程(Thread)来分组的,也就是说每个线程都有自己的消息队列。
 
2、发送消息
 
发送消息到指定 窗体一般通过以下两个函数完成:SendMessage和PostMessage。两个函数的区别在于:PostMessage函数只是向线程 消息队列中添加消息,如果添加成功,则返回True,否则返回False,消息是否被处理,或处理的结果,就不知道了。而SendMessage则有些不同,它并不是把消息加入到队列里,而是直接翻译消息和调用消息处理(线程向自己发送消息才是这样),直到消息处理完成后才返回。所以,如果我们希望发送的消息立即被执行,就应该调用SendMessage。
还有一点,就是SendMessage发送的消息由于不会被加入到 消息队列中(错:线程向其他线程发送消息也是追加到其他线程的发送消息队列的,即使这两个线程在同一个进程也是如此),所以通过PeekMessage或GetMessage是不能获取到由SendMessage发送的消息。
另外,有些消息用PostMessage不会成功,比如wm_settext。所以不是所有的消息都能够用PostMessage的。
还有一些其它的发送消息API函数,如PostThreadMessage, SendMessageCallbackSendMessageTimeoutSendNotifyMessage等。
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值