Windows 消息处理机制与事件驱动
windows消息机制的工作原理

windows消息机制的工作原理Windows消息机制是一种用于不同进程间进行通信的机制,Windows操作系统以消息队列为基础,将消息作为一种最基本的通信单元进行传输。
在这个机制下,进程之间可以通过发送和接收消息来进行通信。
Windows消息机制的工作原理如下:1. 消息队列的创建:每个进程都有自己的消息队列,用于存储接收到的消息。
当进程初始化时,系统会为该进程创建一个消息队列,并为之分配一个唯一的标识符。
2. 消息的发送:当一个进程需要向其他进程发送消息时,它首先需要明确消息的发送目标。
在Windows中,每个进程都有一个唯一的标识符(句柄),可以用来标识其他进程。
发送消息的进程根据目标进程的标识符,将消息发送到目标进程的消息队列。
3. 消息的接收:当一个进程接收到消息时,它需要从自己的消息队列中读取消息。
Windows提供了一种机制,使得进程可以通过消息循环来接收和处理消息。
消息循环是一个无限循环,负责从消息队列中读取消息,并将消息分发给相应的处理函数。
4. 消息的处理:一旦消息被分发给相应的处理函数,进程就可以根据消息的类型和附加数据来进行相应的处理。
处理函数可以修改进程中的状态,调用相应的函数,或者发送其他消息。
5. 消息的传递:在发送和接收消息的过程中,消息并不是实时传输的。
当一个进程发送消息时,消息并不会立即发送给目标进程,而是先存储在发送进程的消息队列中。
接收进程通过消息循环来读取消息,也是间断性的进行读取。
因此,消息的传递是一种异步的过程。
6. 消息的优先级:Windows中的消息有不同的优先级,系统会根据消息的优先级来确定消息的处理顺序。
一般情况下,系统会优先处理高优先级的消息,然后才会处理低优先级的消息。
7. 消息的同步和异步:在发送消息的过程中,Windows提供了两种方式:同步方式和异步方式。
同步方式下,发送消息的进程会等待接收进程对消息的处理完成,然后才会继续执行。
异步方式下,发送消息的进程不需要等待接收进程的处理结果,可以立即继续执行。
MFC程序设计

例2 应用程序窗口示例,说明创建Windows 窗口的方法和过程。例3_1
MFC概述
1. 目前的MFC版本中包含了100多个类,不同的类 实现不同的功能。MFC同时还是一个应用程序框 架,它封装了一个程序操作的每一个方面。程序 员通过定义MFC类的对象并通过调用对象的成员 函数来实现相应的功能,而很少直接调用 Windows API函数。 2. MFC中的类:CObject(根类)、非CObject派生 类。
删除编辑框中当前选定 的内容 将剪贴板内容粘贴到编 辑框中光标所在位置 撤消对编辑框的最后一 次操作 将ch中的内容替换编辑 框中选定的内容
m_e.Cut();
M_e.Clear(); M_e.Paste(); M_e.Undo(); Char ch[80]=“abcd” M_e. ReplaceSel(ch);
框架、单选按钮和复选框
• 框架group box:使用它把一组相关的控件框起来, 达到标识一组的控件的作用,不要连接变量,也不要 处理函数。 • 单选按钮radio button:只能选一组中的一项 1.设计要求:必须一个接一个地放进对话框中,中间 不能插入其它控件,且一个组的第一个按钮要选中 “Group”属性,只能对第一个按钮连接变量。 2.重要属性: (ID) 每个按钮都有一个缺省ID,如 IDC_RADIO1,可以重新设置。(标题) 即按钮右 边显示的文本标题。(Group) 一组中第一个按钮 选中该属性。
3.消息:BN_CLICKED 4.重要函数: (1)设定单选按钮选中状态 void CheckRadioButton(int nIDFirstButton, int nIDLastButton, int nIDCheckButton); nIDFirstButton:一组中第一个单选按钮的ID; nIDLastButton:一组中最后一个单选按钮的ID; nIDCheckButton:为初始时设置为选中的那个单选按钮 的ID (2)判定单选按钮是否被选定 形式:UINT IsDlgButtonChecked(int nIDButton); 如果ID为nIDButton的按钮被选定,则该函数的返回值为 true,否则为false。
windows程序消息机制(Winform界面更新有关)

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消息处理机制与事件驱动

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系统中鼠标消息的处理过程。
一、鼠标消息的触发在Windows系统中,鼠标消息的触发是由用户对鼠标的操作所引起的。
比如,当用户点击鼠标左键、右键或滚轮时,系统会通过硬件设备捕捉到对应的鼠标消息,并将其发送给操作系统。
二、鼠标消息的处理流程1. 消息捕捉:当用户操作鼠标时,硬件设备会将对应的消息传递给操作系统。
操作系统会通过相应的驱动程序对鼠标消息进行捕捉。
2. 消息分发:操作系统会将捕捉到的鼠标消息分发给当前活动的窗口。
如果用户操作的是桌面或任务栏等系统级界面,那么鼠标消息将由相应的系统进程进行处理。
3. 消息处理:窗口接收到鼠标消息后,会根据消息的具体类型进行相应的处理。
常见的鼠标消息类型包括鼠标移动、鼠标点击、鼠标释放等。
4. 消息响应:窗口在处理完鼠标消息后,会根据需要执行相应的操作或者触发相应的事件。
比如,当用户点击鼠标左键时,窗口可能会执行某个按钮的点击事件。
5. 消息传递:在消息响应过程中,窗口可能需要将鼠标消息传递给其他窗口进行处理。
这个过程通过消息传递机制来实现,比如通过SendMessage函数将消息传递给指定的窗口。
6. 消息绘制:在消息处理过程中,窗口可能需要进行界面的绘制操作,以反馈给用户。
比如,当用户在窗口上移动鼠标时,窗口可能需要更新鼠标所在位置的显示状态。
7. 消息返回:在消息处理完毕后,窗口会返回消息处理结果给操作系统。
操作系统可以根据返回结果进行相应的处理,比如更新鼠标光标的位置。
通过以上的处理流程,Windows系统能够有效地响应用户对鼠标的操作,并进行相应的处理。
这种鼠标消息的触发和处理机制,为用户提供了便捷的操作体验,使得人机交互更加顺畅。
深入分析Windows消息机制

维护 大 多 数 可视 对 象 的 句 柄( 口、 话 框 、 钮 、 辑 框 窗 对 按 编
等) 。句 柄 决 定 消 息 被 发 送 到 哪 个 窗 口 。
() 1 标准 消息 : 了 WM OMMAND, 除 C 所有 的 以 WM 开
头 的消 息都是标 准消 息 。如 窗 口、 鼠标 移动 、 口大 小改变 窗
() 2 命令 消息 : 自于 菜单 、 来 加速键 、 具栏按钮 的消 息, 工 这类 消息都 以 WM O C MMA ND形 式呈现 。 (1 3 通知 消息 : 由控件 产生 的消 息 。 按键和 鼠标 的单击 列 表框 都会产 生这 类消 息[ 这 类消 息 的 目的是 为 了向父 窗 口 4 ] , ( 常 是 对 话 框 ) 通 知 事 件 的 发 生 , 它 也 是 以 WM 通 C MMA O ND形 式呈现 的。 () 4 用户 白定义 的消息 。 2 2 消息结构 . 在 Wid ws n o 程序 中 ,消息本 身是作 为一个 记 录传递 给 应用 程序 的 , 个记 录 中包含 了消 息 的类 型 以及其 它信 息 , 这 由 MS G结 构体表示 。MS G结构体 的定义如 下 :
事件驱 动意 味着 操作系 统 的每一 部分 之 间 以及 操作 系统 与
在 MS G结构 中, 息是 由一个 消息 名称( N 1 两个 消 uI T 和 参数( AR M, P R WP A L A AM) 组成 。当用户进 行 了输入 或者窗 口的状态 发生改 变时 , 系统都会 发送消息 到某一个 窗 口。例 如, 当菜单 点中之后会 有 WM O C MMA D消息发送 。 中, N 其 WP A 的高字 节( WO D( aa ) AR M HI R wP r m)是命令 的 I 号 , D 是 菜单 I D。同时 , 用户 能定义 自己的消息名称 , 也能利用 自定 义 消息来 发送通知和 传送数据 。
C#事件(event)解析

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中,应⽤程序都包含⼀个消息循环。
该消息循环持续反复检测消息队列,查看是否有⽤户事件消息,这些⽤户事件消息包括⿏标移动、单击、双击、键盘操作和计时器到达等。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
【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也会依次做重绘的工作。