⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄

📁 /*[原创]一个树形多级菜单参考程序 这是一个用于车载电话的菜单程序,可以看成是手机功能菜单的简化板. 我所认为的树形多级菜单是指:在一个父菜单项目下面有多个子菜单, 子菜单下面又有多个孙菜单...,
💻
字号:
/*[原创]一个树形多级菜单参考程序
这是一个用于车载电话的菜单程序,可以看成是手机功能菜单的简化板.
我所认为的树形多级菜单是指:在一个父菜单项目下面有多个子菜单,
子菜单下面又有多个孙菜单...,进入下层菜单主要依*当前选中的索引.有点象文件的目录结构.  
本木从前实现这类的菜单主要*分层的switch语句,每层都是一个switch.但当我看到晓奇大侠的
程序和耳朵灌满lq等人的争论后,那时那地,我的心境变化了,我意识到指针代表了先进的生产力,
代表了社会的发展方向,是建设和谐社会的必要条件.不管你用了多长时间C语言,只要你不善于用
一个小针指来指去,你就是那种"用嘴吃饭的高贵骑士,决不用屁股装弹步枪"的守旧分子和社会发
展的绊脚石.(跑题太远,删去1万字...打住)
.言归正传,下面的程序适用CPU为Mega16,编译器为CVAVR 1.24.4a;由于按键数目较多,所以按键程
序把按键事件分为数字键,快捷键,确认键,取消键,上下翻键几类,以减小菜单结构的容量.一下菜单
数据在菜单结构数组中的偏移量,有多少个菜单象就有多少个宏定义*/
#define DIAL00_MENU     1
#define SET00_MENU      2
#define DIAL01_MENU     3
#define SET01_MENU      4
#define SET02_MENU      5
#define SET03_MENU      6
#define SET04_MENU      7
#define SET05_MENU      8
//功能函数说明
void MainFace(void);             
void EditCodeFace(void);             
void MFunListFace(void);           
void TranTelCodeFace(void);  
void FCodeListFace(void);
void CallRecListFace(void );
void GroupFunListFace(void );
void SysFunListFace(void );
void TelNoteListFace(void );
//重头戏:
//定义用于菜单操作得结构
typedef  flash struct { 
unsigned int  fatherMenu;     //父菜单偏移地址 
unsigned int  ownIndex;       //本身地偏移地址  
unsigned int  mNumKeyFunc;   // 数字按键时指向的菜单结构 
unsigned int  mFastKeyFunc;   // 数字按键时指向的菜单结构 
unsigned int  mYesKeyFunc;   // YES键时指向的菜单结构 
unsigned int  mNoKeyFunc;   //  NO键时指向的菜单结构 
unsigned int  mUpKeyFunc;   //   UP键时指向的菜单结构 
unsigned int  mDownKeyFunc;   //DOWN键时指向的菜单结构  
void(*menuFunc)(void);
}_menu;
flash _menu menuList[]  ={  
//主菜单                      偏移 0  
{ MAIN_MENU,MAIN_MENU,   
  DIAL00_MENU, DIAL00_MENU, DIAL00_MENU, IN_MENU, SET00_MENU, SET00_MENU, MainFace},               
//拨号第一屏---号码编辑     偏移 1  
{ MAIN_MENU,DIAL00_MENU,   
  DIAL00_MENU, DIAL00_MENU, DIAL01_MENU, DIAL00_MENU, USELESS, USELESS, EditCodeFace},                 
//设定第一屏---功能列表     偏移 2 
{ MAIN_MENU,DIAL00_MENU,   
   USELESS, USELESS, SET00_MENU, MAIN_MENU, SET00_MENU, SET00_MENU, MFunListFace},                 
//拨号第二屏---拨号通话     偏移 3  
{ MAIN_MENU,DIAL01_MENU,   
  USELESS, USELESS, USELESS, MAIN_MENU, USELESS, USELESS, TranTelCodeFace},                 
//速拨第一屏---号码列表     偏移 4  
{ SET00_MENU,SET01_MENU,   
  USELESS, USELESS, SET11_MENU, SET00_MENU, SET01_MENU, SET01_MENU, FCodeListFace},                
//通话记录第一屏---号码列表 偏移 5   
{ MAIN_MENU,DIAL00_MENU,    
  USELESS, USELESS, SET00_MENU, SET00_MENU, SET02_MENU, SET02_MENU, CallRecListFace},                
//集群设定第一屏---功能列表 偏移 6 
{ MAIN_MENU,DIAL00_MENU,   
   USELESS, USELESS, SET00_MENU, SET00_MENU, SET03_MENU, SET03_MENU, GroupFunListFace},                 
//系统设定第一屏---功能列表 偏移 7  
{ MAIN_MENU,DIAL00_MENU,   
  USELESS, USELESS, SET00_MENU, SET00_MENU, SET04_MENU, SET04_MENU, SysFunListFace},                
//电话本第一屏---  记录列表 偏移 8  
{ MAIN_MENU,DIAL00_MENU,   
  USELESS, USELESS, SET00_MENU, SET00_MENU, SET05_MENU, SET05_MENU, TelNoteListFace} 
};
//定义每个菜单项下面的子菜单相对父菜单的偏移,如果不用全局索引,此项为零
.flash unsigned char gMain_SubLoc[]   ={0,0}; 
flash unsigned char gDial00_SubLoc[] ={0};
flash unsigned char gDial01_SubLoc[] ={0}; 
flash unsigned char gSet00_SubLoc[]  ={ 
  SET01_MENU-SET00_MENU, 
  SET02_MENU-SET00_MENU, 
  SET03_MENU-SET00_MENU, 
  SET04_MENU-SET00_MENU, 
  SET05_MENU-SET00_MENU
}; 
flash unsigned char *pSubMenu
;//同上面的数组配合确定按YES键时转向的子菜单
flash _menu *pCurrMenu;调用程序:
void KeyMenu(){           
//旧情难舍还是用了一个switch 
   if (gKeyValue != NULL){  
      switch (gKeyAttr){   
          case NUM_KEY:      
                SwitchMenu(pCurrMenu->mNumKeyFunc); 
                break;   
          case FAST_KEY: 
                SwitchMenu(pCurrMenu->mFastKeyFunc); 
                break;        
          case YES_KEY:
                SwitchMenu((*(pSubMenu+gMenuLocIndex))+pCurrMenu- 
                           >mYesKeyFunc); 
                gMenuLocIndex=0;          
                break;           
          case NO_KEY:  
                SwitchMenu(pCurrMenu->mNoKeyFunc);    
                break;  
          case UP_KEY:
                SwitchMenu(pCurrMenu->mUpKeyFunc);  
                break;   
          case DOWN_KEY: 
                SwitchMenu(pCurrMenu->mDownKeyFunc);  
                break;         
         default:break;   
     } 
     gKeyValue = NULL;    
   }  
   if (pCurrMenu->ownIndex == MAIN_MENU)    pCurrMenu->menuFunc();
}
/********************************************
菜单功能函数功能:
根据输入参数确定菜单指针转向,并执行转向后的菜单功能参数:
菜单指针相对偏移返回:
无执行返回:FALSE,
有执行返回:TRUE
影响:pCurrMenu
*********************************************/
BOOL SwitchMenu(unsigned int menuIndex){  
    if (menuIndex == USELESS) return FALSE;   
    pCurrMenu = &menuList[menuIndex];  
    pCurrMenu->menuFunc();  
    return TRUE;
}
/*如果要添加菜单,
步骤是:
1.在菜单数据结构中增加记录项,
2.添加记录项所在位置的宏定义
3.定义使用全局索引的子目录相对偏移
总结:这个程序结构最大功绩在于简化了KeyMenu()的结构.
用的FLASH好像小了点,菜单复杂时的可读性太差.*/

 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -