• 轻量级多级菜单控制框架程序(C语言)


    1、前言

            作为嵌入式软件开发,可能经常会使用命令行或者显示屏等设备实现人机交互的功能,功能中通常情况都包含 UI 菜单设计;很多开发人员都会有自己的菜单框架模块,防止重复造轮子,网上有很多这种菜单框架的代码,但是大多耦合性太强,无法独立出来适配不同的菜单设计。

            本文介绍一个降低了耦合性,完全独立的菜单框架,菜单显示风格和显示平台完全由自己根据需求设计,而菜单操作统一由菜单模块处理即可,提高程序的移植性。


    2、介绍

    菜单框架代码主要特点有:

    • 采用链表方式实现多级菜单(通过配置选择采用动态分配或者数组实现)
    • 菜单框架作为独立模块,拒绝和按键模块、显示模块进行耦合
    • 在十分独立的情况下,也保证不受菜单的显示风格和显示平台影响,可自由选择设计显示风格和显示平台
    • 快捷菜单操作等
    • 可以采用表驱动的方式初始化菜单,提高代码的可读性

    3、代码功能

    源文件部分代码如下:

    copy
    /**
      * @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;
    }

    头文件部分代码如下:

    copy
    /**
      * @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 分支)

  • 相关阅读:
    全面讲解 Handler机制原理解析 (小白必看)
    一个例子形象的理解协程和线程的区别
    LeetCode 0342. 4的幂
    算法训练 第一周
    学习永不止步!誉天9月开班计划来啦!
    求解答pycharm弹窗显示的问题
    Alibaba最新发布的Spring Boot项目实战文档,Github标星78k
    【Flutter】包管理(5)Flutter 中 Hive 的详细使用说明
    Sui学术研究奖公布,资助研究者探索人工智能、能源市场和区块链游戏
    c++入门必学库函数 memset
  • 原文地址:https://www.cnblogs.com/const-zpc/p/16364420.html