搜索
bottom↓
回复: 8

请教:傻孩子菜单的函数执行菜单怎样用?

[复制链接]

出0入55汤圆

发表于 2018-3-12 18:06:04 | 显示全部楼层 |阅读模式
菜单A                                            菜单B
项目1                                            数量x
项目2  -->(按确认键后进入)-->    UP,DOWN按键调整
项目3                                            OK          按键返回

如上面菜单所示:
在菜单A中,按UP,DOWN键选择项目,按 OK 键进入下一级菜单(如选择项目2进入菜单B)
菜单B是调整数量x的,按UP,DOWN按键调整,按OK按键返回

问题来了:菜单B是否要定义成MenuItem?UP,DOWN按键是怎样处理的?

菜单链接,在100楼
[古董贴][交流]怎样在点阵屏上绘图——基于LCD12864
https://www.amobbs.com/thread-591361-1-1.html
(出处: amoBBS 阿莫电子论坛)

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入296汤圆

发表于 2018-3-13 21:19:49 来自手机 | 显示全部楼层
我看了下原贴子,我提供处理代码了呀?哪里看不明白?

出0入55汤圆

 楼主| 发表于 2018-3-13 21:57:37 来自手机 | 显示全部楼层
Gorgon_Meducer 发表于 2018-3-13 21:19
我看了下原贴子,我提供处理代码了呀?哪里看不明白?

谢谢傻孩子考试回复,不是不明白,菜单跳转也都没问题,但如果菜单带有变量要显示呢?这个变量要随着按键调整呢?也就是不同的界面对应不同的按键功能。

出0入55汤圆

 楼主| 发表于 2018-3-13 21:59:29 来自手机 | 显示全部楼层
Gorgon_Meducer 发表于 2018-3-13 21:19
我看了下原贴子,我提供处理代码了呀?哪里看不明白?

如果把变量那些加到结构体里,结构体会变得很庞大,如果单独放出来,又很难处理

出0入296汤圆

发表于 2018-3-14 18:43:16 | 显示全部楼层
本帖最后由 Gorgon_Meducer 于 2018-3-14 21:26 编辑
jssd 发表于 2018-3-13 21:59
如果把变量那些加到结构体里,结构体会变得很庞大,如果单独放出来,又很难处理 ...


如果不同的菜单对应不同的按键,那的确不能直接使用统一的菜单引擎了,但答案也很明显啊。
你在每个菜单的结构体里再加入一个函数指针,指向这个菜单专用的处理引擎函数就行了,
这样对于普通的菜单,那就统一指向一个默认的菜单处理引擎函数;对于有特殊要求的菜单,
就指向自己专用的菜单引擎处理函数就行了。

不知道我说的你是否理解了?

我更新了下菜单的数据结构,希望有所启示:



  1. #ifndef __FSM_RT_TYPE__
  2. #define __FSM_RT_TYPE__
  3. //! \name finit state machine state
  4. //! @{
  5. typedef enum {
  6.     fsm_rt_err          = -1,    //!< fsm error, error code can be get from other interface
  7.     fsm_rt_cpl          = 0,     //!< fsm complete
  8.     fsm_rt_on_going     = 1,     //!< fsm on-going
  9.     fsm_rt_wait_for_obj = 2,     //!< fsm wait for object
  10.     fsm_rt_asyn         = 3,     //!< fsm asynchronose complete, you can check it later.
  11. } fsm_rt_t;
  12. //! @}

  13. #endif


  14. typedef struct __menu_item  menu_item_t;
  15. typedef struct __menut      menu_t;

  16. typedef fsm_rt_t menu_item_handler_t(menu_item_t *);

  17. struct __menu_item {
  18.     menu_item_handler_t *fnHandle;                      //!< handler
  19.     menu_t              *ptChild;                       //!< Child Menu
  20.    
  21.     //! depends on your application, you can add/remove/change following members
  22.     char                *pchTitle;                      //!< Menu Title
  23.     char                *pchDescription;                //!< Description for this menu item
  24.     char                chShortCutKey;                  //!< Shortcut Key value in current menu
  25. };

  26. typedef fsm_rt_t menu_engine_t(menu_t *);

  27. struct __menut {
  28.     menu_item_t        *ptItems;                        //!< menu item list
  29.     uint_fast8_t        chCount;                        //!< menu item count
  30.     menu_t             *ptParent;                       //!< parent menu;
  31.     menu_engine_t      *fnEngine;                       //!< engine for process current menu
  32. };

复制代码


一个可能的初始化形式是:


  1. extern fsm_rt_t top_menu_engine(menu_t *ptMenu);

  2. extern fsm_rt_t top_menu_item_a_handler(menu_item_t *ptItem);
  3. extern fsm_rt_t top_menu_item_b_handler(menu_item_t *ptItem);
  4. extern fsm_rt_t top_menu_item_c_handler(menu_item_t *ptItem);

  5. extern const menu_t c_tTopMenu;

  6. menu_item_t c_tTopMenuItems[] = {
  7.     {
  8.         top_menu_item_a_handler,
  9.         NULL,                                           //!< child menu
  10.         "Top Menu A",
  11.         "This is Top Menu A",
  12.     },
  13.     {
  14.         top_menu_item_b_handler,
  15.         NULL,                                           //!< child menu
  16.         "Top Menu B",
  17.         "This is Top Menu B"
  18.     },
  19.     {
  20.         top_menu_item_c_handler,
  21.         NULL,                                           //!< child menu
  22.         "Top Menu C",
  23.         "This is Top Menu C"
  24.     }
  25. };

  26. const menu_t c_tTopMenu = {
  27.     c_tTopMenuItems,                                    //!< menu item list
  28.     UBOUND(c_tTopMenuItems),                            //!< menu item count
  29.     NULL,                                               //!< top menu has no parent
  30.     top_menu_engine,                                    
  31. };


  32. fsm_rt_t top_menu_item_a_handler(menu_item_t *ptItem)
  33. {
  34.     return fsm_rt_cpl;
  35. }

  36. fsm_rt_t top_menu_item_b_handler(menu_item_t *ptItem)
  37. {
  38.     return fsm_rt_cpl;
  39. }

  40. fsm_rt_t top_menu_item_c_handler(menu_item_t *ptItem)
  41. {
  42.     return fsm_rt_cpl;
  43. }

  44. fsm_rt_t top_menu_engine(menu_t *ptMenu)
  45. {
  46.     return fsm_rt_cpl;
  47. }
复制代码


通过加入一些辅助宏,我们可以让这个初始化的菜单的定义过程更简单(只消耗ROM):


  1. #define __def_menu(__NAME, __PARENT, __ENGINE)                                  \
  2. extern const menu_t c_tMenu##__NAME;                                            \
  3. menu_item_t c_tMenu##__NAME##Items[] = {
  4. #define def_menu(__NAME, __PARENT, __ENGINE)                                    \
  5.             __def_menu(__NAME, (__PARENT), (__ENGINE))

  6. #define __end_def_menu(__NAME, __PARENT, __ENGINE)                              \
  7.     };                                                                          \
  8.     const menu_t c_tMenu##__NAME = {                                            \
  9.         c_tMenu##__NAME##Items,                                                 \
  10.         (sizeof(c_tMenu##__NAME##Items)/sizeof(menu_item_t)),                   \
  11.         (__PARENT),                                                             \
  12.         &(__ENGINE),                                                            \
  13.     };
  14. #define end_def_menu(__NAME, __PARENT, __ENGINE)                                \
  15.             __end_def_menu(__NAME, (__PARENT), (__ENGINE))
  16.             
  17.             
  18. #define __extern_menu(__NAME)   extern const menu_t c_tMenu##__NAME;
  19. #define extern_menu(__NAME)     __extern_menu(__NAME)
  20.             
  21. #define __menu(__NAME)          c_tMenu##__NAME
  22. #define menu(__NAME)            __menu(__NAME)   

  23. #define __menu_item(__HANDLER, __CHILD_MENU, ...)                               \
  24.     {                                                                           \
  25.         &(__HANDLER),                                                           \
  26.         (__CHILD_MENU),                                                         \
  27.         __VA_ARGS__,                                                            \
  28.     },
  29. #define menu_item(__HANDLER, __CHILD_MENU, ...)                                 \
  30.             __menu_item((__HANDLER), (__CHILD_MENU), __VA_ARGS__)
复制代码


因此,前面初始化的例子就等效的可以简化为:


  1. extern fsm_rt_t top_menu_engine(menu_t *ptMenu);

  2. extern fsm_rt_t top_menu_item_a_handler(menu_item_t *ptItem);
  3. extern fsm_rt_t top_menu_item_b_handler(menu_item_t *ptItem);
  4. extern fsm_rt_t top_menu_item_c_handler(menu_item_t *ptItem);


  5. def_menu(TopMenu, NULL, top_menu_engine)
  6.     menu_item(
  7.         top_menu_item_a_handler,
  8.         NULL,
  9.         "Top Menu A",
  10.         "This is Top Menu A"
  11.     )
  12.     menu_item(
  13.         top_menu_item_a_handler,
  14.         NULL,
  15.         "Top Menu B",
  16.         "This is Top Menu B"
  17.     )
  18.     menu_item(
  19.         top_menu_item_a_handler,
  20.         NULL,
  21.         "Top Menu C",
  22.         "This is Top Menu C"
  23.     )
  24. end_def_menu(TopMenu, NULL, top_menu_engine)


  25. fsm_rt_t top_menu_item_a_handler(menu_item_t *ptItem)
  26. {
  27.     return fsm_rt_cpl;
  28. }

  29. fsm_rt_t top_menu_item_b_handler(menu_item_t *ptItem)
  30. {
  31.     return fsm_rt_cpl;
  32. }

  33. fsm_rt_t top_menu_item_c_handler(menu_item_t *ptItem)
  34. {
  35.     return fsm_rt_cpl;
  36. }

  37. fsm_rt_t top_menu_engine(menu_t *ptMenu)
  38. {
  39.     return fsm_rt_cpl;
  40. }
复制代码


定义好的menu怎么用呢?

需要用到变量的时候,用menu宏,例如:

  1.     menu_t *ptThis = &menu(TopMenu);                        
复制代码


如果要extern给其它.c文件使用怎么办呢?使用extern_menu宏,例如:

  1. ...
  2.     extern_menu(TopMenu);
  3. ...                       
复制代码


我专门开了一个帖子来详细讨论菜单技术:
https://www.amobbs.com/thread-5688720-1-1.html

出0入55汤圆

 楼主| 发表于 2018-3-15 09:52:28 | 显示全部楼层
Gorgon_Meducer 发表于 2018-3-14 18:43
如果不同的菜单对应不同的按键,那的确不能直接使用统一的菜单引擎了,但答案也很明显啊。
你在每个菜单 ...

谢谢解答!在专用的处理引擎函数处理各自的界面和按键处理之类的是可以解决,我也试过这样写,相当一个弹出式的菜单,然后发现整个菜单会被搞得乱七八糟的,还不如直接用一个switch结构来的清晰。
仔细看了下你的新帖子,发现功力不够,不是很明白,我再静心看多几次。非常感谢

出0入296汤圆

发表于 2018-3-15 17:48:08 | 显示全部楼层
jssd 发表于 2018-3-15 09:52
谢谢解答!在专用的处理引擎函数处理各自的界面和按键处理之类的是可以解决,我也试过这样写,相当一个弹 ...

具体什么地方不明白,还请务必在帖子里提出,我给你答案。
相信我,你遇到的问题一定对其它人有很大的帮助。

出0入55汤圆

 楼主| 发表于 2018-3-16 16:45:52 | 显示全部楼层
Gorgon_Meducer 发表于 2018-3-15 17:48
具体什么地方不明白,还请务必在帖子里提出,我给你答案。
相信我,你遇到的问题一定对其它人有很大的帮 ...

因为涉及工作的东西,所以不能全部弄出来 ,请见谅。但我会整理一下,以最接近的形式提出。

出0入296汤圆

发表于 2018-3-16 17:38:13 | 显示全部楼层
jssd 发表于 2018-3-16 16:45
因为涉及工作的东西,所以不能全部弄出来 ,请见谅。但我会整理一下,以最接近的形式提出。 ...

期待你的具体问题。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-13 09:43

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表