《minigui技术讨论》由会员分享,可在线阅读,更多相关《minigui技术讨论(38页珍藏版)》请在金锄头文库上搜索。
1、LOGOMiniGUI技术讨论Rainleaf2006.07.28 概要MiniGUI的窗口系统MiniGUI的消息系统 个人心得内容摘要四大手机平台的对比概要MiniGUI是一种嵌入式的图形用户界面系统,它具 有资源小、速度快、可移植好,且它的基本原理与一般 GUI的原理是相同的,同时也是遵循GWES(图形窗口 事件系统)的一般规律,总体上GUI就是管理用户输入 和系统屏幕输出的一个系统。四大手机平台的比较v Symbian Symbian由摩托罗拉、西门子、诺基亚等几家大型移动通 讯设备商共同出资组建的一个合资公司,专门研发手机操 作系统。 Symbian操作系统在智能移动终端上拥有强大的
2、 应用程序以及通信能力。四大手机平台的比较v Linux OS Linux具有源代码开放、软件授权费用低、应用开发人才资 源丰富等优点,便于开发个人和行业应用。 MiniGUI就是基于Linux平台的。 四大手机平台的比较v Window Mobile Windows Mobile包括Pocket PC、SmartPhone以及 Pocket PC Phone三大平台体系,Windows Mobile具有录 音、音视频播放等多媒体功能。由于大多数机型支持彩色 显示,因此耗电量极大,并且由于Windows CE本身对于 资源的巨大吞噬作用,所以在能耗方面Windows CE系统 要明显逊于Pal
3、m操作系统。 四大手机平台的比较v Palm OS Palm OS是Palm公司的是一种32位的嵌入式操作系统,由 于Palm操作系统本身所占的内存极小,基于Palm操作系 统编写的应用程序所占的空间也很小。但 Palm在其它方 面还存在一些不足,Palm操作系统本身不具有录音、MP3 播放功能等,而且对于中国用户而言,另一个不足之处在 于Palm操作系统起初在中国销售的产品仍然要使用中文外 挂平台,有相当部分依然是以英文界面为主,在一定程度 上影响了基于Palm操作系统的产品在中国市场的大面积进 入。 MiniGUI的窗口系统v 一般图形界面系统组成:MiniGUI的窗口系统v MiniGU
4、I有三种窗口类型: 主窗口、对话框和控件窗口(子窗口),每一个MiniGUI 应用程序一般都要一个主窗口,作为应用程序的主界面或 开始界面。应用程序还会创建其它类型的窗口,如对话框 和消息框,对话框本质上就是主窗口,应用程序一般通过 对话框提示用户进行输入操作,消息框是用于给用户一些 提示或警告的主窗口,属于内建的对话框类型。MiniGUI的窗口系统v MiniGUI窗口创建步骤: 1.创建窗口类; 2.登记窗口类; 3.创建并显示窗口; 4.启动消息循环。MiniGUI的窗口系统v MiniGUI窗口创建说明: 1.CreateInfo.dwAddData:在程序编制过程中,应该尽量减少静态
5、变 量,但是如何不使用静态变量而给窗口传递参数呢?这时可以使用这 个域。该域是一个 32 位的值,因此可以把所有需要传递给窗口的参 数编制成一个结构,而将结构的指针赋予该域。在窗口过程中,可以 使用 GetWindowAdditionalData 函数获取该指针,从而获得所需要传 递的参数。 2.CreateInfo.hHosting:该域表示的是将要建立的主窗口使用哪个主 窗口的消息队列。使用其他主窗口消息队列的主窗口,我们称为“被托 管“的主窗口。当然,这只在 MiniGUI-Threads 版本中有效。 3.MainWinProc 函数负责处理窗口消息。这个函数就是主窗口的“窗口 过程“
6、。窗口过程一般有四个入口参数,第一个是窗口句柄,第二个是 消息类型,第三个和第四个是消息的两个参数。MiniGUI的窗口系统v MiniGUI对话框模板构建窗口: 采用对话框模板,可以快速的构建窗口和其中的控件,而 且便于维护和控制,具体方法如下: 1.定义对话框模板结构(DLGTEMPLATE)并将对话框相关 设置填入:static DLGTEMPLATE DlgInitProcess=; 2.定义控件数组(CTRLDATA)并将需要创建的控件按照格 式填入:static CTRLDATA CtrlArray = ; 3.将控件数组依附在对话框模板上: DlgInitProcess.cont
7、rols = CtrlArray; 4.编写对话框回调函数:InitDialogBoxProc(); 5.调用对话框函数DialogBoxIndirectParam()创建对话框。MiniGUI的消息系统v 事件驱动编程 事件驱动的含义就是,程序的流程不再是只有一个入口和 若干个出口的串行执行线路;相反,程序会一直处于一个 循环状态,在这个循环当中,程序从外部输入设备获取某 些事件,比如用户的按键或者鼠标的移动,然后根据这些 事件作出某种的响应,并完成一定的功能,这个循环直到 程序接受到某个消息为止。“事件驱动“的底层设施,就是 常说的“消息队列“和“消息循环“。MiniGUI的消息系统v 消
8、息驱动的应用程序的简单架构:MiniGUI的消息系统v 消息和消息循环: 1.消息 在 MiniGUI 中,消息被如下定义(include/window.h): typedef struct _MSG HWND hwnd; int message; WPARAM wParam; LPARAM lParam; #ifdef _LITE_VERSION unsigned int time; #else struct timeval time; #endif POINT pt; #ifndef _LITE_VERSION void* pAdd; #endif MSG; typedef MSG* PM
9、SG; 一个消息由该消息所属的窗口(hwnd)、消息编号(message)、消息的 WPARAM 型参数(wParam)以及消息的 LPARAM 型参数(lParam)组成。MiniGUI的消息系统MiniGUI 定义了 MSG_USER 宏,可如下定义自己的消息: #define MSG_MYMESSAGE1 (MSG_USER + 1) #define MSG_MYMESSAGE2 (MSG_USER + 2) 2.消息循环 消息循环就是一个循环体,在这个循环体中,程序利用 GetMessage 函数不停地从消息队列中获得消息,然后利用 DispatchMessage 函 数将消息发送到指
10、定的窗口,也就是调用指定窗口的窗口过程,并传 递消息及其参数。典型的消息循环如下所示: while (GetMessage (DispatchMessage ( MiniGUI的消息系统v 消息的传送机制: 1.PostMessage:消息发送到消息队列后立即返回,这种发送方式称 为“邮寄”消息。如果消息队列中的邮寄消息缓冲区已满,则该函数返 回错误值。 2.PostSyncMessage:该函数用于在不同线程中进行消息邮寄,并且 只有当该函数被处理后,该函数才能返回,因此这种消息称为“同步消 息”。 3.SendMessage:该函数可以向任意一个窗口发送消息,消息处理完 成之后,该函数返回
11、。如果目标窗口所在线程和调用线程是同一个线 程,该函数直接调用窗口过程,如果处于不同的线程,则利用 PostSyncMessage 函数发送同步消息。MiniGUI的消息系统4.SendNotifyMessage:该函数向指定的窗口发送通知消 息,将消息放入消息队列后立即返回。由于这种消息和邮 寄消息不同,是不允许丢失的,因此,系统以链表的形式 处理这种消息。 5.SendAsyncMessage:利用该函数发送的消息称为“异步 消息”,系统直接调用目标窗口的窗口过程。MiniGUI的消息系统v消息的处理:MiniGUI的消息系统vMiniGUI-Threads与MiniGUI-Lite消息队
12、列的区 别: 在 MiniGUI-Threads 版本中,每个建立有窗口的 GUI 线 程有自己的消息队列,而且,所有属于同一线程的窗口共 享同一个消息队列。因此,GetMessage 函数将获得所有 与 hMainWnd 窗口在同一线程中的窗口的消息。而在 MiniGUI-Lite 版本中,只有一个消息队列,GetMessage 将从该消息队列当中获得所有的消息,而忽略 hMainWnd 参数。MiniGUI的消息系统v MiniGUI-Threads 和 MiniGUI-Lite 在消息处理上的不 同:MiniGUI-Threads MiniGUI-Lite 多消息队列 每个创建窗口的线程
13、拥有 独立的消息队列 只有一个消息队列。所有窗口共享 一个消息队列。除非嵌套消息循环 ,否则一个程序中只有一个消息循 环。 内建多线程处 理 是。可以自动处理跨线程 的消息传递 不能。从一个线程向另外一个线程 发送或者邮寄消息时,必须通过互 斥处理保护消息队列。 其他 可利用PostSyncMessage 函数跨线程发送消息,并 等待消息的处理结果 不能使用 PostSyncMessage、 SendAsynMessage 等消息。 个人心得v MSG_PAINT消息: 该消息的优先级最低,从上至下直到当前窗口发送到每一 个窗口。当Post此消息时不会放在消息队列中,而是在窗 口实体上作一个N
14、EEDPAINTD的标志,处理完消息队列 后检查此标志,如有则发送同步消息:WM_PAINT。个人心得v MSG_ERASEBKGND消息: 每当要创建窗口时,会发送这个消息重绘窗口背景。当用 户需要自定义背景时,可在这个消息内处理,然后返回( 不经过默认处理)即可。如果在此消息内直接返回且不作 任何处理,则会以上一层窗口的内容作为当前窗口的背景 。当使用函数InvalidateRect ()或发送MSG_PAINT时也会 产生这个消息。个人心得v 控件背景颜色的设置: 在界面处理中,经常要消除或改变背景的颜色,而且基本 上是跟多控件需要相同的背景。为了处理上的方便和以后 的维护或修改,最好将
15、所改的颜色值定义成宏,然后在所 需要更改的控件后调用函数SetWindowBkColor()即可。 个人心得v 内存DC的应用: 当需要显示的内容过多或数据量太大时,由于屏幕DC处 理上的问题导致了明显的刷屏动作,影响了视觉效果,此 时应用内存DC来处理。内存DC是先把要显示的内容写入 内存区,然后将内存DC转化成屏幕DC将其中的内容一次 性显示在屏幕上,避免了刷屏。使用步骤: 1.创建内存DC:CreateMemDC(); 2.用内存DC Paint; 3.设置内存DC:SetMemDCColorKey()、SetMemDCAlpha(); 4.将内存DC转化为屏幕DC:BitBlt();
16、5.释放内存DC:DeleteMemDC().个人心得v 控件字体的改变: 函数SetWindowFont可以用来改变显示在控件上的逻辑字 体。先通过函数GetSystemFont取得系统的逻辑字体: SYSLOGFONT_DEFAULT、 SYSLOGFONT_WCHAR_DEF、SYSLOGFONT_FIXED , 在由函数SetWindowFont来改变字体。对于控件 IACMLEDIT_CTRL,通过发送消息 MSG_IAC_FONTCHANGE来改变字体。个人心得v 带有ICON的列表框的创建: 在创建列表框时加入风格:LBS_USEICON,在添加条目 时,填充结构LISTBOXITEMINFO,向列表框发送 LB_ADDSTRING即可。 个人心得v 旋钮的使用(IAC_SELBOX): 在使用旋钮时,必须包含扩展库:mgext.h,并在创建旋 钮时调用函数InitMiniGUIExt()来初始化扩展库,用完后释 放扩展库MiniGUIExtCleanUp()。 个人心得v 工具