菜单数据结构及结构

合集下载

非阻塞模式LCD多级菜单的设计及其数据结构

非阻塞模式LCD多级菜单的设计及其数据结构

第16卷 第4期2007年10月 云南民族大学学报(自然科学版)Journal of Yunnan Nati onalities University (Natural Sciences Editi on )Vol .16 No .4Oct .20073 收稿日期:2007-06-18.作者简介:纳新(1971~),男(回族),硕士研究生,工程师,主要研究方向:嵌入式系统应用.非阻塞模式LC D 多级菜单的设计及其数据结构纳 新1 赵东风2(1、昆明冶研新材料股份有限公司,云南昆明650031;2、云南大学信息学院,云南昆明650091)摘 要 提出一种非阻塞模式LC D 多级菜单的设计,分析了菜单的树形结构,给出了菜单的状态转换模型及其菜单的核心数据结构.并分析菜单实现算法的较小空间复杂度和给出了其数据结构的C51的实现.关键词 非阻塞模式;LC D;多级菜单;数据结构;空间复杂度【中图分类号】TP31111【文献标识码】A【文章编号】1672—8513(2007)04-0347-03Design of Unbl ock Module LCD Multistage Menu and It ’s Data StructureNa Xin 1 Zhao Dongfeng2(1.Kun m ing Metallurgy Reserarch Ne w Materlals Co .,L td,Kun m ing 650031,China;2.Depart m ent of Co mmunicati on Engineering,College of I nfor mati on,Yunnan University,Kun m ing 650091,China )Abstract:This paper intr oduces a design of multistage menu,and analyzes the tree structure of it .A ls o,the state conversi on model and the core data structure of menu is given .The paper analyzes the s pace comp lexity of al 2gorithm s,it sho ws that the s pace comp lexity of our algorith m is l ower .The data structure of C51is als o obtained in this paper .Key words:unbl ock module;LCD;multistage menu;data structure;s pace comp lexity1 概述目前,使用LCD 模块作为智能仪表的人机接口已成为主流趋势,而软件实现菜单驱动的事件处理的人机交互方式,是目前实现人机交互的首选方式.如何在LCD 上实现多级菜单的操作也就成为了必须要解决的问题.LCD 上实现多级菜单的操作有多种方式,但大多都采用阻塞模式LCD 多级菜单设计.而阻塞模式LCD 多级菜单的设计会给操作带来很多不便.比如操作出现错误,系统就停顿下来等待正确的操作后才能进入下一步操作,如果操作者不能进行正确操作,那么系统将一直处于等待状态;进入底层菜单后,如只有单一退出键时,只能逐层推出.多种退出键时,又带来退出操作上的不便利等.非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该操作不会阻塞当前操作,而会立刻返回.非阻塞模式LC D 多级菜单的设计,使得各种操作后程序就返回到操作结束,不必等待正确的操作才结束菜单操作.操作的结果靠定义状态来表示,其关键在于定义了多种操作状态符,每当进入菜单操作后就判断操作状态来执行相应的操作.这种设计方式使得菜单的操作者,不因不正确的操作而使系统停顿下来,系统能较为方便的返回到工作状态等.2 硬件环境和LCD 菜单实现的功能在智能仪表的液晶显示设备中,目前广泛采用的是128×64图形点阵液晶模块.该类液晶可以实现16×16点阵的汉字4行8列,本文就是基于F M12864A -3图形点阵液晶模块实现非阻塞模式LC D 多级菜单的设计.同时将set (设置)、right (右移)、up (下移)、exit (退出)4个按键分别和单片机的I/O 口相连,这样就很容易实现按键值的读取和键值的判断.菜单设计为二级菜单,菜单形式如图1所示.仪表在工作状态下,按set 键进入一级菜单、按exit 键退出一级菜单;仪表在一级菜单下,按set 键进入二级菜单、按up 键滚动反色显示菜单条、按exit 退出743一级菜单,返回工作状态;在二级菜单下,按set 键进入参数设置状态、按right 和up 键进行参数修改、按exit 键退出二级菜单,返回工作状态.图1 菜单形式3 菜单状态转换模型非阻塞模式LCD 多级菜单设计的关键在于操作状态的定义.我们定义了五种操作状态,状态1为无操作状态:其状态标识符为假;状态2为进入一级菜单状态:其标识符为setup _select M enu;状态3为进入二级菜单:其状态标识符为setup _modi D ata .状态4为:在二级菜单中输入参数后有些参数需进行确认,其标识符为setup_confir m.状态5为超时退出(对于在不同状态下没有键操作,超过一定时间后会使菜单状态发生变化)菜单状态转化模型的可见图2所示.键操作后程序进入菜单程序,判断现程序处于何种状态,目前按何操作键,菜单状态根据判定进行转换,程序执行并不停顿下来.菜单状态转变后立即更新菜单状态.图2 菜单状态转换模型4 菜单数据结构的设计菜单的组织结构是一种树形结构,其结构如图3所示.此树形结构可以用长子兄弟法表示,其中左分支为长子,右分支为兄弟,表示结果见图4.由于菜单操作时,有时需在某一子菜单内反复操作,也就是在遍树结构时,需要有父节点的信息,才能较为方便的返回父节点.如果采用带双亲的链式二叉树,那么一个节点就必须多出3个指针(父亲指针,长子指针、兄弟指针)的存储空间.在单片机存储空间较为紧张的情况下,这是难以接受的.为此我们构造了一级菜单的数据结构和二级菜单的数据结构,通过一级菜单数据项的子项信息能寻址到二级菜单项,进而完成长子兄弟法对菜单树的表示[1].由于菜单的各项数据类型差别较大,难以用一种统一的数据类型来表示所有数据,于是将全体数据存入全体参数结构体中(见4.2),并设计了一种统一的参数项属性数据结构(见4.3).在遍历到二级菜单子节点时,首先读取该节点参数项属性,根据参数项属性和一级菜单中给出的二级菜单中第一子项的位置Par mOffset,计算出该节点的存储位置,并读取相应的数据后根据操作状态来进行操作.图3 菜单的组织结构图4 菜单树本文构造的数据结构实现如下:4.1 一级菜单的数据结构在菜单树中,一级菜单项为树结构前几层的兄弟节点,二级菜单项为一级菜单对应项的儿子节点.针对菜单树中的一级菜单项结点a 、b 、c,定义了如下结构体://一级菜单项结构typedef struct843云南民族大学学报(自然科学版) 第16卷{ucharMenuStrI d;//一级菜单名称字符串编号uchar Par mNu m;//相应二级菜单中子参数项数目uchar Par mOffset;//相应二级菜单中第一子项对应全体参数结构的位置}Main MenuStruct;实例化一级菜单:Main MenuStruct code Main2 Menu[3];当菜单状态转入setup_select M enu状态后,通过up键进行菜单滚动时,程序执行Menu I d++操作,得到相应的Main Menu[Menu I d]数据来得出相应一级菜单名称(菜单名称用于显示)和其长子的地址.对于一级菜单项节点,只需两个虚拟指针Par mNu m 和Par mOffset就可表示该树结构,其维持树形结构的空间复杂度为0(2n)[2].4.2 全体参数结构体对二级菜单中全部参数用如下结构体变量存储://全体参数结构typedef struct{uchar Pass wordU ser[4];//一级参数设置密码fl oat ST D;//校正液体密度fl oat S1;//校正液体计数率uchar Pass wordSys[4];//系统密码fl oat SSG;//悬浮固体密度…uchar LoadSettings;//恢复设置uchar Pass wordTri m[4];//输出设置密码…uchar SaveSettings;//保存设置}Par mStruct;实例化全体参数Par mStruct Par m;4.3 参数项属性数据结构参数项属性的结构体,可以表达全部各类参数的属性.其参数项属性结构体如下://参数项属性结构typedef struct{ucharMode; //参数类型ucharMax Value;//参数中某一位最大允许值(浮点参数固定为0~9)uchar T otal L en;//参数的总长度uchar Dec Len;//浮点参数的小数长度fl oatMaxFl oat;//浮点参数对应的上限值fl oatM inFl oat;//浮点参数对应的下限值uint16Offset;//某项对应全体参数结构的地址偏移量}Par mA ttrStruct;实例化参数项属性Par mA ttrStructcode Par mA ttr[24];当遍历二级菜单子节点时,根据某项参数其属性的Offset(某项对应全体参数结构的地址偏移量)和对应一级菜单项的Par mOffset(相应二级菜单中第一子项对应全体参数结构的位置)即可计算出其在Par mStruct中的位置,从而能从全部参数结构体中读出该参数.对于二级菜单项节点,只需1个虚拟指针Offset就可表示该树结构,其维持树形结构的空间复杂度为0(n)[3].由于二级菜单项节点数目远大于一级菜单项节点数,所以从算法的空间复杂度上可以看出,本算法的空间复杂度约为0(n),而带双亲的链式二叉树的空间复杂度约为0(3n).算法操作上也较为简单,能比较好地适应单片机存储空间较为紧张的环境.5 结论本文给出了一种非阻塞模式LCD多级菜单的设计,并在分析菜单结构的基础上,构造了一种特殊的长子兄弟法表示该菜单树,并分析了其较小的空间复杂度,能比较好地适应单片机存储空间较为紧张的环境.该方法已在作者开发的智能仪表上得到成功应用,其可广泛F应用于单片机系统的LCD多级菜单设计中.参考文献:[1] 李敏通,张战国.一种建立单片机应用系统菜单的新方法[J].计算机工程,2006,32(16):259-273.[2] 马忠梅,马岩,张凯,等.单片机的C语言应用程序设计[M].北京:北京航空航天大学出版社,1997.[3] 孙涵芳,徐爱卿.MCS-51/96系列单片机原理及应用[M].北京:北京航空航天大学出版社,1992.(责任编辑 万志琼)943第4期 纳新等:非阻塞模式LCD多级菜单的设计及其数据结构。

前端框架中的多级菜单设计与实现技巧

前端框架中的多级菜单设计与实现技巧

前端框架中的多级菜单设计与实现技巧多级菜单是一个常见的前端框架中的设计需求,它可以帮助用户在界面上更好地组织和管理信息,提供更好的用户体验。

在本文中,我将介绍多级菜单的设计与实现技巧,希望能对前端开发人员有所帮助。

首先,我们需要明确多级菜单的设计目标和需求。

多级菜单应该具有以下几个特点:可展开折叠、可选中高亮、支持无限层级、易于扩展和维护。

基于这些特点,我们可以采用以下方法来设计和实现多级菜单。

1. 使用树状数据结构:多级菜单往往是由一个层级嵌套的树状结构组成的。

我们可以通过使用树状数据结构来表示菜单项和菜单层级关系。

这样的数据结构可以方便地进行遍历、增加、删除和修改操作。

2. 递归生成菜单项:通过递归地遍历树状数据结构,我们可以生成相应的菜单项并将其渲染到页面上。

递归生成菜单项的好处在于,不管菜单有多少层级,我们都只需要一套相同的模板和方法即可。

3. 使用事件委托:多级菜单往往涉及到大量的点击事件处理。

为了避免为每个菜单项都绑定事件处理器,我们可以使用事件委托的方式来减少事件绑定的数量。

只需要将事件绑定到菜单容器上,然后根据事件的目标元素来处理相应的逻辑。

4. 利用 CSS 实现样式:多级菜单的样式设计也是重要的一部分。

我们可以利用 CSS 实现菜单项的样式,如背景颜色、文字颜色、字体大小等。

同时,利用CSS 也可以实现菜单项的展开和折叠效果,例如使用伪类和过渡来实现动画效果。

5. 考虑响应式设计:在设计多级菜单时,我们还需要考虑到不同设备和屏幕尺寸的适配。

可以通过使用媒体查询、flexbox 布局等技术来实现菜单的响应式设计,使其在不同的平台和终端上都能够良好地展示。

总结起来,设计和实现多级菜单需要考虑树状数据结构、递归生成菜单项、事件委托、利用 CSS 实现样式以及响应式设计等方面。

这些技巧可以帮助我们更好地实现多级菜单,提供更好的用户体验。

希望本文能对前端开发人员在多级菜单的设计与实现中提供一些帮助和启示。

element el-cascader 返回的数据结构 -回复

element el-cascader 返回的数据结构 -回复

element el-cascader 返回的数据结构-回复Element UI是一个非常流行的Vue.js组件库,提供了丰富的可复用的UI 组件,满足了前端开发者日常开发需求。

其中,el-cascader(级联选择器)是Element UI中的一个重要组件之一,用于在多级数据间进行联动选择。

在本文中,我们将以返回的数据结构为主题,一步一步回答有关el-cascader组件的相关问题,帮助读者理解这一组件的工作原理以及如何使用。

1. 什么是el-cascader?el-cascader是一个级联选择器,可以帮助开发者在多级数据间进行联动选择。

它由多个菜单组成,在选择某个菜单项后,会触发下一个菜单的内容更新。

通过嵌套和反映式的选择,它能够帮助用户快速定位到他们感兴趣的数据。

2. el-cascader的数据结构是怎样的?el-cascader的数据结构采用树形结构表示,在el-cascader组件中,需要传入一个名为options的属性,它是一个数组,数组中的每一个元素代表一个级别的数据。

每个级别的数据都应该是一个对象,该对象包含了该级别的菜单项以及下一级菜单的数据。

3. 如何使用el-cascader?使用el-cascader非常简单,主要包括三个步骤:引入组件、传入数据、处理选择事件。

首先,在Vue.js的项目中引入el-cascader组件,可以通过import语句引入,或者直接在HTML中引入Element UI的JS和CSS文件。

然后,在组件的使用位置使用el-cascader标签即可。

接下来,为el-cascader传入数据。

根据el-cascader的数据结构,我们需要创建一个适当的数据结构,并将其作为options属性传递给el-cascader。

可以通过在Vue组件中定义一个data属性来保存这个数据结构。

最后,通过监听el-cascader的change事件,可以获取当前选择的值,进而进行相应的处理。

《数据结构》实验指导书

《数据结构》实验指导书
四、实验说明
1.单链表的类型定义
#include <stdio.h>
typedef int ElemType;//单链表结点类型
typedef struct LNode
{ElemType data;
struct LNode *next;
2.明确栈、队列均是特殊的线性表。
3.栈、队列的算法是后续实验的基础(广义表、树、图、查找、排序等)。
六、实验报告
根据实验情况和结果撰写并递交实验报告。
实验四 串
一、预备知识
1.字符串的基本概念
2.字符串的模式匹配算法
二、实验目的
1.理解字符串的模式匹配算法(包括KMP算法)
typedef struct
{ElemType *base;
int front,rear;
} SqQueue;
4.单链队列的类型定义
typedef struct QNode
{QElemType data;
typedef struct list
{ElemType elem[MAXSIZE];//静态线性表
int length; //顺序表的实际长度
} SqList;//顺序表的类型名
五、注意问题
1.插入、删除时元素的移动原因、方向及先后顺序。
4.三元组表是线性表的一种应用,通过它可以更好地理解线性表的存储结构。同时矩阵又是图的重要的存储方式,所以这个实验对更好地掌握线性表对将来对图的理解都有极大的帮助。
六、实验报告
根据实验情况和结果撰写并递交实验报告。
实验六 树和二叉树
一、预备知识
1.二叉树的二叉链表存储结构

课程设计电话簿管理系统

课程设计电话簿管理系统

一.程序功能简介一个基本的电话簿管理程序,具有插入、删除、显示、修改和查询联系人电话码的功能。

主菜单如右图所示,每个菜单项功能如下:1.增加记录菜单:请输入用户姓名,如果该用户已经存在则添加失败,否则,输入用户的电话号码,进行添加。

2.修改某条记录:请输入用户姓名,如果没有该用户显示“该用户不存在”信息,否则,输出原电话号码,然后输入新的电话号码,进行修改。

3.删除记录:输入用户姓名,进行删除(删除时要进行确认)。

4.查询:输入用户姓名,进行查找。

5.排序:根据子菜单,选择不同的排序方式。

6.显示:逐屏显示(每屏显示10条记录)。

7.全删:进行全部删除(要确认)。

二.课程设计要求请选择以下功能1- 增加记录2- 修改记录3- 删除记录4- 查找(按姓名)5- 排序6- 显示记录1.用汉化菜单实现。

2.提供按姓名查询电话号码的功能。

3.显示功能(提供逐屏显示的功能,每屏显示10条记录)。

4.删除和修改时要进行确认。

5.将电话簿记录以文件的形式存在磁盘上;每次操作时将电话簿调出,操作完毕后存盘。

三.课程设计说明1.程序采用数组数据结构实现。

2.用类来实现数据的封装。

四.参考数据结构1.“电话簿”称为用户信息表,用数组实现。

用户信息表由若干用户信息构成,每个用户信息是一个数组元素。

2.“user.txt”是一个文件,用于保存“用户信息表”中的信息。

当系统启动时,从该文件中读入信息,当退出系统时,将“用户信息表”中的信息写到该文件中。

该文件中信息存放形式如下:ZhangHong 5221369LiLi 84891112ZhaoQiang 5221498其中name(姓名)占20列phone_num(电话号码)占12列五.具体功能及实现定义Fphone类,通过其私有成员数组name[20]和phone[12]分别记录用户姓名与电话号码,定义UserDatabase类记录用户信息,通过公有成员函数实现对数据的操作。

el-dropdown级联写法

el-dropdown级联写法

一、什么是el-dropdown级联写法el-dropdown是一个Vue.js开发的下拉菜单组件,它具有级联的写法,可以实现多层级的下拉菜单。

二、el-dropdown级联写法的基本语法要使用el-dropdown级联写法,首先需要在Vue组件中引入el-dropdown组件,并定义一个数据对象来存储级联菜单的数据结构。

然后在模板中使用el-dropdown组件,并通过数据对象来动态生成多层级的下拉菜单。

三、el-dropdown级联写法的示例下面是一个使用el-dropdown级联写法的示例代码:```vue<el-dropdown><span class="el-dropdown-link">下拉菜单<i class="el-icon-arrow-down el-icon--right"></i></span><el-dropdown-menu><el-dropdown-item>菜单1</el-dropdown-item><el-dropdown-item>菜单2</el-dropdown-item><el-dropdown-item><el-dropdown><span class="el-dropdown-link">子菜单<i class="el-icon-arrow-down el-icon--right"></i></span><el-dropdown-menu slot="dropdown"><el-dropdown-item>子菜单1</el-dropdown-item><el-dropdown-item>子菜单2</el-dropdown-item></el-dropdown-menu></el-dropdown></el-dropdown-item></el-dropdown-menu></el-dropdown>```在这个示例中,使用了el-dropdown组件和el-dropdown-item组件来构建一个两级的级联下拉菜单。

u8g2多级菜单原理 -回复

u8g2多级菜单原理 -回复

u8g2多级菜单原理-回复u8g2多级菜单原理:实现复杂显示效果的逐级菜单控件一、引言介绍(100-150字)u8g2多级菜单是一种用于显示复杂文字和图形的逐级菜单控件,基于u8g2图形库开发。

它提供了一种结构化管理菜单选项和层级关系的方法,使用户可以通过使用方向键和确定键进行导航和选择。

本文将详细介绍u8g2多级菜单的原理和实现步骤,旨在帮助读者理解u8g2多级菜单的工作原理以及如何开发和定制自己的逐级菜单。

二、什么是u8g2多级菜单(200-300字)u8g2多级菜单是一种以树形结构展示菜单选项的图形控件。

它使用u8g2图形库提供的功能来绘制文本、图标和边框等元素,实现了逐级展开、收起和选择的功能。

每个菜单选项都可以包含子菜单,用户可以通过方向键在不同的菜单选项之间进行导航,通过确定键选择某个菜单选项并进入子菜单。

该控件通过将菜单选项组织成树状结构,提供了一种有效管理和展示大量信息和选项的方式。

三、u8g2多级菜单的原理和实现逻辑(400-500字)u8g2多级菜单的实现原理可以概括为以下几个步骤:1. 初始化:首先,创建一个根菜单项,并设置当前菜单指针指向根菜单项。

根菜单项包含了所有的一级子菜单选项,以及每个子菜单选项对应的子菜单项数组。

2. 绘制:使用u8g2图形库提供的绘制函数,根据当前菜单指针指向的菜单项,将菜单选项的文本、图标和边框绘制到显示屏上。

3. 导航:在绘制菜单后,用户可以通过方向键(上、下、左和右)在不同的菜单选项之间进行导航。

根据用户的输入,更新当前菜单指针的位置,并根据需要重新绘制菜单。

4. 选择:当用户按下确定键时,记录当前菜单指针的位置,并根据当前菜单指针的指向进入下一级菜单。

重复步骤2和3,直到用户选择了最终的菜单选项。

5. 返回:在菜单的任何级别,用户都可以通过返回键返回上一级菜单。

通过管理一个菜单栈来记录菜单导航的历史,可实现返回菜单功能。

四、开发u8g2多级菜单的步骤与注意事项(500-600字)开发u8g2多级菜单需要以下几个关键步骤和注意事项:1. 创建菜单结构:首先,定义菜单结构和数据。

ruoyi vue项目三级菜单实现方法

ruoyi vue项目三级菜单实现方法

ruoyi vue项目三级菜单实现方法
Ruoyi Vue项目是一款管理系统框架,可以方便快捷地搭建出一个高效、安全、易用的管理系统。

在Ruoyi Vue项目中,实现三级菜单往往需要经过一些特定的步骤。

第一步是在后端代码中设置好对应的接口,该接口应该返回三级菜单中每一项的相关信息,包括菜单的名称、路径、图标等等。

在Ruoyi Vue项目中,可以使用多种后端框架,例如SpringBoot、SpringCloud等等。

第二步是在Vue前端代码中,编写相应的路由配置。

在路由配置中,需要设置好每一个菜单对应的路由路径以及需要显示的组件,还要考虑到多级嵌套的情况,需要嵌套使用Vue的Router组件来实现。

第三步是在前端代码的菜单组件中,根据后端接口返回的信息,生成三级菜单的数据结构,然后根据该数据结构渲染出菜单组件,同时还需实现菜单组件的点击事件,以跳转到对应的路由页面。

在实现Ruoyi Vue项目的三级菜单时,还需考虑到以下几个方面:
1. 数据结构的设计:针对不同的业务需求,可以设计出不同的数据结
构,以适应不同的菜单结构。

例如,在需要多级嵌套的情况下,可以使用树形结构表示。

2. 路由嵌套的实现:在实现嵌套路由时,需要注意路由匹配的顺序和路由的优先级,以确保路由能够正确匹配。

3. 菜单组件的可扩展性:在实现菜单组件时,需要考虑到菜单的可扩展性,即在后期业务需求变化时需要方便地对菜单进行修改,并保持菜单的稳定性和可靠性。

总之,通过以上步骤的实现,可以方便快捷地在Ruoyi Vue项目中实现三级菜单功能,以满足不同业务需求。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

如果编写简单的程序的话这个菜单函数就可以不用看了,但是当你编写到复杂的程序的时候就可能就会为人机界面和各个函数直接的连接而烦恼了,这个菜单函数就是用来解决这个问题,虽然没有UCGUI厉害,但是我觉得代码在2000行一下的话用起来还是不错的选择的.虽说简单但是用到了结构体大部分的知识了,希望c语言不太好的朋友自己补习一下好了.主要程序:CODE:#define Null 0/************************ 函数声明************************/void ShowMenu(void);void Menu_Change(unsigned char KeyNum);/************************ 按键功能键宏定义************************/#define UP '3'#define Down '7'#define Esc 'B'#define Enter 'F'#define Reset '0'/*********************** 目录结构体定义***********************/struct MenuItem{unsigned char MenuCount; //当前层节点数unsigned char *DisplayString; //菜单标题void (*Subs)(); //节点函数struct MenuItem *ChildrenMenus; //子节点struct MenuItem *ParentMenus; //父节点};/************************ 调用子函数区************************/void NullSubs(void){}//----------------------以下为例子,请根据实际情况修改---------------------------void TimeSet(void){put_s("TimeSet");}void DateSet(void){put_s("DateSet");}void AlertSet (void){put_s("AlertSet");}//------------------------------------------------------------------------------ CODE:/************************ 结构体区************************///----------------------以下为例子,请根据实际情况修改--------------------------- struct MenuItem TimeMenu[4];struct MenuItem FlashMenu[5];struct MenuItem VoiceMenu[5];struct MenuItem RobotMenu[5];struct MenuItem MainMenu[5];struct MenuItem TimeMenu[4]={ //MenuCount DisplayString Subs ChildrenMenus ParentMenus {4, "1.Time Set", TimeSet, Null, MainMenu},{4, "2.Date Set", DateSet, Null, MainMenu},{4, "3.AlertSet", AlertSet, Null, MainMenu},{4, "4.Back", NullSubs, MainMenu, MainMenu},};struct MenuItem FlashMenu[5]={ //MenuCount DisplayString Subs ChildrenMenus ParentMenus {5, "1.Flash Record", NullSubs, Null, MainMenu},{5, "2.Play", NullSubs, Null, MainMenu},{5, "3.Pause", NullSubs, Null, MainMenu},{5, "4.Flash Delete", NullSubs, Null, MainMenu},{5, "5.Back", NullSubs, MainMenu, MainMenu},struct MenuItem VoiceMenu[5]={ //MenuCount DisplayString Subs ChildrenMenus ParentMenus{5, "1.Voice Record" , NullSubs, Null, MainMenu},{5, "2.Play", NullSubs, Null, MainMenu},{5, "3.Pause", NullSubs, Null, MainMenu},{5, "4.Voice Delete", NullSubs, Null, MainMenu},{5, "5.Back", NullSubs, MainMenu, MainMenu},};struct MenuItem RobotMenu[5]={ //MenuCount DisplayString Subs ChildrenMenus ParentMenus{5, "1.Turn Left", NullSubs, Null, MainMenu},{5, "2.Turn Right", NullSubs, Null, MainMenu},{5, "3.Go Ahead", NullSubs, Null, MainMenu},{5, "4.Go Back", NullSubs, Null, MainMenu},{5, "5.Back", NullSubs, MainMenu, MainMenu},};struct MenuItem MainMenu[5]={ //MenuCount DisplayString Subs ChildrenMenus ParentMenus{5, "1.Time Set" , NullSubs, TimeMenu, Null},{5, "2.Voice Center", NullSubs, V oiceMenu, Null},{5, "3.Robot Control", NullSubs, RobotMenu, Null},{5, "4.Flash Option", NullSubs, FlashMenu, Null},{5, "5.Back", NullSubs, MainMenu, MainMenu},};//------------------------------------------------------------------------------CODE:/************************ 全局变量声明区************************/struct MenuItem (*MenuPoint) = MainMenu; //结构体指针,指向结构体后由内部函数指针指向功能函数unsigned char DisplayStart = 0; //显示时的第一个菜单项unsigned char UserChoose = 0; //用户所选菜单项unsigned char DisplayPoint = 0; //显示指针unsigned MaxItems; //同级最大菜单数unsigned char ShowCount=2; //同屏显示菜单数/************************显示函数区************************/void ShowMenu(void){unsigned char n;MaxItems = MenuPoint[0].MenuCount;//定义最大同级菜单DisplayPoint = DisplayStart;for(n=0;DisplayPoint<MaxItems&&n<ShowCount;n++){if(DisplayPoint==UserChoose)LCD_write_string(0,n,"->");LCD_write_string(2,n,MenuPoint[DisplayPoint++].DisplayString); }}void Menu_Change(unsigned char KeyNum){if(KeyNum){switch(KeyNum){case UP:UserChoose --;if (UserChoose ==255){UserChoose = 0;//上翻截至,如果要回滚赋值MaxItems-1}break;case Esc:if (MenuPoint[UserChoose].ParentMenus != Null){MenuPoint = MenuPoint[UserChoose].ParentMenus;UserChoose = 0;DisplayStart = 0;}break;case Down:UserChoose ++;if (UserChoose == MaxItems){UserChoose = MaxItems-1;//下翻截至,如要回滚赋值为0}break;case Enter:if (MenuPoint[UserChoose].Subs != NullSubs){(*MenuPoint[UserChoose].Subs)();}else if (MenuPoint[UserChoose].ChildrenMenus != Null){MenuPoint = MenuPoint[UserChoose].ChildrenMenus;UserChoose = 0;DisplayStart = 0;}break;case Reset:MenuPoint = MainMenu;UserChoose = 0;DisplayStart = 0;break;default:break;}if (UserChoose%ShowCount==0) //一屏只能显示ShowCount行DisplayStart = UserChoose;else if(UserChoose==1||UserChoose== 3)DisplayStart = UserChoose-1; //实现滚屏的关键LCD_write_command(0x01); //液晶清屏,根据不同液晶函数自行修改 delay_nms(5); //液晶为慢速器件ShowMenu();}}。

相关文档
最新文档