Windows 消息处理机制与事件驱动
- 格式:doc
- 大小:41.00 KB
- 文档页数:3
windows消息机制的工作原理Windows消息机制是一种用于不同进程间进行通信的机制,Windows操作系统以消息队列为基础,将消息作为一种最基本的通信单元进行传输。
在这个机制下,进程之间可以通过发送和接收消息来进行通信。
Windows消息机制的工作原理如下:1. 消息队列的创建:每个进程都有自己的消息队列,用于存储接收到的消息。
当进程初始化时,系统会为该进程创建一个消息队列,并为之分配一个唯一的标识符。
2. 消息的发送:当一个进程需要向其他进程发送消息时,它首先需要明确消息的发送目标。
在Windows中,每个进程都有一个唯一的标识符(句柄),可以用来标识其他进程。
发送消息的进程根据目标进程的标识符,将消息发送到目标进程的消息队列。
3. 消息的接收:当一个进程接收到消息时,它需要从自己的消息队列中读取消息。
Windows提供了一种机制,使得进程可以通过消息循环来接收和处理消息。
消息循环是一个无限循环,负责从消息队列中读取消息,并将消息分发给相应的处理函数。
4. 消息的处理:一旦消息被分发给相应的处理函数,进程就可以根据消息的类型和附加数据来进行相应的处理。
处理函数可以修改进程中的状态,调用相应的函数,或者发送其他消息。
5. 消息的传递:在发送和接收消息的过程中,消息并不是实时传输的。
当一个进程发送消息时,消息并不会立即发送给目标进程,而是先存储在发送进程的消息队列中。
接收进程通过消息循环来读取消息,也是间断性的进行读取。
因此,消息的传递是一种异步的过程。
6. 消息的优先级:Windows中的消息有不同的优先级,系统会根据消息的优先级来确定消息的处理顺序。
一般情况下,系统会优先处理高优先级的消息,然后才会处理低优先级的消息。
7. 消息的同步和异步:在发送消息的过程中,Windows提供了两种方式:同步方式和异步方式。
同步方式下,发送消息的进程会等待接收进程对消息的处理完成,然后才会继续执行。
异步方式下,发送消息的进程不需要等待接收进程的处理结果,可以立即继续执行。
windows程序消息机制(Winform界⾯更新有关)1. Windows程序消息机制Windows GUI程序是基于消息机制的,有个主线程维护着消息泵。
这个消息泵让windows程序⽣⽣不息。
Windows程序有个消息队列,窗体上的所有消息是这个队列⾥⾯消息的最主要来源。
这⾥的While循环使⽤了GetMessage() 这个⽅法,这是个阻塞⽅法,也就是队列为空时⽅法就会阻塞,从⽽这个While循环停⽌运动,这避免了⼀个程序把cpu⽆缘⽆故的耗尽,让其他程序难以得到响应。
当然在某些需要cpu最⼤限度运动的程序⾥⾯就可以使⽤另外的⽅法,例如某些3d游戏或者及时战略游戏中,⼀般会使⽤PeekMessage()这个⽅法,它不会被windows阻塞,从⽽保证整个游戏的流畅和⽐较⾼的帧速。
(PeekMessage是⼀个Windows API函数。
该函数为⼀个消息检查线程消息队列,并将该消息(如果存在)放于指定的结构。
DispatchMessage功能是发送消息给窗⼝,窗⼝收到消息,执⾏事件)。
这个主线程维护着整个窗体以及上⾯的⼦控件。
当它得到⼀个消息,就会调⽤DispatchMessage()⽅法派遣消息,这会引起对窗体上的窗⼝过程的调⽤。
窗⼝过程⾥⾯当然是程序员提供的窗体数据更新代码和其它代码。
2. dotnet⾥⾯的消息循环public static void Main(string[] args){Form f = new Form();Application.Run(f);}Dotnet窗体程序封装了上述的while循环,这个循环就是通过Application.Run⽅法启动的。
3、线程外操作GUI控件的问题如果从另外⼀个线程操作windows窗体上的控件,就会和主线程产⽣竞争,造成不可预料的结果,甚⾄死锁。
因此windows GUI编程有⼀个规则,就是只能通过创建控件的线程来操作控件的数据,否则就可能产⽣不可预料的结果。
Windows消息处理机制与事件驱动【SunXin.VC++深⼊】1.窗⼝(Windows)和句柄(HANDLE,handle):窗⼝句柄(HWND)图标句柄(HICON)、光标句柄(HCURSOR)和画刷句柄(HBRUSH)2.消息,消息队列,消息循环,消息响应.OS将操作包装成Message.typedef struct MSG {HWND hwnd; //窗⼝句柄,即标⽰消息所属的窗⼝UINT message;//标⽰消息的类别,是⿏标还是键盘等如⿏标左键按下消息是WM_LBUTTONDOWN,键盘按下消息是WM_KEYDOWN,字符消息是WM_CHARWPARAM wParam;//消息的附加信息LPARAM lParam;//消息的附加信息DWORD time;//消息投递到消息队列中的时间POINT pt;//⿏标的当前位置} MSG;.消息队列,每⼀个Windows应⽤程序开始执⾏后,系统都会为该程序创建⼀个消息队列,这个消息队列⽤来存放该程序创建的窗⼝的消息 .进队消息(OS将产⽣的消息放在应⽤程序的消息队列中,让应⽤程序来处理)不进队消息(OS直接调⽤窗⼝的处理过程).Windows应⽤程序的消息处理机制while(GetMessage(&msg,NULL,0,0)){//接收到WM_QUIT消息时,才返回0TranslateMessage(&msg);//对消息进⾏包装处理然后再以消息的形式投放到消息队列DispatchMessage(&msg);//消息回传给操作系统,由操作系统调⽤窗⼝过程函数对消息进⾏处理}(1)操作系统接收到应⽤程序的窗⼝消息,将消息投递到该应⽤程序的消息队列中。
(2)应⽤程序在消息循环中调⽤GetMessage函数从消息队列中取出⼀条条的消息。
取出后,以对消息进⾏⼀些预处理,如放弃对某些消息的响应,或者调⽤TranslateMessage产⽣新的消息(3)应⽤程序调⽤DispatchMessage,将消息回传给操作系统。
windows鼠标消息触发及其处理流程Windows操作系统是目前最常用的个人计算机操作系统之一,它提供了丰富的功能和便捷的用户界面。
鼠标作为计算机的重要输入设备,对于Windows系统而言也起着至关重要的作用。
本文将从鼠标消息触发及其处理流程的角度,为读者详细介绍Windows系统中鼠标消息的处理过程。
一、鼠标消息的触发在Windows系统中,鼠标消息的触发是由用户对鼠标的操作所引起的。
比如,当用户点击鼠标左键、右键或滚轮时,系统会通过硬件设备捕捉到对应的鼠标消息,并将其发送给操作系统。
二、鼠标消息的处理流程1. 消息捕捉:当用户操作鼠标时,硬件设备会将对应的消息传递给操作系统。
操作系统会通过相应的驱动程序对鼠标消息进行捕捉。
2. 消息分发:操作系统会将捕捉到的鼠标消息分发给当前活动的窗口。
如果用户操作的是桌面或任务栏等系统级界面,那么鼠标消息将由相应的系统进程进行处理。
3. 消息处理:窗口接收到鼠标消息后,会根据消息的具体类型进行相应的处理。
常见的鼠标消息类型包括鼠标移动、鼠标点击、鼠标释放等。
4. 消息响应:窗口在处理完鼠标消息后,会根据需要执行相应的操作或者触发相应的事件。
比如,当用户点击鼠标左键时,窗口可能会执行某个按钮的点击事件。
5. 消息传递:在消息响应过程中,窗口可能需要将鼠标消息传递给其他窗口进行处理。
这个过程通过消息传递机制来实现,比如通过SendMessage函数将消息传递给指定的窗口。
6. 消息绘制:在消息处理过程中,窗口可能需要进行界面的绘制操作,以反馈给用户。
比如,当用户在窗口上移动鼠标时,窗口可能需要更新鼠标所在位置的显示状态。
7. 消息返回:在消息处理完毕后,窗口会返回消息处理结果给操作系统。
操作系统可以根据返回结果进行相应的处理,比如更新鼠标光标的位置。
通过以上的处理流程,Windows系统能够有效地响应用户对鼠标的操作,并进行相应的处理。
这种鼠标消息的触发和处理机制,为用户提供了便捷的操作体验,使得人机交互更加顺畅。
C#事件(event)解析C#事件(event)解析事件(event),这个词儿对于初学者来说,往往总是显得有些神秘,不易弄懂。
而这些东西却往往又是编程中常用且非常重要的东西。
大家都知道windows消息处理机制的重要,其实C#事件就是基于windows消息处理机制的,只是封装的更好,让开发者无须知道底层的消息处理机制,就可以开发出强大的基于事件的应用程序来。
先来看看事件编程有哪些好处。
在以往我们编写这类程序中,往往采用等待机制,为了等待某件事情的发生,需要不断地检测某些判断变量,而引入事件编程后,大大简化了这种过程:- 使用事件,可以很方便地确定程序执行顺序。
- 当事件驱动程序等待事件时,它不占用很多资源。
事件驱动程序与过程式程序最大的不同就在于,程序不再不停地检查输入设备,而是呆着不动,等待消息的到来,每个输入的消息会被排进队列,等待程序处理它。
如果没有消息在等待,则程序会把控制交回给操作系统,以运行其他程序。
- 事件简化了编程。
操作系统只是简单地将消息传送给对象,由对象的事件驱动程序确定事件的处理方法。
操作系统不必知道程序的内部工作机制,只是需要知道如何与对象进行对话,也就是如何传递消息。
有了这么多好处,看来我们的确有必要掌握它。
俗话说:“难了不会,会了不难”。
就让我们一步一步开始吧...要讲事件,必然要讲到委托(delegate)。
它们之间的关系可以通过一个浅显的比方来说明,这个比方可能不是十分恰当。
比如你要租一个房屋,这是一个事件,那么委托就是房屋租赁中介,当你把租房子的消息告知中介后,中介就会产生出一套符合你要求的房屋租赁方案来。
再由中介执行这套方案,你便租得了这个房屋,即事件被处理了。
当然你也可以不通过中介,直接找房东,但如果没有互联网等工具,你如何得到谁出租房屋的信息?话题扯远了。
委托(delegate)委托可以理解成为函数指针,不同的是委托是面向对象,而且是类型安全的。
关于委托的理解,可以参考我的另一篇文章《C#委托之个人理解》。
消息机制与事件处理1. 前⾔1.1 什么是消息?要更好地使⽤C++进⾏Windows编程,就需要进⼀步了解其消息机制。
在Windows应⽤程序中,事件驱动是围绕着消息的产⽣和处理展开的,消息是对发⽣的事件的描述信息。
消息通知程序有关事件的发⽣。
⼀条消息包含有消息的名字、标识、消息发⽣时的⼀些参数,以及处理这条消息的函数⼊⼝指针。
每当⽤户进⾏某种操作,⽐如⿏标单击或键盘按键,就会触发相应的事件。
⽽事件是以消息的⽅式通知Windows应⽤程序的。
⼀旦应⽤程序获得某条消息,就根据消息映射表查找相应消息的响应函数的⼊⼝地址,调⽤该函数处理消息,完成⽤户预期的功能。
1.2 在哪⾥产⽣消息?在哪⾥对消息进⾏响应?在Windows操作系统中,应⽤程序主要以窗⼝的形式存在。
窗⼝是⼀个可视的⼈机交互界⾯,⽤来接收各种事件,如⽤户键盘/⿏标事件、外设的请求事件、定时器的请求事件、信号量的请求事件等。
因此,它也就成为应⽤程序控制消息的发送端和接收端。
即Windows应⽤程序是围绕窗⼝进⾏的,窗⼝不仅提供了可视化的应⽤程序的界⾯,也是Windows消息的产⽣和响应的地⽅。
1.3 Windows系统如何实现消息机制?消息的产⽣是由于相应的事件被触发;消息的发送以队列形式进⾏;消息响应遵循⼀定的顺序。
MFC类库为这种消息响应机制提供了完整的处理功能。
MFC类库中的很多类都具有处理相应消息的功能。
在⾯向过程的程序设计⽅式中,对外设,⽐如⿏标、键盘等的控制是通过轮询⽅式进⾏,即分别定时查询这些设备的输⼊请求来完成的。
⽽在Windows环境中,这些控制是通过消息机制完成的。
因此,Windows也被称为“基于事件驱动的、消息机制的”操作系统。
消息机制是Windows能进⾏多任务并发处理的基础,它保证了Windows下同时运⾏的程序能够协同作业。
在Windows中,应⽤程序都包含⼀个消息循环。
该消息循环持续反复检测消息队列,查看是否有⽤户事件消息,这些⽤户事件消息包括⿏标移动、单击、双击、键盘操作和计时器到达等。
用VC++的多态性实现事件驱动的协调控制
雷超;李纯刚
【期刊名称】《中国计算机用户》
【年(卷),期】1996(000)017
【摘要】在Windows程序设计中,消息驱动是其基本特色,消息驱动的协调控制问题在应用程序的规模日益扩大的情形下显得越来越突出。
Windows本身对消息的管理策略相当简单:它将接受来的消息放入系统消息队列,然后将特定的消息发向特定的应用程序队列,或者将特殊消息直接发向特定的窗口,以后对消息的处理由应用程序负责。
一般而言,较大的应用程序对接收到的消息的处理并不是独立的,也就是说。
【总页数】2页(P26-27)
【作者】雷超;李纯刚
【作者单位】西北工业大学;西北工业大学
【正文语种】中文
【中图分类】TP311
【相关文献】
1.基于事件驱动机制的多智能体系统协调控制研究综述 [J], 许文盈;曹进德
2.基于事件驱动的高性能WebSocket服务器的设计与实现 [J], 曹文彬;谭新明;刘备;刘传文
3.一种事件驱动的生物特征识别框架服务的设计与实现 [J], 蒋林轩;余杰;刘晓东;吴庆波;孔金珠
4.基于变更事件驱动的微服务组合平台设计与实现 [J], 王信;刘晓燕;张开琦;王星;严馨
5.基于事件驱动的太湖流域会商与决策系统设计与实现 [J], 许珂;马媛;王超;张健;李谷涵
因版权原因,仅展示原文概要,查看原文内容请购买。
C#Hook前⾔ 在说C# Hook之前,我们先来说说什么是Hook技术。
相信⼤家都接触过外挂,不管是修改游戏客户端的也好,盗取密码的也罢,它们都是如何实现的呢? 实际上,Windows平台是基于事件驱动机制的,整个系统都是通过消息的传递来实现的。
当进程有响应时(包括响应⿏标和键盘事件),则Windows会向应⽤程序发送⼀个消息给应⽤程序的消息队列,应⽤程序进⽽从消息队列中取出消息并发送给相应窗⼝进⾏处理。
⽽Hook则是Windows消息处理机制的⼀个平台,应⽤程序可以在上⾯设置⼦程以监视指定窗⼝的某种消息,⽽且所监视的窗⼝可以是其他进程所创建的。
当消息到达后,在⽬标窗⼝处理函数之前处理它。
钩⼦机制允许应⽤程序截获处理window消息或特定事件。
所以Hook就可以实现在键盘/⿏标响应后,窗⼝处理消息之前,就对此消息进⾏处理,⽐如监听键盘输⼊,⿏标点击坐标等等。
某些盗号⽊马就是Hook了指定的进程,从⽽监听键盘输⼊了什么内容,进⽽盗取账户密码。
C# Hook 我们知道C#是运⾏在.NET平台之上,⽽且是基于CLR动态运⾏的,所以只能操作封装好的函数,且⽆法直接操作内存数据。
⽽且在C#常⽤的功能中,并未封装Hook相关的类与⽅法,所以如果⽤C#实现Hook,必须采⽤调⽤WindowsAPI的⽅式进⾏实现。
WindowsAPI函数属于⾮托管类型的函数,我们在调⽤时必须遵循以下⼏步: 1、查找包含调⽤函数的DLL,如User32.dll,Kernel32.dll等。
2、将该DLL加载到内存中,并注明⼊⼝ 3、将所需参数转化为C#存在的类型,如指针对应Intptr,句柄对应int类型等等 4、调⽤函数 我们本篇需要使⽤的函数有以下⼏个: SetWindowsHookEx ⽤于安装钩⼦ UnhookWindowsHookEx ⽤于卸载钩⼦ CallNextHookEx 执⾏下⼀个钩⼦ 详细API介绍请参考MSDN官⽅声明 接下来在C#中需要⾸先声明此API函数:[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]public static extern int SetWindowsHookEx(int idHook, HookProc lpfn,IntPtr hInstance, int threadId);[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]public static extern bool UnhookWindowsHookEx(int idHook);[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]public static extern int CallNextHookEx(int idHook, int nCode,IntPtr wParam, IntPtr lParam); 声明后即可实现调⽤,SetWindowsHookEx()把⼀个应⽤程序定义的钩⼦⼦程安装到钩⼦链表中,SetWindowsHookEx函数总是在Hook链的开头安装Hook⼦程。
【SunXin.VC++深入】
1.窗口(Windows)和句柄(HANDLE,handle):窗口句柄(HWND)图标句柄(HICON)、光标句柄(HCURSOR)和画刷句柄(HBRUSH)
2.消息,消息队列,消息循环,消息响应
.OS将操作包装成Message
.typedef struct MSG {
HWND hwnd; //窗口句柄,即标示消息所属的窗口
UINT message;//标示消息的类别,是鼠标还是键盘等如鼠标左键按下消息是
//WM_LBUTTONDOWN,键盘按下消息是WM_KEYDOWN,字符消息是WM_CHAR
WPARAM wParam;//消息的附加信息
LPARAM lParam;//消息的附加信息
DWORD time;//消息投递到消息队列中的时间
POINT pt;//鼠标的当前位置
} MSG;
.消息队列,每一个Windows应用程序开始执行后,系统都会为该程序创建一个消息队列,这个消息队列用来存放该程序创建的窗口的消息
.进队消息(OS将产生的消息放在应用程序的消息队列中,让应用程序来处理)
不进队消息(OS直接调用窗口的处理过程)
用 Windows 的话说, 窗口的事件就是系统发送给窗口的消息; 窗口要采取的行动(事件代码)就是窗口的回调函数.
PostMessage函数将消息添加到应用程序的消息队列中去。
应用程序的消息循环会从消息队列中提取登记的该消息,再发送到相应的窗口中。
SendMessage函数可以越过消息队列直接向窗口过程发送。
所以当Windows需要立刻返回值时使用SendMessage,当需要不同的应用程序依次处理消息时使用PostMessage。
而Perform从本质上和SendMessage相似,它们直接向窗口过程发送。
SendMessage、Postmessage函数只需要知道窗口的句柄就可以发送消息,所以它们可以向非Delphi窗体发送一条消息,但而Control.Perform必须知道窗体或控件的实例。
.Windows应用程序的消息处理机制
while(GetMessage(&msg,NULL,0,0)){//接收到WM_QUIT消息时,才返回0
TranslateMessage(&msg);//对消息进行包装处理然后再以消息的形式投放到消息队列
DispatchMessage(&msg);//消息回传给操作系统,由操作系统调用窗口过程函数对消息进行处理 }
(1)操作系统接收到应用程序的窗口消息,将消息投递到该应用程序的消息队列中。
(2)应用程序在消息循环中调用GetMessage函数从消息队列中取出一条条的消息。
取出后,以对消息进行一些预处理,如放弃对某些消息的响应,或者调用TranslateMessage产生新的消息,再以消息的形式投放到消息队列.
(3)应用程序调用DispatchMessage,将消息回传给操作系统。
消息是由MSG结构体对象来表示的,其中就包含了接收消息的窗口的句柄。
因此,DispatchMessage函数总能进行正确的传递。
(4)系统利用WNDCLASS结构体的lpfnWndProc成员保存的窗口过程函数的指针调用窗口过程,对消息进
行处理(即“系统给应用程序发送了消息”)。
.窗口过程函数
lresult callback windowproc(
hwnd hwnd, // 对应消息的窗口句柄
uint umsg, // 消息代码,区别消息的类型
wparam wparam, // 消息代码的附加参数1
lparam lparam // 消息代码的附加参数2
);
【蔡学镛.揭开消息循环的神秘面纱】
简单归纳如下:
消息循环被封装进了 Application 类别的 Run() 静态方法中;Windows Procedure (WndProc())被封装进了 NativeWindow 与 Control 类别中;
个别的消息处理动作被封装进 Control 类别的 OnXyz()(例如 OnPaint())。
我们可以覆盖(override)OnXyz(),来提供我们自己的程序。
也可以利用.NET的事件(event)机制,在 Xyz 事件上,加入我们的事件处理函式(Event Handler)。
C ontrol 类别的 OnXyz() 会主动呼叫 Xyz 事件的处理函式。
请注意,因为 Xyz 的事件处理函式是由 Control 类别的 OnXyz() 方法所呼叫的,所以当你覆写 OnXyz()方法时,不要忘了呼叫 Control 类别的 OnXyz()(除非你有特殊需求),否则 Xyz 事件处理函式将会没有作用。
只要呼叫 base.OnXyz(),就可以呼叫到 Control 类别的 OnXyz() 方法
1. 在 Main() 中,利用 Application.Run() 来将 Form1 窗口显示出来,并进入讯息循环。
程序的执行过程中,Application.Run() 一直未结束。
2. OS 在此 Process 的消息队列内放进一个 WM_PAINT 讯息,好让窗口被显示出来。
3. WM_PAINT 被 Application.Run() 内的消息循环取出来,发派到 WndProc()。
由于多型(Polymorphis m)的因素,此次调用(invoke)到的 WndProc() 是属于Form1 的 WndProc(),也就是上述程序中批注(c
omment)1 的地方,而不是调用到 Control.WndProc()。
4. 在 Form1.WndProc() 的最后,有调用 base.WndProc(),这实际上调用到 Control.WndProc()。
5. Control.WndProc() 从 Message 参数中得知此讯息是 WM_PAINT,于是调用 OnPaint()。
由于多型的因素,此次调用到的 OnPaint() 是属于 Form1 的 OnPaint(),也就是上述程序中批注 2 的地方,而不是调用到 Control.OnPaint()。
6. 在 Form1.OnPaint() 的最后,有调用 base.OnPaint(),这实际上调用到 Control.OnPaint()。
7. 我们曾经在 Form1 的建构式(constructor)中将 Form1_Paint() 与 Form1_Paint2() 登记成为 Pai nt 事件处理函式(Event Handler)。
Control.OnPaint() 会去依序去呼叫这两个函式,也就是上述程序中批注 3 与 4 的地方。
【.NET Windows Message】
1.Control--Button,Form……
protect vitrual WndProcess(ref Message);
调用private Wm_(ref Message);//具体某类消息
调用Oprotect virtual On_xx(EventArg e);//触发相关事件
2.解释事件冒泡:比如键盘消息可先由Form来处理,然后交由相关的Control来处理
3.解释FormPaint:窗口的移动,最小化,最大话都会引起窗口内容的重新Paint,OS产生一个相关消息发给应用程序的消息队列,应用程序得到并处理消息时先是Form依次经过Wn_Process,Wn_..,On_Paint,Fo rm_Paint,之后Form中的每一个Control也会依次做重绘的工作。