前段时间在做一个窗口项目,这个项目菜单项过多,在管理起来比较麻烦。想做一个高效移植又方便的一个切换机制。后来在网上多方查找这方面资料,但是感觉比较少。后来自己整理出了这个结构,希望对后来朋友有所帮助。

本结构不只局限与按键操作,同时也支持触摸切换,也可以两者共存同时对窗口进行操作。在按键操作过程中我想很多朋友都会遇到窗口焦点问题,内存不足问题等等。这个机制可以尽可能的解决这些问题。

首先先说下这个机制的主要思想。在感官上我们看到是这样子:开一个窗口会覆盖前一个窗口,再开新的窗口就会重复覆盖上一个窗口。而在退出窗口时就是一层一层恢复到前一级的窗口。以此反复。但是在嵌入式系统操作时用这种方式的话,就有点太耗内存了,菜单深度越多那么资源浪费就越多。那要怎么办呢?当然如果我们在进入下一个窗口时销毁上一个窗口就可以有效的解决这个问题。那么退出本级窗口该怎么办呢? 其实退出本级窗口和进入新窗口的性质是一样的,只不过这个新窗口是本窗口的前一级而非后一级。

我们的窗口每级每级是怎么连接在一起的呢?这里我采用的树的结构,一个大家很熟悉的模型树——二叉树。为什么用树呢,大家应该都清楚用树有几大好处:1)维护方便,在您的菜单中增加一个窗口或改变一个窗口位置应该是长有的事吧。那么在修改时我们也只需修改树中结点的位置就可以了,而不用改了位置又要去考虑改窗口名顺序等连带操作。当然这样也可以避免很多出错可能;2)合理使用资源,有多少窗口用开多少窗口的结点,而无须预留充足空间以被扩展。当添加新窗口只需在树中追加节点。

下面能过一个图型来地架构进行解说,如下图

首先先说下窗口的规则,我是以元素的右孩子为子菜单,左孩子为水平菜单。

这是我建立的一个简单事例,主窗口是一个码表盘。主窗口的下一层是一个列表窗口,列表窗口的内容是他的下层窗口的名子。“MenuTest”下层有四个菜单,前三个是列表窗口,最后一个是对话框窗口。 “MenuTest0”又有7个子菜单,前三个为列表窗口,第四个无窗口,第五个是对话框窗口,第六个是数字轴窗口,第七个是一个电字时钟。有人一定会问:只能在最右一排下建立子窗口吗。当然不是,我只是为了方便都在最右排建立子集,你也可以在MenuTest1或MenuTest2下建立,根据你的窗口需要对组合。完成这个树的建立,只通过了很少代码就完成了。完成这个功能只用了两步,1)建立元素,2)将元素链接到一起。 如果我有窗口想一直都在最顶层或有时显示有时不显示,不能和树结构整合到一起怎么办!其实在工程中有WIN_WindowsNumpad一个按键板,他就是一个不依赖在树中的独立窗口。是一个从始至终都会显示的窗口。这些窗口只要独立创建于树外就可以了,他的显示或不显示由你程序操作。

窗口实体就是建立的元素,下面对元素的内容进行详细的介绍:

树中每一个结点的内容如下:

typedef struct BiTreeElem{

DATA_TYPE           *data;              //数据元素

struct BiTreeElem   *Lift;              //窗口标题

struct BiTreeElem   *Right;             //窗口标题

}ELEMENT;

数据DATA_TYPE元素所指向的内容如下:

typedef const struct {

const char      *title;                 //窗口标题

WIN_INFO_TYPE   *win;                   //窗口信息

FunCBType       *enter;                 //窗口进入回调函数

FunCBType       *exit;                  //窗口退出回调函数

}MENU_INFO_TYPE;

通过注释消息可以看出每个元素的作用。这里需要说的FunCBType类型,这两个是回调函数,本窗口进入时运行*enter所指向的指针函数,退出时执行*exit所指向的数据。如果本窗口不需要执行这两个或其中的一个,可以让其指向0。

WIN_INFO_TYPE *win是窗口的相关消息,包括三个元素,内容如下:

typedef const struct{

void            *hWin;                  //窗口句柄

FunCBType       *create;                //窗口建立

FunCBType       *destroy;               //窗口回收

}WIN_INFO_TYPE;

*create指向特定窗口建立的回调函数,*destroy指向特定窗口销毁的回调函数,*hWin指向本窗口的句柄(备用)。

这里大家会发现为什么在结构体前加const ,这是因为嵌入式的资源都有限,这样只会占用ROM空间。还有个好处,就是不会被改变,增加可靠性。

好了,我们所用到的内容就是这三个结构体了。

1)    ELEMENT元素:以经在WIN_Tree.c文件中对其进行了封装。所有的树操作可以完全通过文件内API来实现,这样可以大大降低在树操作时可能出现的故障率。

2)    WIN_INFO_TYPE元素:我们所用到的所有窗口的界面。这里需要提的就是,在操作中有很多窗口是类型是相同的界面,只建立一个就可以了,比如像列表窗口,符合窗口的重复利用性。如果窗口是特有功能和界面的就必须单独建立了。

3)    MENU_INFO_TYPE 元素:一个结点必须有一个这个元素。

本结构的主要文件

WIN.c

WIN.h

结构初始化,树建立等等。

WIN_Tree.c

WIN_Tree.h

树相关API。

WIN_Windows.c

WIN_Windows.h

所有的窗口元素。窗口的建立,销毁,接口等操作。如果建立新窗口或是独立的窗口,般命名规则:WIN_WindowsXxxxx.c

WIN_Context.c

WIN_Context.h

窗口调度相关操作,包括窗口进入,退出等。

WIN_OS.c

WIN_OS.h

如果您的GUI运行在OS平台,可对其进入修改,现工程已经集成了uCosII,uCosIII,win32。

根据你的OS加载对应的头文件就可以了。

uCosII加载"ucos_ii.h";

uCosIII加载"os.h ";

win32及其它平台可以 宏定义#define _WIN32_即可。

WIN_API.c

WIN_API.h

WINAPI_Type.h

所有外部的接口文件,包括获取外部的数据或外部操作显示屏的数据刷新等。

WIN_API.h对外调用接口:就是在文件如果要用到窗口操作,只加载这个接口头文件就可以了。

WINAPI_Type.h 内部调用文件。

使用本操作接口,如果添加一个新的窗口,主要的工作就是写一个新窗口的建立,销毁,接口这三个函数。并在WINAPP_xxx.c中将其连接到树中。

接口细节:

WIN_API 接口部分相对比较难理解,这里需要进行讲解下。这里所有的接口分为两类,1)对外接口,2)对内接口。

对外接口:就是显示函数更新等操作,可被外部调用的函数。在这里所有的本地函数最好都在同一个任务中进行,这样可以减少其它任务栈的使用量,以及避免多任务互斥引起的问题。如果才可以保证函数只在本任务中被调用呢,有个方法就是外部任务在调用本地函数时,把其函数地址及函数参数放入缓冲区,在本地任务中对缓冲区进行事实扫描就可以了。这样可以很好的解决。实现这些方法有很多种,这里我所用的方法是一个相对复杂但是对模块划分及资源高效性考虑的一个方法。把所有接口函数划分为三大类,1)一个整形参数的函数,2)两个整形参数的函数,3)一个字符串函数的函数。大部分的接口函数可以划分成这三个函数。外部调用时把这三个函数装入FIFO中,在任务中实时的对FIFO进行获取并执行。

对内接口:就是外部任务所提供的一些函数,比如说LCD要显示的一些参数等操作。主要可以分为两类:一类是GET,一类是SET。这里我是把这两个类型定义成一个结构体数组中WINAPI_INF_TYPE,在接口函数中只要定义一个常量,内容为“对内接口”一个GET一个SET。当不赋值时,对内接口为空。这样最大的好处就是,不用在你的程序中重复去调用“对内接口”函数的头文件。所有的接口都在WIN_API.c中,这样也增加了您程序的移植性。

以下为工程代码:

http://pan.baidu.com/share/link?shareid=2249960431&uk=118334538

可以用vs2008打开。

视频http://www.tudou.com/programs/view/D-gK-_SLjUA/#

2014-11-24工程进行了更新:

http://www.cnblogs.com/hiker-blogs/p/4119775.html

uCGUI 按键窗口切换机制的更多相关文章

  1. uCGUI 按键窗口切换机制(更新篇)

    在之前文章中,讲述了一个低内存使用量的的窗口切换机制.有人会问,低内存使用量是多低呢,我这里举个例子.我有一个项目中使用到本切换机制,128*64的单色屏,初步计算有105个窗口(后面还会增加),总内 ...

  2. qt布局管理-缩放、多窗口切换

    关于缩放的布局 所有控件要求与主窗口同时缩放,那么在所有控件设置好布局后,最后点击最外侧的主控件,选择水平布局或者垂直布局即可. 另外每个空间的属性可更改,如SizePolicy用于设置空间是否可缩放 ...

  3. Win+Tab键实现自定义程序列表间的窗口切换

    程序是用AutoHotkey语言写的, 说明: 以自己使用频率的顺序在ExeList自定义的程序间切换 切换可以以所有窗口切换,也可以按程序组切换(比如在word窗口间切换) 程序组可以分别定义排除的 ...

  4. ubuntu 18.04多应用窗口切换的快捷键使用指南

    前记 使用ubuntu时间长了,很厌烦用鼠标来点来点去.重复操作的,还是快捷键比较方便.在多窗口切换方面,熟悉了几个快捷键之后,顿时感觉神清气爽.这里就推荐给大家学习一下,提高工作效率啊. 常用快捷键 ...

  5. 如何使用cgdb(一)——窗口切换

    cgdb是一个轻量级的基于控制台的多窗口gdb调试界面.除了标准的gdb控制台之外,cgdb还提供了一个分屏视图,可以在执行的时候显示具备语法高亮的源代码.键盘控制是仿照vim设计的,所以vim用户使 ...

  6. Qt界面编程之多窗口切换

    1.基础知识 信号和槽 信号和槽都是函数,用来完成信号间的协同操作 2.多窗口切换实例       功能 实现登录和重新登录功能 组成 登录界面 和主窗体界面 3.源代码提供  

  7. selenium测试(Java)--多窗口切换(十三)

    selenium测试(Java)--多窗口切换(十三) 如果遇到点击按钮或链接后出现新窗口的情况,就需要使用窗口切换的方法. 本例中就是先打开百度搜索界面,然后利用js打开一个百度新闻界面,然后通过s ...

  8. eclipse中的窗口切换快捷键

    Ctrl+Shift+F6 很简单,如果以后改用IDEA的话就没用了,但这个窗口切换确实很复杂,看起来也操作比较快.

  9. selenium多个窗口切换

    浏览器里面支持多窗口打开,例如这样: html里面写了: target="_blank" 造成新打开一个窗口,但是selenium不会自动跳转到新的串口,需要自己切换: # 你打开 ...

随机推荐

  1. java代理ip有效检测

    java实现代理ip有效检测,依赖Apache的HttpClient   正式版:       /**        * 批量代理IP有效检测        *        * @param pro ...

  2. javax.mail Java Extension(扩展)

    http://baike.baidu.com/view/616724.htm JavaMail,顾名思义,提供给开发者处理电子邮件相关的编程接口.它是Sun发布的用来处理email的API.它可以方便 ...

  3. Java Learning Path(五)资源篇

    Java Learning Path(五)资源篇 1. http://java.sun.com/ (英文) Sun的Java网站,是一个应该经常去看的地方.不用多说. 2.http://www-900 ...

  4. Android中关于cursor类介绍

    使用过 SQLite 数据库的童鞋对 Cursor 应该不陌生,如果你是搞.net 开发你大可以把Cursor理解成 Ado.net 中的数据集合相当于dataReader.今天特地将它单独拿出来谈, ...

  5. Android给力模拟器,秒杀原生模拟器到渣

    1 http://www.eoe.cn/news/17433.html?f_section=new&f_section=new 备注:1秒开机,操作超流畅

  6. IBM Rational Appscan使用之扫描结果分析

    转自:http://www.nxadmin.com/penetration/825.html 之前有IBM Rational Appscan使用详细说明的一篇文章,主要是针对扫描过程中配置设置等.本文 ...

  7. YUV图像合成原理

    http://blog.csdn.net/zwz1984/article/details/50403150 http://zhongcong386.blog.163.com/blog/static/1 ...

  8. macOS 安装安卓模拟器 并用charles抓包

    mac上面安装安卓模拟器并能使用charles抓包软件调研 一.Genymotion 1.先下载Virtua Box虚拟机 https://www.virtualbox.org/wiki/Downlo ...

  9. Swing实现系统托盘

    /* 实现系统托盘化 */ protected void setToolSystemTray() { // 系统是否支持系统托盘 if (SystemTray.isSupported()) { // ...

  10. Carthage:去中心化的Cocoa依赖管理器

    Cocoa的依赖管理器,我们已经有了CocoaPods,非常好用,那么为什么还要创建这样一个项目呢?本文翻译自Carthage的Github的README.md,带大家来了解一下这个工具有何不同之处. ...