购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

4.2 消息循环和事件响应

4.2.1 消息循环

军师,这个“消息”是怎么回事啊?

Windows应用程序是基于消息的程序设计模式,使用事件驱动编程模型,如图4.1所示。应用程序通过处理操作系统发送来的消息来响应事件。Windows程序的入口点是WinMain()函数,该函数一般只用于创建窗口,大多数操作是在其他函数中完成的,例如,利用DlgProc()函数处理发送给窗口的消息,使用WinMain()函数创建该窗口并进入消息循环,即获取消息或将其调度至窗口过程。消息被检查之前在消息队列中等待。

图4.1

哦,俺稍微有些明白了,大体的意思是说如果UI内有什么变化或者是事件发生,这时系统就会通过消息告诉应用程序具体发生了什么事情,是这个意思吧?

没错,大体就是这个意思。结合你刚才的理解,再看看下面这张图你会更加明白。

1.消息概述

WM_QUIT消息通知应用程序结束,该消息在消息队列中被检索到之后,消息循环将停止。在消息循环停止后,WinMain()函数跳出,应用程序结束。窗口过程一般要调用其他函数来帮助处理接收到的消息。应用程序可以调用自己的函数,也可以调用Windows提供的API函数。窗口过程一般作为一个较大函数实现(如DlgProc()函数),包含一个switch/case结构语句,为每个消息提供一个选项。处理特定消息的程序代码被称为消息处理程序。应用程序没有处理的消息被传递到名为DefWindowProc()的API函数,该函数对未处理的消息提供默认响应。

2.消息结构

其实消息自身就是一段数据,这段数据有着特殊的结构。

Windows系统为记录消息信息,定义了一个消息结构MSG:

功能: 用于记录Windows系统消息信息的结构。

参数:

hWnd是一个窗口句柄,表示消息所属的窗口。通过这个句柄,操作系统可以将消息分派到正确的窗口中。

message表示消息标识符,确定具体是哪个消息。

wParam表示消息的附加信息,其含义依赖于具体的消息。

lParam,类似于wParam类型,表示消息的附加信息,其含义依赖于具体的消息。

time表示消息被放入消息队列中的时间。

pt表示消息被放入消息队列时的鼠标位置(以屏幕坐标表示)。

3.消息类型

军师,您一直说“消息”、“消息”的,可是到底有哪些消息啊?

Windows系统将消息分为系统预定义的消息和用户自定义的消息两大类。系统消息由前缀和后缀两部分组成,中间加一条下画线。前缀表示处理该消息的窗口类型,后缀描述消息的内容。这些系统消息有很多,一些常用的消息如表4.1所示。需要注意的是,消息在应用程序的运行中是非常重要的。

表4.1

消息以调用一个窗口的窗口过程函数的形式来表明自己的存在,所以程序每收到一个消息,都会自动调用窗口回调函数。与该调用同时作用的还有4个输入参数:消息所指窗口的句柄、一个消息ID和两个名为wParam和lParam的32位参数。

4.发送消息

军师,程序可以接收消息,是不是也可以向某个窗口发送消息啊?

当然,对话框中的大部分控件在进行操作后,都会发送消息到系统消息队列中,然后被窗口过程函数处理。在代码中有几种发送消息的方法,最常见的是使用SendMessage()和PostMessage()函数。

●SendMessage()函数声明如下:

功能: 该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息并返回。

参数:

hWnd,接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。

Msg指定被发送的消息。

wParam指定附加的消息参数。

lParam指定附加的消息参数。

返回值: 返回值指定消息处理的结果,依赖于所发送的消息。

●PostMessage()函数声明如下:

功能: 该函数将一个消息放入(寄送)到与指定窗口创建的线程相关联的消息队列里,不等待线程处理消息就返回。消息队列里的消息通过调用GetMessage()和PeekMessage()取得。

参数:

hWnd,待接收消息的窗口句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。

Msg指定被发送的消息。

wParam指定附加的消息参数。

lParam指定附加的消息参数。

返回值: 函数执行成功返回非零值,否则返回零值。若想获得更多的错误信息,可调用GetLastError()函数。

5.程序结构

说了这么多,军师你赶紧教给我具体怎么编写代码吧。

Windows应用程序的入口函数是WinMain()。操作系统启动一个程序时,将调用程序的WinMain()函数开始执行代码。当此函数返回时,应用程序也就结束了。此外,处理窗口过程一般作为一个较大的函数(如DlgProc()函数)执行。下面通过一个程序框架说明此类程序的写法。

本章末尾将通过一个例子结合UI设计讲述程序设计的方法。

4.2.2 事件响应

事件是指可以被控件识别的操作,如单击“确定”按钮,选中某个单选按钮或者复选框。每一种控件有自己可以识别的事件,如窗体的加载、单击、双击等。事件分为系统事件和用户事件。系统事件由系统激发,如时间每隔24小时,银行储户的存款日期增加一天。用户事件由用户激发,如用户单击按钮,在文本框中显示特定的文本等。

Windows程序设计是针对事件或消息的,它的执行顺序取决于事件发生的顺序。事件驱动编程方法和死板的操作模式相比,对于编写交互式程序有了极大的改进,如图4.2所示。

图4.2 PEBlCv4JJLhEvd1hFy9r4j80KZdhVidObg2v5WnawBWBQ3SSGNcqeeMHlrwVd3iV

点击中间区域
呼出菜单
上一章
目录
下一章
×