完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
前段时间在做一个窗口项目,这个项目菜单项过多,在管理起来比较麻烦。想做一个高效移植又方便的一个切换机制。后来在网上多方查找这方面资料,但是感觉比较少。后来自己整理出了这个结构,希望对后来朋友有所帮助。 本结构不只局限与按键操作,同时也支持触摸切换,也可以两者共存同时对窗口进行操作。在按键操作过程中我想很多朋友都会遇到窗口焦点问题,内存不足问题等等。这个机制可以尽可能的解决这些问题。 首先先说下这个机制的主要思想。在感官上我们看到是这样子:开一个窗口会覆盖前一个窗口,再开新的窗口就会重复覆盖上一个窗口。而在退出窗口时就是一层一层恢复到前一级的窗口。以此反复。但是在嵌入式系统操作时用这种方式的话,就有点太耗内存了,菜单深度越多那么资源浪费就越多。那要怎么办呢?当然如果我们在进入下一个窗口时销毁上一个窗口就可以有效的解决这个问题。那么退出本级窗口该怎么办呢? 其实退出本级窗口和进入新窗口的性质是一样的,只不过这个新窗口是本窗口的前一级而非后一级。 我们的窗口每级每级是怎么连接在一起的呢?这里我采用的树的结构,一个大家很熟悉的模型树——二叉树。为什么用树呢,大家应该都清楚用树有几大好处: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 元素:一个结点必须有一个这个元素。 本结构的主要文件
使用本操作接口,如果添加一个新的窗口,主要的工作就是写一个新窗口的建立,销毁,接口这三个函数。并在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/# 在之前文章中,讲述了一个低内存使用量的的窗口切换机制。有人会问,低内存使用量是多低呢,我这里举个例子。我有一个项目中使用到本切换机制,128*64的单色屏,初步计算有105个窗口(后面还会增加),总内存使用量(包括任务栈)=105*3*4(窗口树) + 1024(公共buff) + 512(任务栈) + 1024*3(uCGUI动态内存) = 6k左右。从这个数字可以看出内存算是使用比较少的了。毕竟有100多个窗口,我在设计时也就只做了10多个窗口,这100多个窗口就是由10多个窗口大量复用组合得到的。 当然本切换机制只是给读者提供一个灵感,不一定就按笔者的框架来做项目,可以只使用这种思想打造更优秀的架构。毕竟项目千差万别,本架构更适合使用按键来切换窗口的用户,低内存的用户,窗口深度级深及多的用户。 在前一篇文章中有读者留言,问了很多问题,之前的窗口确实有很多不完善的地方。这里我直把以前的工程进行升级,主要完善原工程中缺失部分。更新内容主要如下: 1,增加高级窗口(突发事件窗口)切换代码。 2,增加多语言支持接口。 3,接口变更,去除之前繁琐的外部调用接口。 这里还要讲点本机制的特点,本切换机制只进行在一个任务中,也就类似一个大while(1)循环,这样的操作有他特有的优点,第1可以共有一个大公共buff而不用担心内存互斥问题。这时一定会有朋友会问,外部任务调用时如何操作呢?这里我把供外部调用的接口统称为“外部调用接口”。“外部调用接口”我之前的处理方式是,外部任务调用gui内部函数时,把gui内部的函数指针及参数部分同时存入队列中,直到gui运行到读队列时,运行这些函数。这样就可以很好解决互斥问题。后来我发现,这种方式过于繁琐,以至于有大量的函数需要进行注册。现在做了一定修改,只把要传递的参数保存在中间变量中,gui运行时查询是否有参数变更,如果有运行变更部分的代码。这样大大简化了程序复杂度,也更容易理解。 有人可能会担心这窗口机制的移植性问题。这里我要说下,本窗口我在vc,linux,ucos-ii,ucgui-iii等平台都进行过使用,表现都非常良好,做到了一套代码多平台使用。 中文显示,我只做了简单演示,只把三个窗口使用了中文。 工程链接: http://pan.baidu.com/s/1hqoZgAo |
|
|
相关推荐
|
|
|
编译缺少MicriumLogo_1bpp.c
|
|
|
|
|
|
|
|
169 浏览 0 评论
STM32F405驱动DS1302时钟模块,输出时间错乱该怎么排查?
4077 浏览 2 评论
stm32f405rgt6驱动DS1302ZN出现时间错乱问题
2880 浏览 1 评论
stm32用fsmc读取ad7606采集数据,数据不变,只有开发版复位才更新数据
2564 浏览 0 评论
2690 浏览 1 评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-8 09:00 , Processed in 0.669430 second(s), Total 69, Slave 51 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖