当前位置:首页 >> IT/计算机 >>

再次解析UCGUI390多对话框问题

UCGUI 技术文集

UCGUI 专业网站:www.ucgui.com

再次解析 UCGUI390 多对话框问题 作者:UCGUI 邮箱:UCGUI@163.com 主页:http://www.UCGUI.com 版本:v1.0.0.0 时间:2006/12/01 版本 v1.0.0.0 修改说明
完成多对话框支持的原理解析,以及模态对话框架的原理。 指出某些情况下 UCGUI 多对话框支持的问题及解决办法。

时间 2006/12/01

摘要: 摘要:说明 UCGUI390 版多对话框支持的原理以及模态对话框的支持原理,并指出在某些 情况下使用多对话框时的导致 UCGUI 出错的问题. 目录 一. 二. 三. 四. UCGUI 中的基本设计策略----微型. 为什么 UCGUI 的消息处理机制会导致多对话框的问题. UCGUI324 与 UCGUI390 版本在处理多对话框上的几点不同之处. 如何改进 UCGUI390, 以使其支持在任意控件的点击消息当中弹出对话框.

1

UCGUI 论坛

UCGUI 技术文集

UCGUI 专业网站:www.ucgui.com

问题: 问题: case WM_NOTIFY_PARENT: Id = WM_GetId(pMsg->hWinSrc); // Id of widget NCode = pMsg->Data.v; // Notification code switch (NCode) { case WM_NOTIFICATION_RELEASED: // React only if released if (Id == GUI_ID_OK) { // OK Button GUI_MessageBox("Message","caption", GUI_MESSAGEBOX_CF_MOVEABLE); } if (Id == GUI_ID_LISTBOX0 ){ pObj=LISTBOX_H2P(hListBox); LISTBOX_GetItemText(hListBox,1,ListItemName,20); GUI_MessageBox("item is:",ListItemName,GUI_MESSAGEBOX_CF_MOVEABLE); //改成下面这句正确.. //MESSAGEBOX_Create(ListItemName,"item is:",GUI_MESSAGEBOX_CF_MOVEABLE); } 在如上代码当中, 在点击 ListBox 时,执行 GUI_MessageBox()会导致弹出 N 多对话框, 以及"GUITASK.c: GUI_Lock() _EntranceCnt overflow "的错误提示. 但是点击按钮时, 执行 GUI_MessageBox()没有问题, 这是什么原因?? 论题分析: 论题分析: 深入 UCGUI 的消息处理机制当中,详细介绍一下为什么在 UCGUI390 版本中,仅有 Button 控件的点击支持弹出对话框,其它的控件均会导致出错呢? UCGUI324 版本当中, 我们详细的剖析了为什么在点击 Button 消息中弹出对话框会导致 出 错 , 详 细 的 分 析 可 见 "UCGUI 窗 体 管 理 及 消 息 处 理 机 制 分 析 .pdf"( 可 到 www.ucgui.com/bbs 当中下载). [原创]有关 UCGUI 的几篇技术文章下载 http://www.ucgui.com/bbs/dispbbs.asp?boardID=1&ID=131&page=1 这里不再重复的讲先前讲过的东西了, 下面我们将大略介绍如下几点:

2

UCGUI 论坛

UCGUI 技术文集

UCGUI 专业网站:www.ucgui.com

中的基本设计策略----微型. ----微型 一. UCGUI 中的基本设计策略----微型. 与其它一些同样是嵌入式的 GUI 图形系统相比, UCGUI 很明显的一大区别是:微型; 这微 型的特征主要体现在两点:节省空间, 包括代码空间与程序运行占用空间. -----代码空间占用少, 是指其对于同样的功能, 其实现简单,结构简单,设计简单,复杂 的功能放弃; -----程序运行占用空间少, 是指支持 GUI 运行时, 所消耗的变量空间小, 这对于本来 RAM 空间就紧张的小型嵌入式应用, 是非常的重要的. 程序运行消息消耗的空间小, 主 要有两个方面: [1]. 消息处理不用队列, 而是采取两个变量, 一个变量记载当前消息,一个变量记载先 前消息,当前消息从外部输入驱动中获取更新, 处理消息时与先前消息进行比较, 处理 完消息再将当前消息更新到先前消息变量中.这样处理起来,比起采用消息队列, 就省了 不知道多少空间了,因为在启用 MOSUE 类设备时,移动消息是非常多的.不采用消息队列, 也导致了 UGGUI 中的所有的消息处理都是同步的, 但这对于 UCGUI 来说也不是什么严重 的问题, 并不是必须的功能; 没有消息队列, 则每个消息的处理不能占用大量的时间, 否则严重影响消息处理的灵敏度,造成消息的丢失.但是这些问题都是可以接受的, 因来 带来的空间效率带有帮助了. [2]. 单一运行绪:UCGUI 运行的时候, 仅有一条执行路径, 也就是单一运行绪.这与 MINIGUI 多线程版是有很大的差别的,熟悉 MINIGUI 的朋友都知道 MINIGUI 分了三个版本, 多进程版/多线程版/单一版.多线程版分如下线程: -----用户程序是一个线程. -----桌面程序是一个线程. -----事集收集是一个线程. -----时间 Timer 是一个线程. -----创建窗口也可以单独启用一个线程. 分了线程,当然有些好处, 如计时器/消息接收不至被消息处理阻塞; 但是 UCGUI 中没有 这些复杂的机制, 从而少了很多的线程同步以及与其它系统的相关性(便于移植).而且 在资源占用了又少了一层, 节省了线程资源. [3]. 剪切处理, 窗口系统的剪切处理有两个要素, 一是时间效率;二是空间效率. UCGUI 中采取的是空间策略, 每进行一次图形绘制,都必须处理剪切; 在时间效率优先的系统 当中, 会计算过后就保存每个窗口的剪切矩形, 如果是在这个窗口上绘图, 就无须每一 次绘图操作都进行剪切处理, 只须要判断是否处于剪切矩形之内即可, 当然这个判断也 是很讲究策略的, 因为剪切矩形是一个系列,如果是绘制一个矩形, 这个矩形被分布在 几个剪切矩形当中, 这个时候也能采取两种办法:一是逐点判断之后画点;二是再进行一
3

UCGUI 论坛

UCGUI 技术文集

UCGUI 专业网站:www.ucgui.com

次剪切计算,剪切出可以绘制的矩形.这两个方法其实也体现了空间与时间的问题, 不过 第二种方法在时间上很优, 在空间上也仅是占用一时, 所以是比较优的. 但是如果要计 算过每个窗体的剪切矩形后, 要保存起来, 供窗体上再次作画时用, 这个空间占用则是 比较大的.

的消息处理机制会导致多对话框的问题. 二. 为什么 UCGUI 的消息处理机制会导致多对话框的问题. 同上面关于 UCGUI 中的消息机制的描述, 具体来看一看为什么会导致多话框支持上的问 题. [1]. UCGUI 中创建对话框后, 会形成一个独立的消息 LOOP, 独自的进行消息处理. 我 们已经说过, UCGUI 中的所有消息处理都是同步的,而且是单一执行绪的. 所以这样一来, 明显就带来的一个问题, 试想如下一个点击消息中弹出窗体的流程: ----1. 获取外部驱动的消息, 更新了当前消息变量, 设当前消息为 CurrentMsg, 先前 旧消息为 PrevMsg, 比较新旧消息,如单击发生的坐标及按下与否的状态. ----2. 如果是外部驱动产生的新消息(如单击消息), 处理单击消息, . ----3. 进入单击消息处理, 发送单击消息给对应的当前窗体, 根据当前的点击坐标取 得单击发生位置的窗体句柄. ----4. 对应的消息窗体处理消息, 弹出对话框. ----5. 更新消息, CurrentMsg=PrevMsg, 再转入第 1 步, 检测消息. 这是一个整体的消息处理完成的过程, 这个过程是一直 LOOP, 反复检测的. 想想如果是 新弹出一个对话框, 又进入了新的消息 LOOP, 那么可以肯定的是, 在新的消息 LOOP 处 理当中, 由于上一次消息 LOOP 的第 5 步[更新消息]没有完成, 则新消息 LOOP 中当中就 会反复处理这个没有更新的消息了. 然且这个过程是一个嵌套的过程, 一层的消息 LOOP 引发下一层的消息 LOOP, 但都无法完成在短时间内最后一步的消息更新. 这里我说短时间内, 是指的新的消息还没有到来的时候, 因为新的消息一到来, 就终止 了不断处理旧消息弹出对话框的过程. [2]. UCGUI 中详细的消息处理流程: 在最新版的 UCGUI390 版, 消息的处理主要分成四个部分. ----模态窗口消息分发, 检测当前窗体是否与模态窗体有关, 即是否是模态窗体本身或 者其子孙窗体, 用 WM__IsInModalArea()检测;这一步控制了消息的分布, 实现模态窗体 的功能就是这一句代码了. ----弹起与按下状态变化的消息分发(WM_PID_STATE_CHANGED 消息), 这个消息的分布 在按下 MOUSE 或者弹起 MOUSE 的时刻发生.
4

UCGUI 论坛

UCGUI 技术文集

UCGUI 专业网站:www.ucgui.com

----只要是按下状态, 以及按下与弹起状态变化的消息分发(WM_TOUCH), 这个消息在 MOUSE 按下或者弹起, 以及一直处于按下时发送, 比如你按下一个 BUTTON, 一直不放, 当 移动到另一个 BUTTON 时, 会看到焦点发生了切换到了新的 BUTTON 上, 就是这个消息导 致的.另外这个消息会在消息发生的新旧窗体交界时, 会最后向原来的旧窗体发最后一 个 WM_TOUCH 消息(状态为弹起), 发送这个消息为了让原来的旧窗体改变自己的状态(如 取消息焦点框等), 正如上面你按住 MOUSE 滑动新的 BUTTON, 则原来的 BUTTON 的焦点状 态取消, 不再高亮显示, 就是这个最后的消息发送导致的. ----移动的消息分发(WM_MOUSEOVER), 这个消息是在打开了 GUI_SUPPORT_MOUSE 宏配置 的时候才分发, 这个消息是很大量的, 只要 MOUSE 移动都会产生. 版本在处理多对话框上的几点不同之处. 三. UCGUI324 与 UCGUI390 版本在处理多对话框上的几点不同之处. 新旧版本主要有如下几点不一样: [1]. 增中了模态窗体的支持, 这个在第二点中已经描述过了. [2]. 增加了 WM_MOUSEOVER 消息. [3]. 增加了 WM_PID_STATE_CHANGED 消息. 但是如果仅仅这个地方一点小变化, 也不足以让 UCGUI390 支持在按钮点击消息中弹出 对话框, 还有如下几个变化: [1]. 创建对话框的变化. 具体的问题, 请用户自己查看代码. -----UCGUI324 版中, 在创建对话框时, 用一个全局的回调函数_cbDialog(), 作为每个 对话框的回调函数, 用一个全局变量_cb 来保存用户对话框自己指定的回调函数. 然后 在_cbDialog()函数中再调用用户对话框自己的回调函数(存在_cb 变量中). 这显然是 有问题的, 如果创建了新的对话框, 则这些全局变量就被新的赋值取代了, 就调用不到 用户原来对话框指定的回调函数了. -----UCGUI390 版中, 就不再用什么全局变量了, 直接用用户指定的回调函数, 就不存 在创建新的对话框后, 用户原来对话框指定的回调函数无法调用到的问题了. [2]. BUTTON 按钮的点击消息处理的变化. -----主要的差别在于, 新版当中加上了 Button 是否 BUTTON_STATE_PRESSED 状态的判 断, 即在处理按下 BUTTON 弹起后, 要向父窗体发送出 WM_NOTIFICATION_RELEASED 消息 前, 调用 WIDGET_AndState(hObj, BUTTON_STATE_PRESSED);来取消 Button 的按下状态, 就是这一点, 就使得即使有未更新的消息再次处理, 也不会导致再次给父窗体发送
5

UCGUI 论坛

UCGUI 技术文集

UCGUI 专业网站:www.ucgui.com

Button 弹起的消息, 从而避免了反复陷入弹出对话框, 消息处理中消息一直无法更新的 问题. [3].除了 Button 控件之外, 其它控件在单击消息中弹出对话框, 会出问题. -----比较上面 Button 的处理, 问题就相当容易理解了, 因为其它控件没有关于 BUTTON_STATE_PRESSED 这种类似状态的判断, 所以导致了未更新的消息反复的处理, 在 短时间内弹出一堆的对话框出来, 并且由于反复的消息 LOOP 嵌套, 导致加锁的没有解 锁, 从而报出"GUITASK.c: GUI_Lock() _EntranceCnt overflow "的错误提示. 以使其支持在任意控件的点击消息当中弹出对话框. 四. 如何改进 UCGUI390, 以使其支持在任意控件的点击消息当中弹出对话框. [1]. 弹出对话框时, 如果没有什么特别的问题, 可以使用模态对话框, UCGUI390 中支 持模态对话框, 由于是模态对话框, 那么先前未更新的旧窗体的消息, 就无法再进行处 理了, 所以不会陷入反复的弹出对话框中去. 创建模态对话框: { WM_HWIN hWinDlg = MESSAGEBOX_Create(" GUI_MESSAGEBOX_CF_MOVEABLE); WM_MakeModal(hWinDlg); GUI_ExecCreatedDialog(hWinDlg); }

You Win!!!

", "Win",

[2]. 如果是不采用弹出模态对话框, 我想另外的办法就是, 改进每个控件, 对于 MOUSE 弹起消息转发父窗体时, 加上类似 BUTTON 的控制, 加上一个状态的识别, 就可以了, 但 这要改动几乎每个控件的_OnTouch()处理. [3]. 前面说过, 正是因为弹出的对话框进入了新的消息 LOOP, 导致原来的对话框的消 息 LOOP 无法再执行下去, 无法更新旧消息变量. 那么我们就可以采取不让新建的对话 框开启新的消息 LOOP, 这很容易, 打开对话框时如下: MESSAGEBOX_Create(ListItemName, "sel item is", GUI_MESSAGEBOX_CF_MOVEABLE); 这里仅创建对话框, 而不执行 GUI_ExecCreatedDialog(hWin), 就不会开启新的消息 LOOP; 那消息 LOOP 放到哪里去呢? 直接放到 MainTask()当中去: while (1) {GUI_Exec();};

6

UCGUI 论坛


相关文章:
再次解析UCGUI390多对话框问题.doc
UCGUI 技术文集 UCGUI 专业网站:www.ucgui.com 再次解析 UCGUI390 多对话框问题 作者:UCGUI 邮箱:UCGUI@163.com 主页:http://www.UCGUI.com 版本:v1.0...
uCGUI中的窗口管理机制以及解决独立窗口并存的方法.doc
修改UCGUI 源代码以支持多个独立窗体的说明发 布时间 : 2008-11-17 问题的提出: 关于对话框对话框处理程序中, 按钮按下后想出现一个消息框。 ...
第39章emWin(ucgui)对话框基础知识.pdf
第39章emWin(ucgui)对话框基础知识_互联网_IT/计算机_专业资料。第39章emWin(ucgui)对话框基础知识ucos-ii,ucos-iii,emwin,StemWin,ucgui ...
原创ucGUI入门心得.doc
首先,我使用的是 ucGUI 的高版本emwin5.22。这个版本较旧版本多了些可用...最后总结一下在使用 emwin 过程中遇到的一些问题。 1.在对话框里使用画线画...
ucGUI移植.doc
2. 3. 4. /home/sam/Desktop/UCGUI390a/Start/GUI/下的所有东西加入你的工程。 /home/sam/Desktop/UCGUI390a/Sample 下的 GUIDemo 文件夹加入你的工程(...
stm32 UCGUI 完美移植_图文.pdf
UCGUI390a 下载 整个移植过程,让LCD显示图案倒是没花多少时间,资料也比较多,...很多文档都没清这个问题,可以使用两种方法来触发: 设定触摸屏的一个引脚为外部...
UCGUI中的中的设备驱动解析.doc
在打开多话框时即产生此问题, 避免的办法 很简单: [1].仅创建对话框,不...再次解析UCGUI390多对话... 6页 免费 UCGUI中的实现透明窗体的... 11...
UCOS-II ucGUI的完美移植.pdf
直接复制 UCGUI390a\Sample\GUI_ X\GUI_X.c ...很多文档都 没清这个问题,可以使用两种方法来触发: ...ucos_ii移植过程详解(移... 6页 1下载券 第...
基于STM32的UCGUI移植解析(新手入门).pdf
UCGUI 移植初级解析 ---如何建立一个简单的 UC/GUI 工程 仅供像我这样的新手学习 UCGUI 使用做 UCGUI 移植,首先要选择好自己硬件平台,UCGUI 源码,液晶的底层...
uCGUIBuilder使用说明.doc
uCGUIBuilder使用说明_计算机软件及应用_IT/计算机_...重新在系 统设置--->更新 对话框中选择为自动更新...再添加附件一栏选择问题截图,或其他文件; 如果你的...
uCGUI在stm32内核上的移植.pdf
打开 UCGUI390a\GUI,以下列出各个文件夹的作用 表格 uc/GUI
第20章emWin(UCGUI)XBF外置字体方法(官方推荐).pdf
第20章emWin(UCGUI)XBF外置字体方法(官方推荐)_...卡中读取字体的驱动,另一个建立一个对话框显 示...390,40,360,100,0,0}, 5, 10, 300, 70, 0...
uCGUI介绍(8)解析_图文.ppt
观察器可能解决这个问题,它能显示仿真的LCD窗 口和色彩窗口。观察器的执行文件...再次解析UCGUI390多对话... 6页 免费 解析UCGUI390多对话框支... 7页...
更多相关标签: