?? 一個簡單卻實用的菜單程序.c
字號:
//一個簡單卻實用的菜單程序
//如果編寫簡單的程序的話這個菜單函數就可以不用看了,但是當你編寫到復雜的程序的時候就可能就會為人機界面和各個函數直接的連接而煩惱了,這個菜單函數就是用來解決這個問題,雖然沒有UCGUI厲害,但是我覺得代碼在2000行一下的話用起來還是不錯的選擇的.雖說簡單但是用到了結構體大部分的知識了,希望c語言不太好的朋友自己補習一下好了.
//主要程序:
//CODE:
#define Null 0
/***********************
* 函數聲明 *
***********************/
void ShowMenu(void);
void Menu_Change(unsigned char KeyNum);
/***********************
* 按鍵功能鍵宏定義 *
***********************/
#define UP '3'
#define Down '7'
#define Esc 'B'
#define Enter 'F'
#define Reset '0'
/**********************
* 目錄結構體定義 *
**********************/
struct MenuItem
{
unsigned char MenuCount; //當前層節(jié)點數
unsigned char *DisplayString; //菜單標題
void (*Subs)(); //節(jié)點函數
struct MenuItem *ChildrenMenus; //子節(jié)點
struct MenuItem *ParentMenus; //父節(jié)點
};
/***********************
* 調用子函數區(qū) *
***********************/
void NullSubs(void)
{
}
//----------------------以下為例子,請根據實際情況修改---------------------------
void TimeSet(void)
{
put_s("TimeSet");
}
void DateSet(void)
{
put_s("DateSet");
}
void AlertSet (void)
{
put_s("AlertSet");
}
//------------------------------------------------------------------------------
/***********************
* 結構體區(qū) *
***********************/
//----------------------以下為例子,請根據實際情況修改---------------------------
struct MenuItem TimeMenu[4];
struct MenuItem FlashMenu[5];
struct MenuItem VoiceMenu[5];
struct MenuItem RobotMenu[5];
struct MenuItem MainMenu[5];
struct MenuItem TimeMenu[4]=
{ //MenuCount DisplayString Subs ChildrenMenus ParentMenus
{4, "1.Time Set", TimeSet, Null, MainMenu},
{4, "2.Date Set", DateSet, Null, MainMenu},
{4, "3.AlertSet", AlertSet, Null, MainMenu},
{4, "4.Back", NullSubs, MainMenu, MainMenu},
};
struct MenuItem FlashMenu[5]=
{ //MenuCount DisplayString Subs ChildrenMenus ParentMenus
{5, "1.Flash Record", NullSubs, Null, MainMenu},
{5, "2.Play", NullSubs, Null, MainMenu},
{5, "3.Pause", NullSubs, Null, MainMenu},
{5, "4.Flash Delete", NullSubs, Null, MainMenu},
{5, "5.Back", NullSubs, MainMenu, MainMenu},
};
struct MenuItem VoiceMenu[5]=
{ //MenuCount DisplayString Subs ChildrenMenus ParentMenus
{5, "1.Voice Record" , NullSubs, Null, MainMenu},
{5, "2.Play", NullSubs, Null, MainMenu},
{5, "3.Pause", NullSubs, Null, MainMenu},
{5, "4.Voice Delete", NullSubs, Null, MainMenu},
{5, "5.Back", NullSubs, MainMenu, MainMenu},
};
struct MenuItem RobotMenu[5]=
{ //MenuCount DisplayString Subs ChildrenMenus ParentMenus
{5, "1.Turn Left", NullSubs, Null, MainMenu},
{5, "2.Turn Right", NullSubs, Null, MainMenu},
{5, "3.Go Ahead", NullSubs, Null, MainMenu},
{5, "4.Go Back", NullSubs, Null, MainMenu},
{5, "5.Back", NullSubs, MainMenu, MainMenu},
};
struct MenuItem MainMenu[5]=
{ //MenuCount DisplayString Subs ChildrenMenus ParentMenus
{5, "1.Time Set" , NullSubs, TimeMenu, Null},
{5, "2.Voice Center", NullSubs, VoiceMenu, Null},
{5, "3.Robot Control", NullSubs, RobotMenu, Null},
{5, "4.Flash Option", NullSubs, FlashMenu, Null},
{5, "5.Back", NullSubs, MainMenu, MainMenu},
};
//------------------------------------------------------------------------------
/***********************
* 全局變量聲明區(qū) *
***********************/
struct MenuItem (*MenuPoint) = MainMenu; //結構體指針,指向結構體后由內部函數指針指向功能函數
unsigned char DisplayStart = 0; //顯示時的第一個菜單項
unsigned char UserChoose = 0; //用戶所選菜單項
unsigned char DisplayPoint = 0; //顯示指針
unsigned MaxItems; //同級最大菜單數
unsigned char ShowCount="2"; //同屏顯示菜單數
/***********************
*顯示函數區(qū) *
***********************/
void ShowMenu(void)
{
unsigned char n;
MaxItems = MenuPoint[0].MenuCount;//定義最大同級菜單
DisplayPoint = DisplayStart;
for(n=0;DisplayPoint<MaxItems&&n<ShowCount;n++)
{if(DisplayPoint==UserChoose)
LCD_write_string(0,n,"->");
LCD_write_string(2,n,MenuPoint[DisplayPoint++].DisplayString);
}
}
void Menu_Change(unsigned char KeyNum)
{
if(KeyNum)
{
switch(KeyNum)
{
case UP:
UserChoose --;
if (UserChoose ==255)
{
UserChoose = 0;//上翻截至,如果要回滾賦值MaxItems-1
}
break;
case Esc:
if (MenuPoint[UserChoose].ParentMenus != Null)
{
MenuPoint = MenuPoint[UserChoose].ParentMenus;
UserChoose = 0;
DisplayStart = 0;
}
break;
case Down:
UserChoose ++;
if (UserChoose == MaxItems)
{
UserChoose = MaxItems-1;//下翻截至,如要回滾賦值為0
}
break;
case Enter:
if (MenuPoint[UserChoose].Subs != NullSubs)
{
(*MenuPoint[UserChoose].Subs)();
}
else if (MenuPoint[UserChoose].ChildrenMenus != Null)
{
MenuPoint = MenuPoint[UserChoose].ChildrenMenus;
UserChoose = 0;
DisplayStart = 0;
}
break;
case Reset:
MenuPoint = MainMenu;
UserChoose = 0;
DisplayStart = 0;
break;
default:break;
}
if (UserChoose%ShowCount==0) //一屏只能顯示ShowCount行
DisplayStart = UserChoose;
else if(UserChoose==1||UserChoose== 3)
DisplayStart = UserChoose-1; //實現滾屏的關鍵
LCD_write_command(0x01); //液晶清屏,根據不同液晶函數自行修改
delay_nms(5); //液晶為慢速器件
ShowMenu();
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -