一种嵌入式系统中多级菜单的构建与显示方法技术领域
本发明涉及一种嵌入式系统中多级菜单的构建与显示方法,具体涉及一种基于链
表、树、数组的混合数据结构实现多级菜单构建与显示的方法。
背景技术
由于嵌入式系统的软硬件资源限制,操作系统通常无法直接提供合适的个性化、
人性化的操作接口。传统的基于键盘与LCD显示屏组合的人机交互方式大多通过函数的嵌
套来实现菜单的操作,该方法需要开发人员对键盘、LCD显示屏、数据接口等知识有深入的
了解,因此维护成本较大、维护方法复杂,不利于产品的快速迭代。
发明内容
针对上述问题,本发明提供一种嵌入式系统中的、基于链表、树、数组的混合数据
结构实现多级菜单构建与显示的方法。
为解决上述问题,本发明具体包括以下步骤:
一、多级菜单的构建。
1、子菜单结构体的构建;
子菜单结构体中,每个子菜单的数据结构包括五列内容,第一列为菜单名称,即显
示设备上所显示的名称;第二列为菜单类型,即功能菜单或级联菜单;第三列为指针,即指
向级联菜单或功能菜单的复用指针,级联菜单指向的为下一级数组的入口地址,功能菜单
指向的是具有特定显示功能的函数的指针,当用户点击确认按键时,系统将运行这个函数,
这个函数可以用来显示其他数据、图形、或者执行特定指令等个性化的内容,该函数执行完
毕将重新返回菜单界面;第四列为菜单预处理函数,即进入菜单之前的操作,例如输入密
码、或者从存储器中读取参数等,该组函数具有返回值,返回“是”则允许进入该菜单,返回
“否”则禁止进入该菜单;第五列为菜单后处理函数,用于对用户退出菜单时进行一些后续
处理的工作,即用于对用户的操作的数据进行存储等。
2、用于组织子菜单的单级菜单数组的构建;
单级菜单是由若干个子菜单构成的一组表述不同功能的菜单组合。若干个单级菜
单组合起来就是多级菜单。
单级菜单数组的内容为需要显示的菜单项数组。数组大小利用编译器初始化,不
手工设置。
需要特别强调的是:每个单级菜单都以“结束”菜单结尾,该菜单不显示,仅用于标
记单级菜单结束。
3、所有的单级菜单级联起来,即可组成为树形结构的多级菜单。
4、选中菜单结构体的构建;
选中菜单结构体的数据结构共包括四列内容,第一列为菜单源,具体就是一个指
针;第二列为当前级菜单总数;第三列为当前选中菜单序号,由0开始;第四列为当前级菜单
最大需显示宽度。
5、用于记录菜单选择路径的菜单路径链数组的构建。
二、多级菜单的显示。
多级菜单的显示,是指通过液晶屏等终端以图形与文字的方式向用户展示产品功
能与内容,具体实现时可依据显示屏的大小显示为多级菜单、单级菜单或单个菜单。
本发明是利用表述函数来实现多级菜单的显示功能的。所述的表述函数的作用,
是维护菜单链路径、传输给显示器需显示的内容,即连接菜单数据结构与硬件。表述函数具
有以下模块:菜单路径维护模块、单级菜单处理模块、显示模块、调度模块。
菜单路径维护模块负责维护菜单路径链数组,通过指针实现菜单的层级间转移。
当用户进入第一级菜单时,例如由屏保进入菜单,初始化为根菜单的首地址。当用户进入下
级菜单或退出本级菜单,指向当前级菜单数组的下一个元素或上一个元素;当所指向菜单
层级大于菜单最大级数时,不进行层级转移,当当前级菜单指针位于第一层菜单收到返回
命令时退出菜单显示。
单级菜单处理模块负责用户每次进入新一级菜单时,利用当前级菜单指针初始化
菜单路径链数组的元素。该模块利用菜单源指针获取当前级菜单数组的首地址,由菜单数
组的首地址开始查找名称为“END”的菜单从而获得当前级菜单的总数,并设置为当前级菜
单所有菜单名称的最大长度。当前选中菜单序号被初始化为0,每次用户在单级菜单中移动
选中菜单时当前选中菜单序号随之增大或减小,当前选中菜单序号的值始终为当前选中菜
单项在其所处菜单数组中的位置序号,由0开始。
显示模块负责根据菜单路径链数组与当前级菜单指针使显示器显示当前选中菜
单。显示模块根据不同显示器的大小,可以有选择性的显示为多级菜单或单级菜单或单个
菜单。
显示模块在显示级联菜单时,在名称后面加‘>’标识。在无法完全显示单级菜单时
加‘……’标识。显示模块将当前选中菜单以及父菜单以反显方式显示以起到突出作用,比
如黑底白字或者红底白字,用于告知用户当前选中的菜单。
调度模块负责接收用户下发的命令,例如:上、下移动菜单,进入或退出菜单。当用
户进入功能菜单时,调度模块判断该菜单项目的预处理函数指针是否为空,若是,则直接调
用级联菜单或者功能菜单的指针;若不是则调用预处理函数,预处理函数返回“是”则调用
级联菜单或者功能菜单的指针,否则不进入菜单。
当用户进入级联菜单时,调度模块判断该菜单项目的预处理函数指针是否为空,
若是,则直接调用菜单路径维护模块进入下级菜单;若不是则调用预处理函数,预处理函数
返回“是”则调用菜单路径维护模块进入下级菜单,否则不进入下级菜单。
当用户上、下移动菜单时,调度模块将调用单级菜单处理模块。
当用户退出功能菜单时,调度模块调用显示模块,显示模块将显示当前选中的菜
单。
当用户退出级联菜单时,调度模块调用菜单路径维护模块来维护当前级菜单指
针。
本发明根据对数据结构、菜单种类、需求、样式的深入理解,提出了一种菜单数据
与维护函数相对独立的菜单组织与显示方法,菜单数据改动灵活,可满足个性化、人性化需
求,维护函数仅需一次即可应用于同系列硬件平台的所有产品。本发明通过抽象的数据结
构将不同种类的软硬件开发环境隔离开来,实现了菜单维护的方便、快捷、个性化、人性化。
附图说明
附图1 多级菜单、单级菜单、单个菜单的显示效果示意图;
附图2 树形结构的多级菜单的结构示意图。
具体实施方式
下面结合附图,说明该发明的具体实施方式。实施例中所述的数据结构以C语言形
式实现,但C语言不是唯一的实现该数据结构的方式。
步骤一:构建子菜单结构体,如下所示:
上述子菜单结构体中name为菜单的显示名称,type为菜单的类型(功能或级联),
ptr为指向级联菜单或功能函数的复用指针,byfunc为菜单预处理函数(用于进入菜单之前
的操作,例如输入密码等),vfunc为菜单后处理函数(用于对用户的操作的数据进行存储
等)。
步骤二:构建单级菜单数组,如下所示:
单级菜单数组类型为sMenuArray结构体。数组内容为需要显示的菜单项数组。数
组大小利用编译器初始化,不手工设置。示例中数组的第一列为菜单名称,显示器显示的即
为该名称。第二列为菜单类型:CascadeMenu(级联菜单)与FunctionMenu(功能菜单)为两个
宏。第三列为复用指针:级联菜单指向的为下一级数组的入口地址,功能菜单指向的是具有
特定显示功能的函数的指针。第四列为预处理函数:用于进入菜单前的预处理工作,例如要
求用户输入密码,或者从存储器中读取参数,该组函数具有返回值,返回TRUE则允许进入该
菜单,返回FALSE则禁止进入该菜单。第五列为后处理函数,用于对用户退出菜单时进行一
些后续处理的工作,例如数据的保存。需要特别强调的是:每个单级菜单都以“END”菜单结
尾,该菜单不显示,仅用于标记单级菜单结束。
步骤三:所有的菜单级联起来,即可组成为树形结构的多级菜单,如附图2所示。
步骤四:构建选中菜单结构体,如下所示:
上述结构体中:pSource为菜单源,byTotal为当前级菜单总数,byNum为当前选中
菜单序号(由0开始),byMAXLenth为当前级菜单最大需显示宽度。
步骤五:构建用于记录菜单选择路径的菜单路径链数组,如下所示:
sMenuList sMenuChain[MaxMenuLevel];//菜单路径链数组
MaxMenuLevel为菜单最大级数的宏。
步骤六:利用表述函数实现显示功能。
表述函数具有以下模块:菜单路径维护模块、单级菜单处理模块、显示模块,调度
模块。
1)菜单路径维护模块。
菜单路径维护模块负责维护菜单路径链数组,通过以下指针实现菜单的层级间转
移。
sMenuList*sCurMenu=NULL;//当前级菜单指针
用户进入第一级菜单时,例如由屏保进入菜单,sCurMenu被初始化为菜单路径链
数组sMenuChain的第一个元素的地址,初始化该元素的pSource为菜单树形结构的首地址
sMenuRoot。每当用户进入下级菜单或退出本级菜单,sCurMenu指向sCurMenu数组的下一个
元素或上一个元素,当sCurMenu所指向菜单层级大于MaxMenuLevel时,不进行层级转移,当
sCurMenu位于第一层菜单收到返回命令时退出菜单显示。
2)单级菜单处理模块
单级菜单处理模块负责用户每次进入新一级菜单时利用sCurMenu指针初始化
sMenuChain的元素,该模块利用pSource指针获取当前级菜单数组的首地址,由菜单数组的
首地址开始查找名称为’END’的菜单从而获得当前级菜单的总数byTotal,并将byMAXLenth
设置为当前级菜单所有菜单名称的最大长度。byNum被初始化为0,每次用户在单级菜单中
移动选中菜单时byNum随之增大或减小,byNum的值始终为当前选中菜单项在其所处菜单数
组中的位置序号(由0开始)。
3)显示模块。
显示模块负责根据菜单路径链数组sMenuChain数组与sCurMenu使显示器显示当
前选中菜单。
显示模块根据不同显示器的大小,可以有选择性的显示为多级菜单,单级菜单或
单个菜单。
显示模块在显示级联菜单时在名称后面加‘>’标识。
在无法完全显示单级菜单时加‘……’标识。
显示模块将当前选中菜单以及父菜单反显,用于告知用户当前选中的菜单。
如图1所示,就是用户在多级菜单中选择了“信息查看”、“保护状态”、“开关量”选
项之后,在多级菜单、单级菜单、单个菜单三种不同显示模式下所分别呈现出来的显示效
果。
4)调度模块。
调度模块负责接收用户下发的命令,例如上、下移动菜单,进入或退出菜单。
当用户进入功能菜单时:调度模块判断该菜单项目的预处理函数指针byfunc是否
为空,若是,则直接调用void(*ptr)()函数;若不是则调用char(*byfunc)()预处理函数,
预处理函数返回TRUE则调用void(*ptr)(),否则不进入菜单。
当用户进入级联菜单时:调度模块判断该菜单项目的预处理函数指针byfunc是否
为空,若是,则直接调用菜单路径维护模块进入下级菜单;若不是则调用char(*byfunc)()
预处理函数,预处理函数返回TRUE则调用菜单路径维护模块进入下级菜单,否则不进入下
级菜单。
当用户上、下移动菜单时,调度模块将调用单级菜单处理模块。
当用户退出功能菜单时,调度模块调用显示模块,显示模块将显示当前选中的菜
单。
当用户退出级联菜单时,调度函数调用菜单路径维护模块来维护sCurMenu指针。