嵌入式Linux下的图形用户界面系统设计
位置。
2. 3. 2消息队列
消息队列是事件系统中的消息的暂存处,它由一个环形先入先出结构的消息数组和一个消息链表组成。消息数组的空间是固定的,一旦被写满,后来的消息只好被丢弃;而消息链表则可以动态扩充大小。在SKY-GUI中,消息数组主要用来存放底层输入设备的事件(如鼠标、键盘、时钟等等),而消息链表主要用来存放优先级更高且不可丢弃的上层事件(窗口事件和显示事件)。
2. 3. 3消息操作接口
SKY-GUI定义了三类消息操作接口:消息发送函数、消息获取函数和事件处理函数。
消息发送函数为输入抽象层和窗口系统提供消息发送接口,包括Post_Msg函数和Send_Msg函数,其作用都是向消息队列发送消息,不同之处在于Post_Msg发送的消息存入消息队列的数组之中,而Send_Msg发送的消息则存入链表之中。
消息获取函数为Get_Msg函数,它为窗口提供取得消息的接口。拥有独立线程的窗口(异2. 4会描述其结构)调用它从消息队列中取得一个消息,其中存在链表中的消息更为重要,优先取出。
事件处理函数是窗口处理消息事件的函数接口,在SKY-GUI中,拥有独立线程的窗口调用Dispatch_Msg函数来实现对自己消息处理函数的调用。
2. 3. 4消息处理函数
Dispatch_Msg只是事件处理的调用接口,窗口收到消息后所采取的具体措施是由消息处理函数决定的,其定义为:
int WndProc(HWND hwnd, int event, void *wParam,void* lParam);
每一个窗口都有一个函数指针指向自己的消息处理函数,其功能根据不同的窗口有所不同,但总体结构是一样的,如图4所示。
图4消息处理函数的结构
其本质上是一个消息处理的分类列表。当窗口调用消息处理函数时,其根据消息类型的不同分别调用底层输入消息、控件消息或显示消息的处理函数,而后再根据具体的消息事件调用相应的处理函数,实现对各种事件的响应。
2. 4窗口系统
窗口系统为SKY-GUI系统的核心,它维护了一个完整的窗口列表,定义了窗口系统和事件系统之间的关系,并制定了窗口之间的消息传递机制。
2. 4. 1窗口的定义
SKY-GUI中,窗口既包含桌面、对话框这种狭义的窗口,也包含窗口控件(如按钮、下拉菜单、编辑框等等)这样的广义窗口,其定义为:
typedef struct __WINDOW {
STR32 caption; / /窗口的名称
RECT rect; / /窗口的大小、位置
int style; / /窗口的类型
MsgQueue* pMsgQ; / /附属于窗口的消息队列
struct __WINDOW*pFocus; / /活动窗口指针
struct __WINDOW*pParent; / /父窗口指针
struct __WINDOW*pChldHead; / /子窗口列表
struct __WINDOW*pNext; / /兄弟窗口或控件指针
struct __WINDOW*pCtrlHead; / /控件列表
WNDPROC WndProc; / /消息处理函数指针
void* data1; / /窗口私有数据
void* data2; / /窗口私有数据
void* data3; / /窗口私有数据
int msg1; / /窗口状态变化消息
} WINDOW;
caption为窗口的名称;rect为保存窗口位置和大小的矩形;style为窗口的类型;pMsgQ为窗口的消息队列的指针;pFocus指向当前窗口的活动子窗口或控件;pParent指向当前窗口的父窗口;pNext指向当前窗口的兄弟窗口;pChldHead用来保存当前窗口的子窗口列表;pCtrlHead保存当前窗口的控件列表。WndProc指向当前窗口的消息处理函数;data1、data2、data3为窗口的私有数据,msg1为窗口状态变化时需要发出的控件消息,它们的意义根据窗口的类型而定。
从窗口的定义可以看出,本文要实现的是一种树形的窗口关系,整个系统可以拥有一个或多个主窗口,每个主窗口拥有自己的控件和子窗口,而子窗口又可以拥有各自的子窗口和控件,依此类推。
2. 4. 2窗口与消息队列的关系
窗口定义中含有指向消息队列的指针,但并不是所有的窗口都有自己的消息队列。主窗口(如桌面)需要随时呈现在用户的面前,可以拥有自己的消息队列;其他的子窗口、控件则没有必要拥有自己的消息队列。这两类窗口用不同的方式使用事件系统。
拥有消息队列的主窗口必须拥有自己独立的线程,其消息发送和处理的流程如图5所示。
图5拥有消息队列的窗口的消息发送和处理流程。
当其他窗口或输入抽象层需要操作主窗口时,就调用事件系统中的Post_Msg或Send_Msg函数向该窗口的消息队列发送一个消息。而主窗口得知有消息输入,就调用事件系统中的Get_Msg函数取出消息,并使用Dispatch_Msg调用自己的消息处理函数,找到相应的事件处理方法处理事务。这种消息传递的特点是消息的发送和处理分别在不同的窗口线程中完成,一般用于两个主窗口之间或者输入抽象层和主窗口之间的消息通信。
没有消息队列的子窗口
- REDIce-Linux--灵活的实时Linux内核(11-12)
- linux文件系统基础(02-09)
- Linux标准趋向统一(11-12)
- linux基础技术(02-09)
- LINUX的目录树(02-09)
- 在Windows下启动Linux(02-09)