本文包含原理图、PCB、源代码、封装库、中英文PDF等资源
您需要 登录 才可以下载或查看,没有账号?注册会员
×
/*******************************************************************************
标 题: 优化的通用菜单程序
修改人: 王新
描 述: 优化的通用菜单程序
程序特点:
1、程序和数据的分离,菜单可任意定义,甚至放在RAM里
2、定义好链表和菜单条目后,即可自动显示菜单、自动循环、跳转、执行,自
动控制程序流向,不需任何额外的判断和switch
3、保留菜单路径,可原路返回
4、可任意定义菜单层数,每层菜单可以任意组织,多一层菜单仅需增加1字节RAM
5、节省内存,仅需2字节+菜单层数个RAM
*****************************************************************************/
#define MENU_MAX_LAYER 16 //菜单链最大层数,示例只用到4层
#define MENU_NUM_OF_PAGE 4 //每页可以显示菜单数目
unsigned char Menu_tree[MENU_MAX_LAYER]; //菜单按键树,类似堆栈
unsigned char Menu_tree_ptr; //当前菜单按键树所在层数
unsigned char Menu_item_ptr; //当前菜单项在本层中位置
typedef struct
{
unsigned char code *Menu_NextTab; //本级菜单菜单链表
char code *Menu_Name; //当前菜单名称
void (*CurrentOperate)(); //当前状态应该执行的功能操作
}Menustruct;
void (*KeyFuncPtr)(); //按键功能指针
void refur_Menu(void); //刷新菜单层,就是依次打印总标题、各个条目,
void refur_Menu_item(void); //刷新本层菜单项,就是恢复原来项颜色,反显当前项
//则两个函数和界面布局有关,自己写吧
extern void ScanKey(void); //键盘扫描
void Menu_Key_Func(unsigned char NowKey); //菜单按键功能
{
switch(NowKey)
{
case KEY_UP:
if(*(KeyTab[Menu_tree][Menu_tree_ptr]Menu_NextTab)) //Menu_NextTab[0]不为0,是菜单
{
Menu_item_ptr--; //菜单项上移
if(Menu_tree_ptr== -1) //菜单项上移到顶翻转了,修正到最后一项
Menu_item_ptr=sizeof(*(KeyTab[Menu_tree][Menu_tree_ptr]Menu_NextTab))-1; //菜单循环
refur_Menu_item(); //刷新本层菜单项
}
else
Error_Beep(); //否则不是菜单,上下移无效,蜂鸣警告
break;
case KEY_doWN:
if(*(KeyTab[Menu_tree][Menu_tree_ptr]Menu_NextTab)) //Menu_NextTab[0]不为0,是菜单
{
Menu_item_ptr++; //菜单项下移
if(Menu_item_ptr==sizeof(*(KeyTab[Menu_tree][Menu_tree_ptr]Menu_NextTab))-1) //菜单项下移到底
Menu_item_ptr=0; //菜单项下移到底,循环上去
refur_Menu_item(); //刷新本层菜单项
}
else
Error_Beep(); //否则不是菜单,上下移无效,蜂鸣警告
break;
case KEY_OK://KEY_OK, KEY_UP, KEY_ESC,
if(*(KeyTab[Menu_tree][Menu_tree_ptr]Menu_NextTab)) //Menu_NextTab[0]不为0,是菜单
{
Menu_tree[Menu_tree_ptr+1]=KeyTab[Menu_tree][Menu_tree_ptr]Menu_NextTab[Menu_item_ptr]);
//下一级菜单压进菜单树,能看懂吗?
Menu_tree_ptr++; //菜单又多了一级
refur_Menu(); //刷新菜单层,当前菜单当然是在Menu_tree[Menu_tree_ptr]中啦
}
else //不是菜单,执行当前菜单项的操作
{
KeyFuncPtr=KeyTab[Menu_tree][Menu_tree_ptr]CurrentOperate;
(*KeyFuncPtr)(); //执行当前菜单项的操作
}
break;
case KEY_ESC:
//
if(Menu_tree_ptr) //当前菜单位置不是顶层(主界面)
{
Menu_tree_ptr--; //则返回上一层
refur_Menu(); //刷新菜单层,当前菜单当然是在Menu_tree[Menu_tree_ptr]中啦
}
else
Error_Beep(); //否则蜂鸣警告
break;
//
//case Other:
//....
}
} |
|