|
发表于 2019-2-23 12:44:06
|
显示全部楼层
本帖最后由 jssd 于 2019-2-23 12:46 编辑
请教大师: 关于 窗体框架 的理解,
就对此菜单而言,我理解为:
1、每一个菜单容器本身除了菜单引擎,还有一个 窗体框架,负责显示菜单容器中的内容。
2、每一个菜单项也有一个窗体框架,也就是一个弹出窗口,窗口大小可以整屏,也可以是一小部分。负责显示菜单项的数据调整。
此时进入了RUN_ITEM_HANDLER,所以菜单导航键用来调整数据等。
3、就是说每一个响应函数都是独立的,这样就可以把每个一参数都独立出来调整,使用独立的导航键和独立的显示。
个人觉得:
优点:很明显,所有的东西都是独立的,耦合度低
缺点:说不出来,感觉好像导航键重写了很多次的样子。。。
PS:
之前问过大师的菜单问题,后来时间太紧张,就直接用了switch结构来写。
请教:傻孩子菜单的函数执行菜单怎样用?
https://www.amobbs.com/thread-5688618-1-1.html
(出处: amoBBS 阿莫电子论坛)
这次又要涉及LCD12864的菜单,感觉之前的代码耦合度太高,很难管理,所以花了几天看了好几遍这个帖子,
感觉抓到了一点点感觉,下面是刚刚跑起来的程序。加了菜单容器的显示(简单的),菜单项的只简单加了个说明显示。
接下来要把参数调整和显示都加了,感觉好像差不多把菜单容器的引擎+显示再拷贝一次的样子
头文件
- #ifndef __BSP_MENU_H__
- #define __BSP_MENU_H__
- #pragma anon_unions //匿名结构体需要
- #include <stdio.h> //printf( "\r\n USART1 Initialize Success!\r\n" );
- #include <string.h> //memset(buf,0,sizeof(buf));清零 memcpy(,,)
- #include "stm32f10x.h"
- #define this (*ptThis)
- #define UBOUND(__ARR) (sizeof(__ARR)/sizeof(__ARR[0]))
- #ifndef __FSM_RT_TYPE__
- #define __FSM_RT_TYPE__
- //! \name finit state machine state
- //! @{
- typedef enum {
- fsm_rt_err = -1, //!< fsm error, error code can be get from other interface
- fsm_rt_cpl = 0, //!< fsm complete
- fsm_rt_on_going = 1, //!< fsm on-going
- fsm_rt_wait_for_obj = 2, //!< fsm wait for object
- fsm_rt_asyn = 3, //!< fsm asynchronose complete, you can check it later.
- } fsm_rt_t;
- //! @}
- #endif
- //#define __def_menu(__NAME, __PARENT, __ENGINE) \
- //extern const menu_t c_tMenu##__NAME; \
- //menu_item_t c_tMenu##__NAME##Items[] = {
- //#define def_menu(__NAME, __PARENT, __ENGINE) \
- // __def_menu(__NAME, (__PARENT), (__ENGINE))
- //#define __end_def_menu(__NAME, __PARENT, __ENGINE) \
- // }; \
- // const menu_t c_tMenu##__NAME = { \
- // c_tMenu##__NAME##Items, \
- // (sizeof(c_tMenu##__NAME##Items)/sizeof(menu_item_t)), \
- // (__PARENT), \
- // &(__ENGINE), \
- // };
- //#define end_def_menu(__NAME, __PARENT, __ENGINE) \
- // __end_def_menu(__NAME, (__PARENT), (__ENGINE))
- //
- //
- //#define __extern_menu(__NAME) extern const menu_t c_tMenu##__NAME;
- //#define extern_menu(__NAME) __extern_menu(__NAME)
- //
- //#define __menu(__NAME) c_tMenu##__NAME
- //#define menu(__NAME) __menu(__NAME)
- //#define __menu_item(__HANDLER, __CHILD_MENU, ...) \
- // { \
- // &(__HANDLER), \
- // (__CHILD_MENU), \
- // __VA_ARGS__, \
- // },
- //#define menu_item(__HANDLER, __CHILD_MENU, ...) \
- // __menu_item((__HANDLER), (__CHILD_MENU), __VA_ARGS__)
- //typedef struct __menu_item menu_item_t;
- //typedef struct __menut menu_t;
- //typedef fsm_rt_t menu_item_handler_t(menu_item_t *);
- //struct __menu_item {
- // menu_item_handler_t *fnHandle; //!< handler
- // menu_t *ptChild; //!< Child Menu
- //
- // //! depends on your application, you can add/remove/change following members
- // char *pchTitle; //!< Menu Title
- // char *pchDescription; //!< Description for this menu item
- // char chShortCutKey; //!< Shortcut Key value in current menu
- //};
- //typedef fsm_rt_t menu_engine_t(menu_t *);
- //struct __menut {
- // menu_item_t *ptItems; //!< menu item list
- // uint_fast8_t chCount; //!< menu item count
- // menu_t *ptParent; //!< parent menu;
- // menu_engine_t *fnEngine; //!< engine for process current menu
- //};
- /*============================ MACROS ========================================*/
- /*============================ MACROFIED FUNCTIONS ===========================*/
- #define __declare_menu_item_template(__NAME) \
- typedef struct __##__NAME __NAME;
- #define declare_menu_item_template(__NAME) \
- __declare_menu_item_template(__NAME)
-
- #define __def_menu_item_template(__NAME) \
- struct __##__NAME { \
- menu_item_t;
- #define def_menu_item_template(__NAME) \
- __def_menu_item_template(__NAME)
- #define end_def_menu_item_template(__NAME) \
- };
- #define __def_menu(__NAME, __PARENT, __ENGINE, __TEMPLATE) \
- extern const menu_t c_tMenu##__NAME; \
- __TEMPLATE c_tMenu##__NAME##Items[] = {
- #define def_menu(__NAME, __PARENT, __ENGINE) \
- __def_menu(__NAME, (__PARENT), (__ENGINE), default_menu_item_t)
-
- #define def_menu_ex(__NAME, __PARENT, __ENGINE, __TEMPLATE) \
- __def_menu(__NAME, (__PARENT), (__ENGINE), __TEMPLATE)
- #define __end_def_menu(__NAME, __PARENT, __ENGINE, __TEMPLATE) \
- }; \
- const menu_t c_tMenu##__NAME = { \
- (menu_item_t *)c_tMenu##__NAME##Items, \
- (sizeof(c_tMenu##__NAME##Items)/sizeof(__TEMPLATE)), \
- (menu_t *)(__PARENT), \
- (__ENGINE), \
- };
- #define end_def_menu(__NAME, __PARENT, __ENGINE) \
- __end_def_menu(__NAME, (__PARENT), (__ENGINE), default_menu_item_t)
- #define end_def_menu_ex(__NAME, __PARENT, __ENGINE, __TEMPLATE) \
- __end_def_menu(__NAME, (__PARENT), (__ENGINE), __TEMPLATE)
-
- #define __extern_menu(__NAME) extern const menu_t c_tMenu##__NAME;
- #define extern_menu(__NAME) __extern_menu(__NAME)
- #define __menu(__NAME) c_tMenu##__NAME
- #define menu(__NAME) __menu(__NAME)
-
- #define __menu_item(__HANDLER, __CHILD_MENU, ...) \
- { \
- (__HANDLER), \
- (menu_t *)(__CHILD_MENU), \
- __VA_ARGS__, \
- },
- #define menu_item(__HANDLER, __CHILD_MENU, ...) \
- __menu_item((__HANDLER), (__CHILD_MENU), __VA_ARGS__)
- /*============================ TYPES =========================================*/
- typedef struct __menu_item menu_item_t; //菜单项
- typedef struct __menu menu_t; //菜单容器
- typedef struct __menu_engine_cb menu_engine_cb_t; //菜单引擎?
- typedef fsm_rt_t menu_item_handler_t(menu_item_t *); //菜单项消息处理引擎
- typedef fsm_rt_t menu_engine_t(menu_engine_cb_t *); //菜单容器消息处理引擎
- //菜单项 基类
- struct __menu_item {
- menu_item_handler_t *fnHandle; //!< handler
- menu_t *ptChild; //!< Child Menu
- };
- //菜单容器 基类
- struct __menu {
- menu_item_t *ptItems; //!< menu item list
- uint_fast8_t chCount; //!< menu item count
- menu_t *ptParent; //!< parent menu;
- menu_engine_t *fnEngine; //!< engine for process current menu
- };
- //菜单引擎?
- struct __menu_engine_cb {
- uint_fast8_t tState;
- const menu_t *ptCurrentMenu; //指向当前菜单容器
- uint_fast8_t chCurrentItemIndex; //当前菜单容器中的菜单项索引号
- };
- /*============================ 以上是基类 =========================================*/
- /*===================== 派生类 默认菜单项 ====================================*/
- typedef struct __default_menu_item_t default_menu_item_t; //派生类 默认菜单项
- struct __default_menu_item_t {
- //! inherit from base class menu_item_t
- menu_item_t;
- //! depends on your application, you can add/remove/change following members
- char *pchTitle; //!< Menu Title
- char *pchDescription; //!< Description for this menu item
- char chShortCutKey; //!< Shortcut Key value in current menu
- };
- /*===================== 派生类 默认菜单项初始化 ================================*/
- extern fsm_rt_t top_menu_engine(menu_engine_cb_t *ptThis); //菜单容器处理函数
- extern fsm_rt_t top_menu_item_a_handler(menu_item_t *ptItem); //菜单项a处理函数
- extern fsm_rt_t top_menu_item_b_handler(menu_item_t *ptItem); //菜单项b处理函数
- extern fsm_rt_t top_menu_item_c_handler(menu_item_t *ptItem); //菜单项c处理函数
- extern const menu_t c_tTopMenu; //顶层菜单容器
- void Display_top_menu(menu_engine_cb_t*ptThis);
- /*===================== 派生类 默认菜单项初始化 ================================*/
- extern fsm_rt_t lv2_menu_engine(menu_engine_cb_t *ptThis); //菜单容器处理函数
- extern fsm_rt_t lv2_menu_item_1_handler(menu_item_t *ptItem); //菜单项处理函数
- extern fsm_rt_t lv2_menu_item_2_handler(menu_item_t *ptItem); //菜单项处理函数
- extern fsm_rt_t lv2_menu_item_3_handler(menu_item_t *ptItem); //菜单项处理函数
- extern const menu_t lv2_menu_A; //菜单容器
- fsm_rt_t menu_task(menu_engine_cb_t *ptThis);
- #endif
复制代码
c 文件
- /*============================ INCLUDES ======================================*/
- #include "Globals.h"
- //顶层菜单项定义和初始化 c_tTopMenuItems[]
- default_menu_item_t c_tTopMenuItems[] = {
- {
- NULL,
- (menu_t*)&lv2_menu_A, //!< child menu
- "Top Menu A ",
- "这是 A ",
- },
- {
- top_menu_item_b_handler,
- NULL, //!< child menu
- "Top Menu B ",
- "这是 B ",
- },
- {
- top_menu_item_c_handler,
- NULL, //!< child menu
- "Top Menu C ",
- "这是 C ",
- }
- };
- //顶层菜单容器定义和初始化 c_tTopMenu
- const menu_t c_tTopMenu = {
- (menu_item_t *)c_tTopMenuItems, //!< menu item list
- UBOUND(c_tTopMenuItems), //!< menu item count
- NULL, //!< top menu has no parent
- top_menu_engine,
- };
- //菜单项a处理函数
- fsm_rt_t top_menu_item_a_handler(menu_item_t *ptItem)
- {
- default_menu_item_t *ptitem = (default_menu_item_t *)ptItem;
- LCD_ShowLine(3,ptitem->pchDescription);
- return fsm_rt_cpl;
- }
- //菜单项b处理函数
- fsm_rt_t top_menu_item_b_handler(menu_item_t *ptItem)
- {
- default_menu_item_t *ptitem = (default_menu_item_t *)ptItem;
- LCD_ShowLine(3,ptitem->pchDescription);
- return fsm_rt_cpl;
- }
- //菜单项c处理函数
- fsm_rt_t top_menu_item_c_handler(menu_item_t *ptItem)
- {
- default_menu_item_t *ptitem = (default_menu_item_t *)ptItem;
- LCD_ShowLine(3,ptitem->pchDescription);
- return fsm_rt_cpl;
- }
- //菜单容器处理函数
- fsm_rt_t top_menu_engine(menu_engine_cb_t*ptThis)
- {
- #define DEFAULT_MENU_ENGINE_RESET_FSM() \
- do { this.tState = START; } while(0)
- enum {
- START = 0,
- READ_KEY_EVENT,
- KEY_PROCESS,
- RUN_ITEM_HANDLER
- };
- key_t tKey;
- default_menu_item_t *ptItem;
- // menu_item_t *ptItem;
-
- switch(this.tState) {
- case START:
- this.tState++;
- Display_top_menu(ptThis);
- case READ_KEY_EVENT:
- tKey = Key_GetKey();
- if (KEY_NULL == tKey) {
- break;
- }
- //this.tState = KEY_PROCESS;
-
- case KEY_PROCESS:
- switch (tKey) {
- case KEY_DOWN:
- printf("KEY_DOWN \r\n");
- this.chCurrentItemIndex++;
- if (this.chCurrentItemIndex >= this.ptCurrentMenu->chCount) {
- this.chCurrentItemIndex = 0;
- }
- break;
- case KEY_UP:
- printf("KEY_UP \r\n");
- if (0 == this.chCurrentItemIndex--) {
- this.chCurrentItemIndex = this.ptCurrentMenu->chCount - 1;
- }
- break;
- case KEY_ENTER: {
- printf("KEY_ENTER \r\n");
- // ptItem = &(this.ptCurrentMenu->ptItems[this.chCurrentItemIndex]);
- ptItem = &((default_menu_item_t *)this.ptCurrentMenu->ptItems) [this.chCurrentItemIndex];
- if (NULL != ptItem->fnHandle) {
- this.tState = RUN_ITEM_HANDLER;
- } else if (NULL != ptItem->ptChild) {
- this.ptCurrentMenu = ptItem->ptChild;
- this.chCurrentItemIndex = 0;
-
- DEFAULT_MENU_ENGINE_RESET_FSM();
- return fsm_rt_cpl;
- }
- }
- break;
- case KEY_ESC:
-
- //! return to upper menu
- if (NULL != this.ptCurrentMenu->ptParent) {
- this.ptCurrentMenu = this.ptCurrentMenu->ptParent;
- this.chCurrentItemIndex = 0;
-
- DEFAULT_MENU_ENGINE_RESET_FSM();
- return fsm_rt_cpl;
- }
- break;
- default:
- break;
- }
- Display_top_menu(ptThis);
- break;
-
- case RUN_ITEM_HANDLER:
- // ptItem = &(this.ptCurrentMenu->ptItems[this.chCurrentItemIndex]);
- ptItem = &((default_menu_item_t *)this.ptCurrentMenu->ptItems) [this.chCurrentItemIndex];
- fsm_rt_t tFSM = ptItem->fnHandle((menu_item_t *)ptItem);
- printf("RUN_ITEM_HANDLER \r\n");
- if (tFSM>0) {
- break;
- }
- else {
- DEFAULT_MENU_ENGINE_RESET_FSM();
- return fsm_rt_cpl;
- }
- // break;
- }
- return fsm_rt_on_going;
- }
- //菜单容器显示函数
- void Display_top_menu(menu_engine_cb_t*ptThis)
- {
- uint_fast8_t i;
- uint_fast8_t index = this.chCurrentItemIndex;
- // default_menu_item_t *ptItem = &((default_menu_item_t *)this.ptCurrentMenu->ptItems) [this.chCurrentItemIndex];
- default_menu_item_t *ptItem = (default_menu_item_t *)this.ptCurrentMenu->ptItems;
-
- for(i=0;i<4;i++)
- {
- LCD_ShowLine(i,ptItem[index].pchTitle);
- index++;
- if(index==this.ptCurrentMenu->chCount)
- index=0;
- if(index==this.chCurrentItemIndex)
- break;
- }
-
- }
- //菜单任务 10ms 运行一次
- fsm_rt_t menu_task(menu_engine_cb_t *ptThis)
- {
- do {
- /* this validation code could be removed for release version */
- if (NULL == ptThis) {
- break;
- } else if (NULL == this.ptCurrentMenu) {
- break;
- } else if (NULL == this.ptCurrentMenu->fnEngine) {
- break;
- } else if (NULL == this.ptCurrentMenu->ptItems) {
- break;
- } else if (0 == this.ptCurrentMenu->chCount) {
- break;
- }
-
- return this.ptCurrentMenu->fnEngine(ptThis);
-
- } while(0);
-
- return fsm_rt_err;
- }
复制代码
lv2 c文件
- /*============================ INCLUDES ======================================*/
- #include "Globals.h"
- ///*===================== 派生类 默认菜单项初始化 ================================*/
- //extern fsm_rt_t lv2_menu_engine(menu_engine_cb_t *ptThis); //菜单容器处理函数
- //extern fsm_rt_t lv2_menu_item_1_handler(menu_item_t *ptItem); //菜单项处理函数
- //extern fsm_rt_t lv2_menu_item_2_handler(menu_item_t *ptItem); //菜单项处理函数
- //extern fsm_rt_t lv2_menu_item_3_handler(menu_item_t *ptItem); //菜单项处理函数
- //extern const menu_t lv2_menu_A; //顶层菜单容器
- //顶层菜单项定义和初始化 c_tTopMenuItems[]
- default_menu_item_t lv2_menuItems[] = {
- {
- lv2_menu_item_1_handler,
- NULL, //!< child menu
- "LV2 Menu A ",
- "这是 A ",
- },
- {
- lv2_menu_item_2_handler,
- NULL, //!< child menu
- "LV2 Menu B ",
- "这是 B ",
- },
- {
- NULL,
- (menu_t*)&c_tTopMenu, //!< child menu
- "LV2 Menu C ",
- "这是 C ",
- }
- };
- //顶层菜单容器定义和初始化 lv2_menu_A
- const menu_t lv2_menu_A = {
- (menu_item_t *)lv2_menuItems, //!< menu item list
- UBOUND(lv2_menuItems), //!< menu item count
- (menu_t*)&c_tTopMenu,
- // NULL, //!< top menu has no parent
- top_menu_engine,
- };
- //菜单项a处理函数
- fsm_rt_t lv2_menu_item_1_handler(menu_item_t *ptItem)
- {
- default_menu_item_t *ptitem = (default_menu_item_t *)ptItem;
- LCD_ShowLine(3,ptitem->pchDescription);
- return fsm_rt_cpl;
- }
- //菜单项b处理函数
- fsm_rt_t lv2_menu_item_2_handler(menu_item_t *ptItem)
- {
- default_menu_item_t *ptitem = (default_menu_item_t *)ptItem;
- LCD_ShowLine(3,ptitem->pchDescription);
- return fsm_rt_cpl;
- }
- //菜单项c处理函数
- fsm_rt_t lv2_menu_item_3_handler(menu_item_t *ptItem)
- {
- default_menu_item_t *ptitem = (default_menu_item_t *)ptItem;
- LCD_ShowLine(3,ptitem->pchDescription);
- return fsm_rt_cpl;
- }
- //菜单容器处理函数
- fsm_rt_t lv2_menu_engine(menu_engine_cb_t*ptThis)
- {
- return fsm_rt_cpl;
- }
复制代码 |
|