Windows系统的消息机制
1)Add the window to the clipboard viewer chain.
通过SetClipboardViewer()传入窗口句柄,所有监视剪贴板的窗口句柄会组成一个链表(后来者靠前)。这样当剪贴板内容发生变化时,Windows系统给这些窗口发生消息。剪贴板是系统的一个功能。每个系统功能都有一个消息链。用户程序想要使用某个系统功能,首先是把自己的程序窗口注册到指定功能的消息链上。如果把一个系统功能理解一个设备,就象Windows对文件或者设备都用处理函数。系统中的每个设备都有自己相应的功能。每一个系统的行为都要告诉给需要这个设备的程序。谁需要知道这个知道的行为呢?想要知道这个设备当前行为或者状态的程序容器就要先将自己登记到这个设备的消息链表中。
每个设备只给已经登记在自己的消息链表中的程序窗口发送消息,表明设备当前的状态或者行为。消息只发给自己消息链中的程序,这个很好理解。把自身行为状态的消息发给不关心这个设备的程序窗口,显然没有任何的意义。从这里可以知道。Windows消息必然有两种,一种是发给指定对象,一种是发给全体所有。从用户的角度来说,就是发给所有需要的用户,或者发给全部的用户。
2)Remove the window from the clipboard viewer chain before itis destroyed.
首先是登记,将用户的程序窗口登记到某个功能或者设备的消息链表中。与登记对应的操作就是注销。程序窗口已经不需要了解设备或者功能的行为状态时,就要将自己从设备的消息链中删除。与登记过程SetClipboardViewer()对应的注销过程ChangeClipboardChain()。需要了解某个系统功能或者设备的时候,就要将自己的程序窗口登记到设备的消息链中。不再需要知道设备的行为状态时,就要从设备的消息链中把自己的程序窗口删除掉。
3)互动
为什么要登记?因为想要了解系统某个功能或者设备的行为状态。为什么要注销,因为不再关心指定设备或者某个系统功能的行为状态。在登记与注销的过程之间也就是响应。登记是为了掌握系统设备的某个状态或者行为,并在自己的程序窗口对其做出反映。也就是说当系统设备达到某个状态时,用户的程序窗口要有一些行为或者动作与之发生互动。实际上对于消息的发送与接收,就是发送者与接收者之间的互动。首先是彼此建立联系,然后在某一个特定的时间或者行为或者状态下进行交流,最后结束联系恢复到初始的状态。这样说来初始的状态是没有联系的吗?也不是。初始的状态并非完全的没有联系。
所谓初始的状态是具有联系机制,也即消息发送与接收,消息链的登记与注销,这些做为联系的机制或者方法或者原则已经建立起来了。做为用户的程序窗口什么时候使用这些机制实现具体的功能,这就要由用户自身来决定。不同的程序开发环境必然提供了不同的方法与系统的消息互动。不过,做为编程环境会有万千的变化,做为系统确只有一定之规。
4)消息链
用户的程序窗口在将自身登记到消息链中时,是不需要关注消息链的结构变化。这个过程是由系统来完成。问题在于当用户的程序窗口从消息链中退出的时候。每一个程序窗口从消息链退出的时候,消息链的结构都要发生变化。这个时候维护消息链的工作就要有谁来完成呢?一方面是系统自己维护消息链的增减变化,一方面由用户的程序窗口维护消息链的退出行为。那么维护消息链的工作究竟是由系统来完成,还是由用户自己的程序窗口来完成?具体的系统功能或者设备,提供的消息与服务都是不同的,这就要根据实际情况具体的分析。
//以下内容在C++Builder编程环境下可用
1 class TForm1 : public TForm
2 {
3 public: // User declarations
5 HWND NextViewerHandle;
6 void __fastcall OnWMDrawClipboard(TMessage &Msg);
7 void __fastcall OnWMChagecbchain(TMessage &Msg);
8 BEGIN_MESSAGE_MAP
9 VCL_MESSAGE_HANDLER(WM_DRAWCLIPBOARD,TMessage,OnWMDrawClipboard);
10 VCL_MESSAGE_HANDLER(WM_CHANGECBCHAIN,TMessage,OnWMChagecbchain);
11 END_MESSAGE_MAP(TForm)
12 }
13
14 //1)登记消息链
15 void __fastcall TForm1::FormCreate(TObject *Sender)
16 {
17 NextViewerHandle = SetClipboardViewer(Handle);
18 }
19 //2)注销消息链
20 void __fastcall TForm1::FormDestroy(TObject *Sender)
21 {
22 ChangeClipboardChain (Handle, NextViewerHandle);
23 }
24 //3)消息处理
25 void __fastcall TForm1::OnWMDrawClipboard(TMessage &Msg)
26 {
27 if(NextViewerHandle != NULL )
28 {
29 SendMessage(NextViewerHandle,Msg.Msg,0,0);
30 }
31 //{写入用户自己的代码}
32 }
33
//4)维护消息链的结构
34 void __fastcall TForm1::OnWMChagecbchain(TMessage &Msg)
35 {
36 if((HWND) Msg.WParam == NextViewerHandle)
37 {
38 NextViewerHandle = (HWND)Msg.LParam;
39 }
40 else if(NextViewerHandle != NULL)
41 {
42 SendMessage(NextViewerHandle, Msg.Msg, Msg.WParam, Msg.LParam);
43 }
44 }
Windows系统的消息机制的更多相关文章
- Windows程序设计2(消息机制、菜单)
一 .小记; PostQuitMessage(0); 产生WM_QUIT消息给进程队列,且立即返回,同时使得消息循环退出,使得进程终止.(其实它通过PostMessage(hWnd,WM_QUIT,0 ...
- Windows消息机制(转)1
Windows的应用程序一般包含窗口(Window),它主要为用户提供一种可视化的交互方式,窗口是总是在某个线程(Thread)内创建的.Windows系统通过消息机制来管理交互,消息(Message ...
- 收藏:Windows消息机制
百度百科介绍的windows消息机制也不错:http://baike.baidu.com/view/672379.htm Windows的应用程序一般包含窗口(Window),它主要为用户提供一种可视 ...
- 深入Delphi -- Windows 消息机制
http://www.txsz.net/xs/delphi/3/Windows%20%E6%B6%88%E6%81%AF%E6%9C%BA%E5%88%B6.htm Windows 消息机制 by m ...
- windows消息机制与实例
windows发送窗口消息 所需工具:spy++,visual studio 2017,c#语言 技术路线:首先通过spy++获得所要操纵的窗口的句柄,函数的原型声明为: [DllImport(&qu ...
- Windows 消息机制浅析
1. Windows 的历史 中国人喜欢以史为鉴,而事实也确实是,如果你能知道一件事情的来龙去脉,往往可以更容易地理解事物为什么会表现为当前这样的现状.所以,我的介绍性开场白通常会以一段历 ...
- Windows 消息机制详解
总的来说: MSG包括: 窗口句柄,指示MSG发送的目的窗口 消息标识 lPARAM.wParam 发送时间 发送时的鼠标位置 关于消息队列: Windows系统有一个系统消息队列 每个线程都有一 ...
- java:从消息机制谈到观察者模式
从简单的例子开始 同样,我们还是先看一个简单例子:创建一个窗口实现加法的计算功能.其效果如下: 图1: 加法计算 Calculator.java: import javax.swing.*; impo ...
- Windows内核读书笔记——Windows异常分发处理机制
本篇读书笔记主要参考自<深入解析Windows操作系统>和<软件调试>这两本书. IDT是处理异常,实现操作系统与CPU的交互的关口. 系统在初始化阶段会去填写这个结构. ID ...
随机推荐
- delphi char数组、string和Pchar的相互转换
因为要调用windows的api或者给vc++写接口,很多地方都要用到pchar,现在将char数组.string和pchar之间的相互转换都列出来,都是网上找的资料,我总结一下,先直接上代码,再讲原 ...
- flutter 安装过程遇到的坑
Flutter是一个移动应用程序的软件开发工具包(SDK),用一个代码库构建高性能.高保真的iOS和Android应用程序.目标是使开发人员能够为Android和iOS提供自然的高质量的应用,在滚动行 ...
- C#6.0语言规范(十三) 接口
接口定义合同.实现接口的类或结构必须遵守其合同.接口可以从多个基接口继承,并且类或结构可以实现多个接口. 接口可以包含方法,属性,事件和索引器.接口本身不为它定义的成员提供实现.接口仅指定必须由实现接 ...
- Swift 里 Set(一)辅助类型
_UnsafeBitset  是一个固定大小的 bitmap,用来确定指定位置是否有元素存在. HashTable  具体的 hash 碰撞算法在HashTable里实现,目前使用的是简单的开放地 ...
- ProxySQL 部署 Single Writer Failover 读写分离 (PXC)
主机信息: Proxysql: 如果你忽略了ProxySQL会报告主机组的变化,我建议把它设置为0,除非你试图调试"某些东西",否则你的日志将很快变得巨大.UPDATE globa ...
- vue教程2-05 v-for循环 重复数据无法添加问题 加track-by='索引'
vue教程2-05 v-for循环 重复数据无法添加问题 加track-by='索引' 解决问题的代码示例: <!DOCTYPE html> <html lang="en ...
- Grape简介
什么是Grape Grape是Ruby中的一个类REST API框架,被设计用于运行在Rack上或弥补已有的web应用框架(比如Rails或者Sinatra),Grape提供了一个简单的DSL用于方便 ...
- vue框架之自定义组件中使用v-model
通常 vue在html常见表单空间支持v-model双向绑定例如 <input v-model="message" placeholder="edit me&quo ...
- MYSQL中常用的强制性操作(例如强制索引)
mysql常用的hint 对于经常使用oracle的朋友可能知道,oracle的hint功能种类很多,对于优化sql语句提供了很多方法.同样,在mysql里,也有类似的hint功能.下面介绍一些常用的 ...
- 从Java进程里dump出类的字节码文件
想要查看一些被增强过的类的字节码,或者一些AOP框架的生成类,就需要dump出运行时的Java进程里的字节码. 从运行的java进程里dump出运行中的类的class文件的方法: 用agent att ...