轻量级多级菜单控制框架程序(C语言)
1、前言
作为嵌入式软件开发,可能经常会使用命令行或者显示屏等设备实现人机交互的功能,功能中通常情况都包含 UI 菜单设计;很多开发人员都会有自己的菜单框架模块,防止重复造轮子,网上有很多这种菜单框架的代码,但是大多耦合性太强,无法独立出来适配不同的菜单设计。
本文介绍一个降低了耦合性,完全独立的菜单框架,菜单显示风格和显示平台完全由自己根据需求设计,而菜单操作统一由菜单模块处理即可,提高程序的移植性。
2、介绍
菜单框架代码主要特点有:
- 采用链表方式实现多级菜单(通过配置选择采用动态分配或者数组实现)
- 菜单框架作为独立模块,拒绝和按键模块、显示模块进行耦合
- 在十分独立的情况下,也保证不受菜单的显示风格和显示平台影响,可自由选择设计显示风格和显示平台
- 快捷菜单操作等
- 可以采用表驱动的方式初始化菜单,提高代码的可读性
3、代码功能
源文件部分代码如下:
/**
* @brief 菜单初始化
*
* @param[in] pMainMenu 主菜单注册信息
* @param[in] num 主菜单数目
* @param[in] fpnShowMenu 主菜单显示效果函数
* @return 0,成功; -1,失败
*/
int Menu_Init(MenuRegister_t *pMainMenu, uint8_t num, ShowMenuCallFun_f fpnShowMenu)
{
MenuCtrl_t *pMenuCtrl = NULL;
#if MENU_MAX_DEPTH != 0
sg_currMenuDepth = 0;
#endif
if ((pMenuCtrl = NewMenu()) != NULL)
{
pMenuCtrl->pLastMenuCtrl = NULL;
pMenuCtrl->pfnShowMenuFun = fpnShowMenu;
pMenuCtrl->pMenuInfo = pMainMenu;
pMenuCtrl->menuNum = num;
pMenuCtrl->currPos = 0;
pMenuCtrl->isRunCallback = 0;
sg_tMenuManage.pCurrMenuCtrl = pMenuCtrl;
return 0;
}
return -1;
}
头文件部分代码如下:
/**
* @brief 菜单信息注册结构体
*
*/
typedef struct MenuRegister
{
const char *pszDesc; /*!< 当前选项的中文字符串描述 */
const char *pszEnDesc; /*!< 当前选项的英文字符串描述 */
menusize_t subMenuNum; /*!< 当前选项的子菜单数目, 子菜单数目为0则表示下一级非菜单界面, 会执行非菜单功能函数 */
struct MenuRegister *pSubMenu; /*!< 当前选项的子菜单内容 */
ShowMenuCallFun_f pfnShowMenuFun; /*!< 当前选项的子菜单显示效果函数, 为NULL则延续上级菜单显示效果 */
MenuCallFun_f pfnEnterCallFun; /*!< 当前选项确定进入时需要执行的函数, 为NULL不执行 */
MenuCallFun_f pfnExitCallFun; /*!< 当前选项进入后在退出时需要执行的函数, 为NULL不执行 */
MenuCallFun_f pfnRunCallFun; /*!< 当前选项的非菜单功能函数, 只有当菜单数目为0有效, 为NULL不执行 */
void *pExtendData; /*!< 当前选项的菜单显示效果函数扩展数据入参, 可自行设置该内容 */
}MenuRegister_t;
/* Exported constants ------------------------------------------------------------------------------------------------*/
/* Exported macro ----------------------------------------------------------------------------------------------------*/
#define GET_MENU_NUM(X) (sizeof(X) / sizeof(MenuRegister_t))
/* Exported functions ------------------------------------------------------------------------------------------------*/
/* 菜单初始化和反初始化 */
extern int Menu_Init(MenuRegister_t *pMainMenu, uint8_t num, ShowMenuCallFun_f fpnShowMenu);
extern int Menu_DeInit(void);
/* 菜单功能设置 */
extern menubool Menu_IsEnglish(void);
extern int Menu_SetEnglish(menubool isEnable);
/* 菜单选项显示时需要使用的功能扩展函数 */
extern int Menu_UpdateShowBase(MenuShow_t *ptMenuShow, menusize_t showNum);
/* 菜单状态获取函数 */
extern menubool Menu_IsRun(void);
extern menubool Menu_IsMainMenu(void);
extern menubool Menu_IsAtMenu(void);
/* 菜单操作 */
extern int Menu_Reset(void);
extern int Menu_Enter(void);
extern int Menu_Exit(uint8_t isReset);
extern int Menu_SelectPrevious(uint8_t isAllowRoll);
extern int Menu_SelectNext(uint8_t isAllowRoll);
/* 菜单轮询处理任务 */
extern int Menu_Task(void);
4、示例代码显示效果
示例代码采用的平台是命令行输出输入显示效果
demo中提供了如何实现图形菜单(主菜单有点粗糙)、普通列表菜单、右侧弹窗菜单(更多设置)等效果演示,菜单样式可自由扩展,足够自由;快捷菜单操作、中英文切换演示。(windows中编译需要将 demo.c转 GBK 编码,Linux 转 utf8 编码,不然可能出现汉字乱码的问题)

以下是通过单片机驱动 OLED 显示的菜单界面显示效果

5、示例代码获取链接
下载链接点击:轻量级菜单框架(最新的功能可切换 develop 分支)
轻量级多级菜单控制框架程序(C语言)的更多相关文章
- 单片机C语言下LCD多级菜单的一种实现方法
摘要: 介绍了在C 语言环境下,在LCD 液晶显示屏上实现多级嵌套菜单的一种简便方法,提出了一个结构紧凑.实用的程序模型. 关键词: 液晶显示屏; 多级菜单; 单片机; C 语言; LCD 中 ...
- Python基础-小程序练习(跳出多层循环,购物车,多级菜单,用户登录)
一. 从第3层循环直接跳出所有循环 break_flag = False count = 0 while break_flag == False: print("-第一层") wh ...
- MVC5+EF6 入门完整教程13 -- 动态生成多级菜单
稍微有一定复杂性的系统,多级菜单都是一个必备组件. 本篇专题讲述如何生成动态多级菜单的通用做法. 我们不用任何第三方的组件,完全自己构建灵活通用的多级菜单. 需要达成的效果:容易复用,可以根据mode ...
- 谈谈MSP430 的框架程序
最近在学习MSP430f149这块单片机,开始程序也没烧进去,弄了一天,发现串口不能下载,买了个jtag下载器,才搞定.现在也谈谈开始写程序的一些方法吧 程序重要的是框架,有这个基础之后才能行云流水的 ...
- Vue2 实现树形菜单(多级菜单)功能模块
结构示意图 ├── index.html ├── main.js ├── router │ └── index.js # 路由配置文件 ├── components # 组件目录 │ ├── App. ...
- 微信小程序开发语言的选择
微信使用的开发语言和文件很「特殊」. 小程序所使用的程序文件类型大致分为以下几种: ①WXML(WeiXin Mark Language,微信标记语言) ②WXSS(WeiXin Style Shee ...
- WPF权限控制框架——【4】抛砖引玉
写第一篇"权限控制框架"系列博客是在2021-01-29,在这不到一个月的时间里,收集自己零碎的时间,竟然写出了一个"麻雀虽小,五脏俱全"的权限控制框架:对于一 ...
- 前端开发css实战:使用css制作网页中的多级菜单
前端开发css实战:使用css制作网页中的多级菜单 在日常工作中,大家都会遇到一些显示隐藏类菜单,比如页头导航.二维码显示隐藏.文本提示等等......而这些效果都是可以使用纯css实现的(而且非常简 ...
- java 24 - 7 GUI之 创建多级菜单窗体
需求: 创建多级菜单 步骤: A:创建窗体对象(并设置属性和布局) B:创建菜单栏 C:创建菜单和子菜单 D:逐步添加菜单(子菜单添加到菜单中,菜单添加到菜单栏中) E:窗体中设置菜单栏(菜单栏并不是 ...
随机推荐
- Linux---必备命令(2)
进程相关命令 # 查看系统所有的进程 ps -ef ps -ef | grep vim # 过滤出vim有关的进程 ps -ef | grep vim # 过滤出22端口的信息 ps -tunlp | ...
- 前端NEXT实践系列:(一)ECMAScript 6.0技术栈
随着ECMAScript 6.0(ES6)是JavaScript 语言的下一代标准的普及,各个大公司和大的厂商都推出了自己的前端开发框架,如Angular,React,Vue 等,微软更是锦上添花,开 ...
- float,short类型赋值运算问题
float f = 3.4; 有错吗? 有错,因为浮点类型默认是double类型,double类型赋值给float类型是大类型赋值给小类型需要进行强转,可在3.4前加(float)进行强转,或者在声明 ...
- OpenHarmony 3.1 Beta版本关键特性解析——HAP包安装实现剖析
(以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点) 石磊 随着社会的不断发展,人们逐渐注重更加高效.舒适.便捷.有趣的生活和工作体验. OpenAtom OpenHa ...
- upsource 配置git仓库时的 rsa 问题
在使用 upsource 时,当 通过 SSH-key 需要配置一个 git 仓库代码时,在使用本机已有配置的 rsa 是出现无法连接的问题.这是需要看下具体的提示,如下图的显示 其实关键的地方看这个 ...
- Blazor Bootstrap 组件库语音组件介绍
Speech 语音识别与合成 通过麦克风语音采集转换为文字(STT),或者通过文字通过语音朗读出来(TTS) 本组件依赖于 BootstrapBlazor.AzureSpeech,使用本组件时需要引用 ...
- java中int的最值解析
java中int的最大值为十进制的2147483647,也就是java能进行操作的最大数值,超出就会显示不正常.针对以下问题进行讨论. 1.最大值为什么是2147483647? java中int类型占 ...
- petite-vue源码剖析-逐行解读@vue-reactivity之effect
当我们通过effect将副函数向响应上下文注册后,副作用函数内访问响应式对象时即会自动收集依赖,并在相应的响应式属性发生变化后,自动触发副作用函数的执行. // ./effect.ts export ...
- C#/VB.NET 获取Excel中图片所在的行、列坐标位置
本文以C#和vb.net代码示例展示如何来获取Excel工作表中图片的坐标位置.这里的坐标位置是指图片左上角顶点所在的单元格行和列位置,横坐标即顶点所在的第几列.纵坐标即顶点所在的第几行.下面是获取图 ...
- [AcWing 777] 字符串乘方
点击查看代码 #include<iostream> using namespace std; string str; int main() { while (cin >> st ...