MiniGUI 体系结构
嵌入式Linux环境下MiniGUI的研究与移植

嵌入式Linux环境下MiniGUI的研究与移植近年来随着设备与市场需求的广泛结合,手机、PDA等产品的应用对可视化操作界面的简洁和便利提出了更高的要求,这都需要一个稳定牢靠的高性能GUI系统来提供支持。
图形用户界面(Graphic User Interface,简称GUI)的广泛流行是当今计算机技术的重要成就之一,它极大地便利了非专业用户的用法,人们可以通过窗口、菜单便利地举行操作。
嵌入式系统对GUI的基本要求包括有轻型、占用资源少、高性能、高牢靠性以及可配置等。
MiniGUI是目前比较常用的几种GUI系统之一,与其他的GUI相比,MiniGUI最显著的特点就是轻型、占用资源少,而且在这几年的进展里,MiniGUI已经十分成熟和稳定了,在许多产品和项目中都已得到了实际应用。
1 MiniGUI的特点和体系结构1. 1 MiniGUI的特点MiniGUI是由原清华高校老师魏永明主持开发的轻量级图形系统,是一种面对嵌入式或实时系统的图形用户界面支持系统。
它遵循GPL公约,是基于SVGALib及Thread库的多窗口GUI支持系统。
能跨多种操作系统,主要运行于linux及一切具有POSIX线程支持的POSIX兼容系统,包括一般嵌入式Linux、eCos、uC/OS-II、等系统,是国内最早的自由软件之一。
MiniGUI的主要特点有:(1) 遵循GPL条款的纯自由软件;(2) 提供了完备的多窗口机制;(3) 多字符集和多字体支持,目前支持ISO8859-1、GB2312及Big5等字符集,并且支持各种光栅字体和TrueType、Type1等矢量字体;(4) 全拼和五笔等汉字输入法支持;(5) BMP、GIF、JPEG及PCX等常见图像文件的支持;(6) Windows的资源文件支持,如位图、图标、光标、插入符、定时器及加速键等;(7) 可移植性好。
1.2 MiniGUI的体系结构1.2.1 多线程的分层设计从整体结构上看,MiniGUI是分层设计的,结构1所示。
MiniGUI 体系结构

MiniGUI 体系结构之二1 引言在任何一个足够复杂的 GUI 系统中,处理窗口之间的互相剪切是其首要解决的问题。
因为多窗口系统首先要确保一个窗口中的绘制输出不会影响到另外一个窗口。
为此,GUI 系统一般要利用 Z 序来管理窗口之间的互相剪切关系。
根据窗口在 Z 序中所处的位置,GUI 系统要计算每个窗口受剪切的区域,即剪切域。
通常,窗口的剪切域定义为互不相交的矩形集合。
GUI 系统的底层图形引擎在进行输出时,要根据当前输出的剪切域进行输出的剪切操作。
从而保证窗口的绘制输出不会互相影响。
因为任何一个窗口的创建、销毁、隐藏、显示均有可能影响其他窗口的剪切域,所以首先要有一个高效的剪切域维护算法。
本文将详细描述MiniGUI 中的剪切域生成算法。
许多人对控件(或者部件)的概念已经相当熟悉了。
控件可以理解为主窗口中的子窗口。
这些子窗口的行为和主窗口一样,即能够接收键盘和鼠标等外部输入,也可以在自己的区域内进行输出�D�D只是它们的所有活动被限制在主窗口中。
MiniGUI 也支持子窗口,并且可以在子窗口中嵌套建立子窗口。
我们将MiniGUI 中的所有子窗口均称为控件。
在 Windows 或 X Window 中,系统会预先定义一些控件类,当利用某个控件类创建控件之后,所有属于这个控件类的控件均会具有相同的行为和显示。
利用这些技术,可以确保一致的人机操作界面,而对程序员来讲,可以像搭积木一样地组建图形用户界面。
MiniGUI 使用了控件类和控件的概念,并且可以方便地对已有控件进行重载,使得其有一些特殊效果。
比如,需要建立一个只允许输入数字的编辑框时,就可以通过重载已有编辑框而实现,而不需要重新编写一个新的控件类。
在多语种环境中,输入法是一个必不可少的模块。
输入法提供了将标准键盘输入翻译为适当语种的文字的能力。
MiniGUI 中也包含有标准的中文简体输入法,包括全拼、五笔和智能拼音等等。
本文最后将介绍 MiniGUI 中的输入法模块实现。
MiniGUI(程序开发)

25
控件风格的介绍
窗口的通用风格: WS_VISIBLE WS_CAPTION WS_BORDER WS_VSCROLL WS_EX_NONE (窗口可见) (窗口有标题) (窗口有边框) (垂直滚动条) (无扩展风格)
26
重要的消息类型
MSG_CREATE:在窗口成功创建后进行触发, 在其中可以进行新窗口的创建。 MSG_COMMAND:控件内部发生事件时, 通过此消息来进行发送。 MSG_CHAR:有按键值,当按键按下时触发此 消息。 MSG_LBUTTONDOWN:鼠标点击左键时出 发此消息。
28
主要的API接口函数
GetDlgItem:根据控件标识符获得控件句柄。
GetWindowText:复制编辑框中的文本。
SetWindowText:重置编辑框中的文本。
SetWindowBkColor:设置窗口背景颜色。
SetWindowAdditionalData:保存对话框的附加数 据
// control class // control style // control position in
// control identifier // control caption // additional data // control extended style
14
对话框的建立
//设置主窗口风格
CreateInfo.dwExStyle = WS_EX_NONE; CreateInfo.spCaption = “HelloWorld”; CreateInfo.hMenu = 0;
//设置主窗口的扩展风格 //设置主窗口的标题 //设置主窗口的主菜单
实验八:MiniGUI应用程序设计实验

实验八 MiniGUI应用程序设计实验一、实验目的1.了解MiniGUI的基本结构。
2.练习MiniGUI的系统配置和编译安装。
3.交叉编译、在目标板上运行MiniGUI。
4.分析并了解 MiniGUI应用程序hello world。
5.在目标板上运行hello world程序。
二、实验设备和仪器1.计算机2.FS2410P教学实验平台三、实验内容及要求1.MiniGUI的系统配置和编译安装2.分析并了解 MiniGUI应用程序hello world。
3.交叉编译MiniGUI应用程序hello world。
4.在开发板上运行hello world程序。
四、实验原理及步骤1. 实验原理MiniGUI是一种面向嵌入式系统和实时系统的图形用户界面支持系统。
它主要运行于Linux控制台,实际可以运行在任何一种具有线程支持的POSIX兼容系统上。
MiniGUI同时也是国内最早出现的几个自由软件项目之一。
与Microwindows相比,MiniGUI和MicroWindows均为自由软件,只是前者遵循LGPL条款,后者遵循MPL条款。
这两个系统的技术路线也有所不同。
MiniGUI的策略是首先建立在比较成熟的图形引擎之上,比如SVGALib和LibGGI,开发的重点在于窗口系统如图形接口; MicroWindows目前的开发重点则在底层的图形引擎,窗口系统和图形接口方面的功能还比较欠缺。
举个例子来说,MiniGUI 有一套用来支持多字符集和多编码的函数接口,可以支持各种常见的字符集,包括GB、Big5、Unicode等,而MicroWindows在多字符集的支持上尚没有统一接口。
-MiniGUI最初是为了满足一个工业控制系统的需求而设计和开发的。
这个工业控制系统是清华大学为一台数控机床设计的计算机数控系统(CNC)。
在比较了DOS、Windows 98、Windows NT、Linux等系统之后,该项目组决定选择RT-Linux作为实时操作系统,以便满足2ms甚至更高的实时性。
miniGUI技术白皮书中文翻译稿

迷你GUI技术白皮书1 介绍1.1什么是miniGUIMiniGUI (),是由飞漫软件(Feynman Software)为实时嵌入式系统开发的一款轻量型图形用户界面支持系统。
自1999年第一次授权发布以来,MiniGUI已经被广泛得运用于掌上终端(手机和电子记事本),机顶盒,工业控制系统,工业设备,便携式媒体播放器,查询终端等等。
同时,MiniGUI已经成为了一个跨操作系统的图形用户界面(GUI)系统,它可以在Linux/uClinux,eCos,VxWorks,pSOS,ThreadX,Nucleus,OSE乃至uC/OS-II,以及Windows32位系统的平台下运行;已经被测试过的硬件平台,包括Inrelx86,ARM (ARM7/ARM9/StrongARM/xScale), PowerPC,MIPS和M68k(Dragonball/ColdFire)。
作为将MiniGUI带入高端嵌入式市场的基于嵌入式Linux的高端嵌入式设备,MiniGUI v2.0版为其提供了全部的多任务支持。
作为继MiniGUI 2.0 之后最新的版本,MiniGUI 3.0 有着许多重要的增强,例如单纤双向(BIDI)测试显示支持,透明控制,独立滚动控制,双字节字体渲染(UPF),点阵字形,以及新的组成部分包括mGUtils,mGPlus。
MiniGUI是“用于嵌入式设备的跨系统图形用户界面支持系统”,以及“嵌入式图形中间件”。
迄今为止,MiniGUI已经被中国最著名的电信设备供应商,中国最大的电视机制造商,即时分同步码分多址技术(TD-SCDMA)的主要制定者,以及世界上最大的处理器生产商所授权。
MiniGUI已经被以下领域中的主要厂家广泛采购和应用,包括:工业器械,医用设备,以及军工业。
同时,MiniGUI已经被全球的嵌入式设备开发商所公认,并远销至包括北美,日本,中国台湾和马来西亚等国家和地区。
MiniGUI已经成为嵌入式图形中间件的变相工业标准。
minigui代码分析

minigui代码分析目录一、minigui运行模式 (1)1、线程模式:MiniGui-Threads (1)2、进程模式:MiniGui-Processes (1)3、独立应用模式:MiniGui-Standalone (2)二、数据结构 (2)1、CreateMainWindow函数参数:PMAINWINCREATE pCreateInfo (2)2、MAINWIN结构体:主窗口的详细信息由该结构体给出 (2)3、MSGQUEUE消息队列 (4)三、CreateMainWindow函数流程 (4)1、判断传入的参数pCreateInfo是否为空 (4)2、为PMAINWIN类型的pWin分配内存空间,并判断pWin是否为空 (4)3、是否定义_LITE_VERSION: (4)4、设置pWin的成员: (4)5、SendMessage ((HWND)pWin, MSG_NCCREATE, 0, (LPARAM)pCreateInfo) (6)6、SendMessage ((HWND)pWin, MSG_SIZECHANGING,(WPARAM)&pCreateInfo->lx,(LPARAM)&pWin->left); (7)7、SendMessage ((HWND)pWin, MSG_CHANGESIZE, (WPARAM)&pWin->left, 0) (7)8、SendMessage (HWND_DESKTOP, MSG_ADDNEWMAINWIN, (WPARAM) pWin,(LPARAM) pWin->pZOrderNode); (7)9、SendMessage ((HWND)pWin, MSG_CREATE, 0, (LPARAM)pCreateInfo) (8)四、ShowWindow函数流程 (8)1、MG_CHECK_RET (MG_IS_NORMAL_WINDOW(hWnd), FALSE) (8)2、根据窗口类型和窗口的显示类型对窗口的显示状态进行调整 (8)如果hWnd指示的窗口是主窗口: (9)如果hWnd指示的窗口是控件窗口: (9)3、根据iCmdShow等信息确定当前窗口是否失去输入焦点 (10)4、向消息队列发送消息MSG_SHOWWINDOW根据iCmdShow 指示当前窗口的显示状态 (10)一、minigui运行模式1、线程模式:MiniGui-Threads定义:_MGRM_THREADS运行在MiniGui-Threads上的程序可以在不同的线程中建立多个窗口,但所有的窗口在一个进程或地址空间中运行,传统意义上的嵌入式操作系统。
MiniGUI学习笔记

MiniGUI学习笔记关于操作系统和上层软件的关系,某些操作系统被称为内核空间(kernel space),而操作系统以上的部分被称为用户空间(user space)。
按照功能,操作系统以上的部分可以分为中间件和上层应用两个部分。
中间件一般提供了一些相对底层的软件层次的功能。
它的实现一般不包括应用程序的逻辑,而是向上层软件提供了各种方便的应用程序接口(API)。
GUI系统的移植实现基础包含输出设备和输入设备两个方面在学习一个嵌入式GUI特性和功能的时候,需要关注可移植性、稳定性和可靠性、系统开销、可配置性等几个方面的内容。
第二章.MiniGUI的特点和发展作为操作系统和应用程序之间的中间件,MiniGUI将底层操作系统及硬件平台差别隐藏了起来,并对上层应用程序提供了一致的功能特性,这些功能特性主要包括:1)支持不同的硬件开发平台2)跨操作系统支持3)多运行模式支持。
为了适应不同的操作系统运行环境,MiniGUI可配置成三种运行模式:MiniGUI-Threads(线程模式)、MiniGUI-Processes(进程模式)及MiniGUI-Standalone(独立模式) 4)内建资源支持。
可以将MiniGUI所使用的资源,诸如位图、图标和字体等编译到函数库中。
5)完备的多窗口机制和消息传递机制6)提供常用的控件类。
7)对话框和消息框支持8)其他GUI元素9)界面皮肤支持10)支持低端显示设备(比如单色LCD)和高端显示设备(8位色及以上显示设备)。
通过MiniGUI的图形抽象层及图形引擎技术,还可以支持特殊的显示设备,比如YUV显示设备。
11)提供增强GDI函数。
12) Windows的资源文件支持13)各种流行图像文件支持14)多字符集和多字体支持15)多种键盘布局的支持16)针对嵌入式系统的特殊支持,包括一般性的I/O流操作,字节序相关函数等17)副屏支持。
硬件适配性:可运行于各种含有MMU(内存管理单元)的32位处理器架构之上。
MiniGUI 编程模型(二)

一、对话框
在 MiniGUI 中,对话框是一类特殊的主窗口, 这种主窗口只关注与用户的交互――向 用户提供输出信息,但更多的是用于用户输入。 对话框可以理解为子类化之后的主窗口类。 它针对对话框的特殊性(即用户交互)进行了 特殊设计。
1、对话框模板
在 MiniGUI 中,用两个结构来表示对话框模板 (minigui/window.h),详见PDF文档: 结构 CTRLDATA 用来定义控件,DLGTEMPLATE 用来 定义对话框本身。在程序中,分两步来做: (1)首先利用 CTRLDATA 定义对话框中所有的控件, 并用数组表示。控件在该数组中的顺序,也就是对话框 中用户按 TAB 键时的控件切换顺序。 (2)然后定义对话框,指定对话框中的控件数目,并指 定 DLGTEMPLATE 结构中的 controls 指针指向定义控件 的数组。
HWND GUIAPI CreatWindowEx (const char *spClassName,const char *spCaption,DWORD dwstyle,DWORD dwExstyle, Int id,int x,int,y,int w,int h,HWND hParentWnd,DWORD dwAddData);
如前所述,控件是和用户交互的主角。当控件 上发生了某种时间时,控件将会想其父窗口 发送一条消息来通知所发生的事件,这里的 父窗口既可以是主窗口,也可以是父控件。 但是通常来说应该将控件的父窗口设为主窗 口,因为消息队列通常是由主窗口的窗口过 程处理的。 实际上MiniGUI中还有控件类的概念,但是作 为初学者,先用熟练预先定义好的类是最重 要的。
int GUIAPI DialogBoxIndirectParam (PDLGTEMPLATE pDlgTemplate, HWND hOwner, WNDPROC DlgProc, LPARAM lParam); BOOL GUIAPI EndDialog (HWND hDlg, int endCode); void GUIAPI DestroyAllControls (HWND hDlg); 在 DialogBoxIndirectParam 中,需要指定对话框模板(pDlgTemplate)、 对话框的托管主窗口句柄(hOwner)、对话框回调函数地址DlgProc,以 及要传递到对话框过程的参数值(lParam)。EndDialog 用来结束对话框 过程。DestroyAllControls 用来销毁对话框(包括主窗口)中的所有子控件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
MiniGUI 体系结构之二1 引言在任何一个足够复杂的 GUI 系统中,处理窗口之间的互相剪切是其首要解决的问题。
因为多窗口系统首先要确保一个窗口中的绘制输出不会影响到另外一个窗口。
为此,GUI 系统一般要利用 Z 序来管理窗口之间的互相剪切关系。
根据窗口在 Z 序中所处的位置,GUI 系统要计算每个窗口受剪切的区域,即剪切域。
通常,窗口的剪切域定义为互不相交的矩形集合。
GUI 系统的底层图形引擎在进行输出时,要根据当前输出的剪切域进行输出的剪切操作。
从而保证窗口的绘制输出不会互相影响。
因为任何一个窗口的创建、销毁、隐藏、显示均有可能影响其他窗口的剪切域,所以首先要有一个高效的剪切域维护算法。
本文将详细描述MiniGUI 中的剪切域生成算法。
许多人对控件(或者部件)的概念已经相当熟悉了。
控件可以理解为主窗口中的子窗口。
这些子窗口的行为和主窗口一样,即能够接收键盘和鼠标等外部输入,也可以在自己的区域内进行输出�D�D只是它们的所有活动被限制在主窗口中。
MiniGUI 也支持子窗口,并且可以在子窗口中嵌套建立子窗口。
我们将MiniGUI 中的所有子窗口均称为控件。
在 Windows 或 X Window 中,系统会预先定义一些控件类,当利用某个控件类创建控件之后,所有属于这个控件类的控件均会具有相同的行为和显示。
利用这些技术,可以确保一致的人机操作界面,而对程序员来讲,可以像搭积木一样地组建图形用户界面。
MiniGUI 使用了控件类和控件的概念,并且可以方便地对已有控件进行重载,使得其有一些特殊效果。
比如,需要建立一个只允许输入数字的编辑框时,就可以通过重载已有编辑框而实现,而不需要重新编写一个新的控件类。
在多语种环境中,输入法是一个必不可少的模块。
输入法提供了将标准键盘输入翻译为适当语种的文字的能力。
MiniGUI 中也包含有标准的中文简体输入法,包括全拼、五笔和智能拼音等等。
本文最后将介绍 MiniGUI 中的输入法模块实现。
回页首2 窗口 Z 序Z 序实际定义了窗口之间的层叠顺序。
说起“Z 序”这个名称,实际是相对屏幕坐标而言的。
一般而言,屏幕上的所有窗口均有一个坐标系,即原点在左上角,X 轴水平向右,Y 轴垂直向下的坐标系。
Z 序就是相对于一个假想的 Z 轴而言的,这个 Z 轴从屏幕外指向屏幕内。
窗口在这个 Z 轴上的值,就确定了其 Z 序。
Z 序值大的窗口,覆盖了 Z 序值小的窗口。
当然,在程序当中,Z 序一般表示为一个链表。
越接近于链表头的节点,其 Z 序值就越大。
在 MiniGUI 中,我们维护了两个 Z 序。
其中一个 Z 序永远位于另一个 Z 序之上。
这样,就可以创建始终位于其他窗口之上的窗口,比如输入法窗口。
如果在建立窗口时,指定了 WS_EX_TOPMOST 扩展属性,就可以创建这样的主窗口。
因为 Z 序的操作实际就是链表的操作,这里就不再赘述。
回页首3 窗口剪切算法有了窗口 Z 序,我们就可以计算每个窗口的剪切域。
我们把因为窗口 Z 序而产生的剪切域称为“全局剪切域”,这是相对于窗口自身定义的剪切域而言的,我们把后者称为“局部剪切域”。
窗口中的所有输出,首先要受到全局剪切域的影响,其次受到局部剪切域的影响。
我们在这里重点讲解窗口的全局剪切域的生成和维护。
3.1 全局剪切域的生成和维护在 MiniGUI 中,剪切域表示为若干互不相交的矩形之并集,这些矩形称为剪切矩形。
最初,屏幕上没有任何窗口时,桌面的剪切域由一个矩形组成,即屏幕矩形;当屏幕上只有一个窗口时,该窗口的剪切域由一个矩形组成,该矩形即为窗口在屏幕上的矩形,而桌面的剪切域却可能是由多个矩形组成的。
图 1 说明了只有一个窗口时的桌面的剪切域组成。
从图中可以看出,此时桌面的剪切域由四个矩形组成,分别是 A、B、C 和 D。
如果窗口在桌面的位置变化为图 2 所示,则桌面的剪切域将由两个矩形组成(A和B)。
图 1 由四个矩形组成的桌面剪切域图 2 由两个矩形组成的桌面剪切域读者很容易看出,在只有一个窗口的情况下,形成桌面剪切域的矩形最多只能有四个。
此时,如果有一个新的窗口出现,则新的窗口将同时剪切旧的窗口和桌面(图 3。
窗口的剪切矩形用空心矩形表示,而桌面的剪切矩形用实心矩形表示)。
而这时,桌面和旧窗口的剪切域将多出一些矩形,这些矩形应该是原有剪切域中的每个矩形受到新窗口矩形影响之后生成的剪切矩形。
同样,原有剪切域中的每个矩形只能最多只能派生出4个新剪切域,而某些矩形根本不会受到新窗口矩形的影响。
图 3 有新窗口被创建时,桌面和旧窗口的剪切域这样,我们可以将某个窗口全局剪切域归纳为原有剪切域中排除(Exclude)某个矩形而生成的:1.窗口的全局剪切域初始化为窗口矩形。
2.当窗口之上有其他窗口覆盖时,则该窗口的全局剪切域为排除新窗口矩形之后的剪切域。
3.沿 Z 序迭代第 2 步,直到最顶层窗口。
清单 1 中的代码是在显示一个新窗口时,MiniGUI 处理被该窗口所覆盖的其他所有窗口的代码。
这段代码调用了剪切域维护接口中的 SubtractClipRect 函数计算新的剪切域。
清单 1 显示新窗口时计算被新窗口覆盖的窗口的全局剪切域// clip all windows under this window.static void clip_windows_under_this (ZORDERINFO* zorder, PMAINWIN pWin, RECT* rcWin){PZORDERNODE pNode;PGCRINFO pGCRInfo;pNode = zorder->pTopMost;while (pNode->hWnd != (HWND)pWin)pNode = pNode->pNext;pNode = pNode->pNext;while (pNode){if (((PMAINWIN)(pNode->hWnd))->dwStyle & WS_VISIBLE) {pGCRInfo = ((PMAINWIN)(pNode->hWnd))->pGCRInfo;pthread_mutex_lock (&pGCRInfo->lock);SubtractClipRect (&pGCRInfo->crgn, rcWin);pGCRInfo->age ++;pthread_mutex_unlock (&pGCRInfo->lock);}pNode = pNode->pNext;}}与排除矩形相反的操作是包含(Include)某个矩形到剪切域中。
这个操作用于隐藏或者销毁某个窗口时。
当一个窗口被隐藏或销毁时,该窗口之下的所有窗口将受到影响,此时,要将被隐藏或销毁窗口的矩形包含到这些受影响窗口的全局剪切域中。
为此,MiniGUI 的剪切域维护接口中有一个函数专用于该类操作(IncludeClipRect)。
为确保剪切域中矩形互不相交,该函数首先计算与每个剪切矩形的相交矩形,然后将自己添加到该剪切域中。
但是,在某些情况下,我们必须重新计算所有窗口的全局剪切域,比如在移动某个窗口时。
3.2 剪切矩形的私有堆显然,在剪切域非常复杂,或者窗口非常多时,需要大量的矩形来表示每个窗口的全局剪切域。
而在 C 程序中,如果频繁使用 malloc 和 free 申请和释放每个剪切矩形,将带来许多问题。
第一,malloc 和 free 是非常耗时的操作;第二,频繁的 malloc 和 free 将导致 C 程序堆的碎片化,从而可能导致将来的内存分配失败。
为了避免频繁使用 malloc 和 free,MiniGUI 在初始化时,建立了一个私有的堆。
我们可以直接从这个堆中分配剪切矩形,而不需要从进程的全局堆中分配剪切矩形。
这个私有堆实际是由一些空闲待用的剪切矩形组成的。
每次分配时返回该链表的头节点,而在释放时放进该链表的尾节点。
如果该链表为空,则利用 malloc 从进程的全局堆中分配剪切矩形。
清单 2 说明了这个私有堆的初始化和操作。
清单 2 从剪切矩形私有堆中分配和释放剪切矩形PCLIPRECT GUIAPI ClipRectAlloc(PFREECLIPRECTLIST pList){PCLIPRECT pRect;#ifndef _LITE_VERSIONpthread_mutex_lock (&pList->lock);#endifif (pList->head) {pRect = pList->head;pList->head = pRect->next;}else {if (pList->free < pList->size) {pRect = pList->heap + pList->free;pRect->fromheap = TRUE;pList->free ++;}else {pRect = malloc (sizeof(CLIPRECT));if (pRect == NULL)fprintf (stderr, "GDI error: alloc clip rectfailure!\n");elsepRect->fromheap = FALSE;}}#ifndef _LITE_VERSIONpthread_mutex_unlock (&pList->lock);#endifreturn pRect;}void GUIAPI FreeClipRect(PFREECLIPRECTLIST pList, CLIPRECT* pRect) {#ifndef _LITE_VERSIONpthread_mutex_lock (&pList->lock);#endifpRect->next = NULL;if (pList->head) {pList->tail->next = (PCLIPRECT)pRect;pList->tail = (PCLIPRECT)pRect;}else {pList->head = pList->tail = (PCLIPRECT)pRect;}#ifndef _LITE_VERSIONpthread_mutex_unlock (&pList->lock);#endif}回页首4 主窗口和控件、控件类4.1 控件类和控件如果读者曾经编写过 Windows 应用程序的话,就应该了解窗口类的概念。