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 分支)

最新文章

  1. 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
  2. ueditor集成自己的ImageServer时出现错误的原因分析
  3. 工作流模式与K2实现--(2)
  4. MapReduce读取hdfs上文件,建立词频的倒排索引到Hbase
  5. cannot find module &#39;cordova-common&#39;
  6. linux查看cpu温度
  7. 克鲁斯卡尔(Kruskal)算法
  8. 面向服务的体系架构 SOA(二) --- 服务的路由和负载均衡
  9. 关于Android SDK Manager更新速度慢的解决方法
  10. Mac OS X汇编语言常识
  11. centos6.5安装配置NTP,集群各机器间时间同步
  12. 06:合法 C 标识符
  13. init: wait for &#39;/dev/block/bootdevice/by-name/cache&#39; timed out and took 5007ms【学习笔记】
  14. iOS 集成极光推送
  15. mysql主主同步设置
  16. 使用DUPLICATE 方式创建ORACLE 11G DG备库环境
  17. 【Spring学习笔记-MVC-4】SpringMVC返回Json数据-方式2
  18. Java 中 日期 时间 加减
  19. 超简单CSS3实现圆角、阴影、透明效果
  20. boost库之udp广播实例

热门文章

  1. 设计模式学习笔记(十五)命令模式及在Spring JdbcTemplate 中的实现
  2. 集成JUnit测试
  3. [UE][虚幻]创建默认媒体打包资源路径
  4. C语言结构体指针与结构体变量作形参的区别
  5. JavaWeb学习day8-Response排错
  6. angular.js中 路由 用法及概念
  7. 【深度学习 论文篇 02-1 】YOLOv1论文精读
  8. Spark SQL底层执行流程详解
  9. busybox+linux Deplay 手机服务器
  10. 类变量_main方法_代码块