轻量级多级菜单控制框架程序(C语言)
2024-09-03 10:22:44
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 分支)
最新文章
- HTTP Status 500 - The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
- ueditor集成自己的ImageServer时出现错误的原因分析
- 工作流模式与K2实现--(2)
- MapReduce读取hdfs上文件,建立词频的倒排索引到Hbase
- cannot find module &#39;cordova-common&#39;
- linux查看cpu温度
- 克鲁斯卡尔(Kruskal)算法
- 面向服务的体系架构 SOA(二) --- 服务的路由和负载均衡
- 关于Android SDK Manager更新速度慢的解决方法
- Mac OS X汇编语言常识
- centos6.5安装配置NTP,集群各机器间时间同步
- 06:合法 C 标识符
- init: wait for &#39;/dev/block/bootdevice/by-name/cache&#39; timed out and took 5007ms【学习笔记】
- iOS 集成极光推送
- mysql主主同步设置
- 使用DUPLICATE 方式创建ORACLE 11G DG备库环境
- 【Spring学习笔记-MVC-4】SpringMVC返回Json数据-方式2
- Java 中 日期 时间 加减
- 超简单CSS3实现圆角、阴影、透明效果
- boost库之udp广播实例