Windows 消息处理机制与事件驱动

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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也会依次做重绘的工作。

相关文档
最新文档