1、第四章 Windows CE窗口和消息机制,,2,版权,华清远见嵌入式培训中心版权所有; 未经华清远见明确许可,不能为任何目的以任何形式复制或传播此文档的任何部分; 本文档包含的信息如有更改,恕不另行通知; 保留所有权利。,4.1 Windows 程序设计综述,4.1.1 Windows CE程序与桌面Windows程序的联系 Windows CE和桌面版的Windows操作系统(如Windows 2000/Windows xp等)都隶属与微软的操作系统阵营。 开发Windows CE应用程序和开发Windows应用程序的方法是十分类似的,它们有着相同的消息处理机制,有着类似的窗口,资源和控件
2、。 在一些细节上,Windows CE和桌面版的Windows有一些不同。,4.1.2窗口的概念 微软公司推出的操作系统,都以“Windows”来命名的,如Windows98,Windows 2000,Windows xp,Windows CE等。 “Windows”即为窗口的意思,微软公司的操作系统都是基于窗口机制的。 在Windows操作系统中,一个窗口就是屏幕上的一个矩形区域,它接收用户的输入并以文字或图形的形式显示输出内容。,4.1.3创建第一个Windows CE 程序 使用应用程序开发工具Embedded Visual C+进行程序的创建。 创建程序时的类型选择“WCE Appli
3、cation” 。 CPU选择框中选择“Emulator”和“X86”两项 。 程序生成后可以点击“Build”进行编译和下载。,4.2 Windows 编程基础,4.2.1 源代码初步分析 Windows CE程序员在开始编写一个新程序时,总是会复制一个现有的Windows CE程序,或者利用EVC的程序创建向导创建一个基本的程序框架,然后再做相应的修改,而不必亲手编写每一行代码。 在程序代码中,有一个WinMain函数,这时程序的主函数,也是程序的入口点。 还有另外一个函数,名为WndProc,这是窗口消息处理程序。,下面列出了以Hello程序中出现些函数以及对它们的简明描述: l MyR
4、egisterClass为程序窗口注册窗口类别。 l DialogBox 显示对话框。 l CreateWindow 根据窗口类别建立一个窗口。 l ShowWindow 在屏幕上显示窗口。 l UpdateWindow 通知窗口自我更新。 l GetMessage 从消息队列中取得消息。 l TranslateMessage 传送某些键盘消息。 l DispatchMessage 将消息发送给窗口消息处理程序。 l BeginPaint 开始绘制窗口。 l GetClientRect 取得窗口显示区域的大小。 l DrawText 显示字符串。 l EndPaint 结束绘制窗口。 l Po
5、stQuitMessage 在消息队列中插入一个“退出程序”消息。 l DefWindowProc 执行默认的消息处理。,4.2.2大写字母标识符 在程序源代码中,用到了几个大写的标识符,这些标识符是在系统头文件中定义的。 有些标识符含有两个字母或者三个字母的前缀,后面紧跟一个下划线。 程序开发人员一般不用去记忆这些数值常数,它们的形式以及意义可以在EVC的帮助手册中查到。,4.2.3新的数据形态 有些数据形态在头文件中使用typedef或者#define加以定义,最初是为了便于将Windows程序从原来的16位系统上移植到未来的使用32位技术的操作系统上。 有时这些新的数据型态只是为了方便缩
6、写。 WndProc函数返回一个类型为LRESULT的值,该值被定义为一个LONG。 WinMain函数被指定为WINAPI类型,而WndProc函数被指定为CALLBACK类型。 这两个标识符都被定义为_stdcall,表示在Windows CE系统本身和的应用程序之间发生的函数呼叫的呼叫参数传递方式。,4.2.4匈牙利命名法 在进行Windows CE编程时一般使用“匈牙利命名法”的变量命名规则。 变量名以一个或者多个小写字母开始,这些字母表示变量的数据型态。 在命名结构变量时,可以用结构名(或者结构名的一种缩写)的小写作为变量名的前缀,或者用作整个变量名。 匈牙利命名法能够帮助程序开发者
7、及早发现并避免程序中的错误。 由于变量名既描述了变量的作用,又描述了其数据型态,就比较容易避免产生数据型态不合的错误。,4.2.5句柄的意义 句柄在Windows CE中使用非常频繁。 句柄通常是一个32位的整数,代表着一个具体对象。 程序通过调用Windows CE中的函数来取得要控制的对象的句柄。 在其它Windows CE函数中通过使用这个句柄来操作它所代表的对象。,4.2.6 回调函数 回调函数是一个通过函数指针调用的函数。 如果把函数A的指针作为参数传递给另一个函数B,那么在函数B中通过这个指针来调用它所指向的函数A时,函数A就被称作是回调函数。 使用回调函数可以把调用者与被调用者分
8、开。 调用者不关心谁是被调用者,它只需知道存在一个具有某种特定原型、某些限制条件(如返回值为int)的被调用函数。 在Windows CE程序中,回调函数通常和消息紧密联系。,4.3 消息机制,4.3.1 注册与建立窗口 Windows CE程序中建立的每一个窗口都有相关的窗口消息处理程序。 这个窗口消息处理程序是一个函数,它既可以在程序中,也可以在动态链接库中。 Windows CE通过给窗口发送消息来调用窗口消息处理程序。窗口消息处理程序对发送过来的消息进行处理,然后将控制传回给操作系统。 窗口通常是在“窗口类别”的基础上建立的,窗口类别标识了窗口消息处理程序。 多个窗口可以属于同一个窗口
9、类,并使用同一个窗口消息处理程序。 窗口消息处理程序处理给窗口发送消息。 Windows CE程序开始执行后,系统会为该程序建立一个“消息队列”。 这个消息队列用来存放该程序建立的各种不同窗口的消息。 程序中有一小段程序代码,叫做“消息循环”,用来从消息队列中取出消息,并将它们发送给相应的窗口消息处理程序。有些消息可以直接发送给窗口消息处理程序,不用放入消息队列中。,4.3.3消息循环 Windows CE为当前执行的每个Windows CE程序维护一个“消息队列”。 在发生用户输入之后,Windows CE系统会将这个输入事件转换为一个“消息”,并将消息放入程序的消息队列中。 程序通过执行“
10、消息循环”的程序代码从消息队列中取出消息,4.3.4 窗口消息处理 在Hello程序中,窗口消息处理程序是WndProc函数。 窗口消息处理程序可任意命名,只要不和其它函数命名发生冲突。 一个Windows程序可包含多个窗口消息处理程序。 窗口消息处理程序总是和调用RegisterClass时注册的特定窗口类相关联。,4.3.5 队列化消息与非队列化消息 Windows CE中的消息被分为“队列化消息”和“非队列化消息”。 队列化的消息是由Windows CE系统放入程序消息队列中的。在程序的消息循环中,会把这些消息重新传回并发送给窗口消息处理程序。 而非队列化的消息在Windows CE调用窗口时直接送给窗口消息处理程序。 队列化消息基本上是用户输入产生的。 非队列化消息一般是调用特定的Windows CE函数产生。 消息的产生过程比较很复杂,不过大部分是由Windows CE系统负责的,无需用户程序关心。 从窗口消息处理程序的角度来看,消息是以一种有序的、同步的方式产生的。 窗口消息处理程序可以选择性地对它们进行处理,处理消息时,消息处理程序不会被其它消息突然中断。,,18,Q&A,,19,谢谢!,