分享一个做菜单的方法,转自傻孩子,准备移植到Mini板上2.8寸LCD显示

2019-07-21 08:20发布

------------------------------------------

贴一段代码大家看看哈(我用来做目录的引擎)

(以上的是我在羚羊上实现的,但是原理是一样的,特别是Menu.h可以直接使用)





Menu.h

-------------------------------



#ifndef        __MENU_h__

#define        __MENU_h__

#include "Functions.h"

/****************************************************

* 支持库说明:提供了使用菜单的基本数据结构          *

* 作者:      傻孩子                                *

* 日期:      2005年6月9日                          *

****************************************************/



/**********************

*    目录结构体定义   *

**********************/

struct MenuItem        

{

    short MenuCount;

    char *DisplayString;

    void (*Subs)();

    struct MenuItem *ChildrenMenus;

    struct MenuItem *ParentMenus;

}Null;



void NullSubs(void)

{

}







/****************************************************

*   使用说明:                                      *

*      要定义一个菜单,需要做以下几步工作           *

*      1、定义一个结构体数组                        *

*      2、如果这个菜单是子菜单,那么把上级菜单的    *

*         *ChildrenMenus指针指向该数组的首地址,     *

*         并且设置ParentMenus为上层目录的地址       *

*      3、如果这个菜单是跟菜单,那么直接将MenuPoint *

*         指针指向该数组的首地址                    *

*      4、通过写一个函数为该数组的每一个元素初始化  *

*      5、如果菜单项是最终选项,那么将*ChildrenMenus*

*         置为NULL,将函数指针*Subs指向实现功能的   *

*         函数。                                    *

****************************************************/





struct MenuItem MainMenu[3];

struct MenuItem TimeMenu[4];

struct MenuItem VoiceMenu[5];

struct MenuItem RobotMenu[5];

struct MenuItem FlashMenu[5];



/***********************

*     函 数 声 明 区   *

***********************/

void MainMenuInit(void);

void TimeMenuInit(void);

void VoiceMenuInit(void);

void RobotMenuInit(void);

void FlashMenuInit(void);



/**************************************************************

*  函数说明:Flash处理目录初始化函数                          *

**************************************************************/

void FlashMenuInit(void)

{

    FlashMenu[0].MenuCount = 5;

    FlashMenu[0].DisplayString = "  Flash Record  ";

    FlashMenu[0].Subs = FlashRecord;

    FlashMenu[0].ChildrenMenus = &Null;

    FlashMenu[0].ParentMenus = MainMenu;

    

    FlashMenu[1].MenuCount = 5;

    FlashMenu[1].DisplayString = "      lay      ";

    FlashMenu[1].Subs = FlashPlay;

    FlashMenu[1].ChildrenMenus = &Null;

    FlashMenu[1].ParentMenus = MainMenu;

    

    FlashMenu[2].MenuCount = 5;

    FlashMenu[2].DisplayString = "      ause     ";

    FlashMenu[2].Subs = FlashPause;

    FlashMenu[2].ChildrenMenus = &Null;

    FlashMenu[2].ParentMenus = MainMenu;

    

    FlashMenu[3].MenuCount = 5;

    FlashMenu[3].DisplayString = "  Flash Delete  ";

    FlashMenu[3].Subs = FlashDelete;

    FlashMenu[3].ChildrenMenus = &Null;

    FlashMenu[3].ParentMenus = MainMenu;

    

    FlashMenu[4].MenuCount = 5;

    FlashMenu[4].DisplayString = "      Back      ";

    FlashMenu[4].Subs = NullSubs;

    FlashMenu[4].ChildrenMenus = MainMenu;

    FlashMenu[4].ParentMenus = MainMenu;

}



/**************************************************************

*  函数说明:机器人控制目录初始化函数                         *

**************************************************************/

void RobotMenuInit(void)

{

    RobotMenu[0].MenuCount = 5;

    RobotMenu[0].DisplayString = "   Turn  Left   ";

    RobotMenu[0].Subs = RobotTurnLeft;

    RobotMenu[0].ChildrenMenus = &Null;

    RobotMenu[0].ParentMenus = MainMenu;

    

    RobotMenu[1].MenuCount = 5;

    RobotMenu[1].DisplayString = "   Turn Right   ";

    RobotMenu[1].Subs = RobotTurnRight;

    RobotMenu[1].ChildrenMenus = &Null;

    RobotMenu[1].ParentMenus = MainMenu;

    

    RobotMenu[2].MenuCount = 5;

    RobotMenu[2].DisplayString = "    Go  Ahead   ";

    RobotMenu[2].Subs = RobotGoAhead;

    RobotMenu[2].ChildrenMenus = &Null;

    RobotMenu[2].ParentMenus = MainMenu;

    

    RobotMenu[3].MenuCount = 5;

    RobotMenu[3].DisplayString = "     Go Back    ";

    RobotMenu[3].Subs = RobotGoBack;

    RobotMenu[3].ChildrenMenus = &Null;

    RobotMenu[3].ParentMenus = MainMenu;

    

    RobotMenu[4].MenuCount = 5;

    RobotMenu[4].DisplayString = "      Back      ";

    RobotMenu[4].Subs = NullSubs;

    RobotMenu[4].ChildrenMenus = MainMenu;

    RobotMenu[4].ParentMenus = MainMenu;

    

}



/**************************************************************

*  函数说明:声音处理目录初始化函数                           *

**************************************************************/

void VoiceMenuInit(void)

{

    VoiceMenu[0].MenuCount = 5;

    VoiceMenu[0].DisplayString = "  Voice Record  ";

    VoiceMenu[0].Subs = VoiceRecord;

    VoiceMenu[0].ChildrenMenus = &Null;

    VoiceMenu[0].ParentMenus = MainMenu;

    

    VoiceMenu[1].MenuCount = 5;

    VoiceMenu[1].DisplayString = "      lay      ";

    VoiceMenu[1].Subs = Play;

    VoiceMenu[1].ChildrenMenus = &Null;

    VoiceMenu[1].ParentMenus = MainMenu;

    

    VoiceMenu[2].MenuCount = 5;

    VoiceMenu[2].DisplayString = "      ause     ";

    VoiceMenu[2].Subs = Pause;

    VoiceMenu[2].ChildrenMenus = &Null;

    VoiceMenu[2].ParentMenus = MainMenu;

    

    VoiceMenu[3].MenuCount = 5;

    VoiceMenu[3].DisplayString = "  Voice Delete  ";

    VoiceMenu[3].Subs = VoiceDelete;

    VoiceMenu[3].ChildrenMenus = &Null;

    VoiceMenu[3].ParentMenus = MainMenu;

    

    VoiceMenu[4].MenuCount = 5;

    VoiceMenu[4].DisplayString = "      Back      ";

    VoiceMenu[4].Subs = NullSubs;

    VoiceMenu[4].ChildrenMenus = MainMenu;

    VoiceMenu[4].ParentMenus = MainMenu;

}



/**************************************************************

*  函数说明:时间设定子目录初始化                             *

**************************************************************/

void TimeMenuInit(void)

{

    TimeMenu[0].MenuCount = 4;

    TimeMenu[0].DisplayString = "    Time Set    ";

    TimeMenu[0].Subs = TimeSet;

    TimeMenu[0].ChildrenMenus = &Null;

    TimeMenu[0].ParentMenus = MainMenu;

    

    TimeMenu[1].MenuCount = 4;

    TimeMenu[1].DisplayString = "    Date Set    ";

    TimeMenu[1].Subs = DateSet;

    TimeMenu[1].ChildrenMenus = &Null;

    TimeMenu[1].ParentMenus = MainMenu;

    

    TimeMenu[2].MenuCount = 4;

    TimeMenu[2].DisplayString = "    AlertSet    ";

    TimeMenu[2].Subs = AlertSet;

    TimeMenu[2].ChildrenMenus = &Null;

    TimeMenu[2].ParentMenus = MainMenu;

    

    TimeMenu[3].MenuCount = 4;

    TimeMenu[3].DisplayString = "      Back      ";

    TimeMenu[3].Subs = NullSubs;

    TimeMenu[3].ChildrenMenus = MainMenu;

    TimeMenu[3].ParentMenus = MainMenu;

    

}



/**************************************************************

*  函数说明:根目录初始化                                     *

**************************************************************/

void MainMenuInit(void)

{

     MainMenu[0].MenuCount = 3;

     MainMenu[0].DisplayString = "    Time Set    ";

     MainMenu[0].Subs = NullSubs;

     MainMenu[0].ChildrenMenus = TimeMenu;

     MainMenu[0].ParentMenus = &Null;



     MainMenu[1].MenuCount = 3;

     MainMenu[1].DisplayString = "  Voice Center  ";

     MainMenu[1].Subs = NullSubs;

     MainMenu[1].ChildrenMenus = VoiceMenu;

     MainMenu[1].ParentMenus = &Null;

/*

     MainMenu[2].MenuCount = 3;

     MainMenu[2].DisplayString = "  Robot Control ";

     MainMenu[2].Subs = NullSubs;

     MainMenu[2].ChildrenMenus = RobotMenu;  

     MainMenu[2].ParentMenus = &Null;

*/     

     MainMenu[2].MenuCount = 3;

     MainMenu[2].DisplayString = "  Flash Option  ";

     MainMenu[2].Subs = NullSubs;

     MainMenu[2].ChildrenMenus = FlashMenu;     

     MainMenu[2].ParentMenus = &Null;



}



#endif



Function.h

------------------------------



#ifndef        __FUNCTIONS_h__

#define        __FUNCTIONS_h__

/****************************************************

* 支持库说明:系统菜单功能文件宏                    *

* 日期:      2005年6月9日                          *

****************************************************/

    #include "TimeSet.h"

    #include "VoiceCenter.h"

    #include "RobotControl.h"

    #include "FlashOption.h"



/*--------------------------------

   上面包含的头文件里面包含了菜单

   功能选项所要调用的函数。

--------------------------------*/

#endif





main.c

-----------------------------



#include "GRAPH_Command.h"

#include "Functions.h"

#include "Menu.h"



/***********************

*   按键功能键宏定义   *

***********************/

# define UP        0

# define Down      4

# define Enter     5

# define Esc       1

# define Reset     2



/***********************

*     全局变量声明区   *

***********************/



    

    struct MenuItem (*MenuPoint) = MainMenu;

    short DisplayStart = 0;

    short UserChoose = 0;

    short DisplayPoint = 0;

    short MaxItems;    





/*****************************

* Struct MenuItem:           *

*    short MenuCount;        *

*    char *DisplayString;    *

*    void (*Subs)();         *

*    MenuItem *ChildrenMenus;*

*    MenuItem *ParentMenus;  *

*****************************/



/***********************

*     函 数 声 明 区   *

***********************/

extern void ClearWatchDog();

void MenuInitialation(void);

void SystemInitialation(void);

void ShowMenu(void);

short GetKeyNum(void);



/**************************************************************

*  函数说明:系统初始化函数                                   *

**************************************************************/

void SystemInitialation(void)

{

        Init_sys();          

        Enable_LCD();                          //初始化字库      函数定义在

        MenuInitialation();               //初始化菜单

        GRAPH                             //图形初始化

}



/**************************************************************

*  函数说明:目录初始化函数                                   *

**************************************************************/

void MenuInitialation(void)

{

    MainMenuInit();

    TimeMenuInit();

    VoiceMenuInit();

    RobotMenuInit();

    FlashMenuInit();

}



/**************************************************************

*  函数说明:目录显示函数                                     *

**************************************************************/

void ShowMenu(void)

{

    short n = 0;



    MaxItems = MenuPoint[0].MenuCount;

    DisplayPoint = DisplayStart;

        if (MaxItems >= 4)

        {

             for (n = 0;n<4;n++)

             {

                         

                 LOCATE(n+1,1);

                 PRINT(MenuPoint[DisplayPoint].DisplayString);

                 

                 if ((DisplayPoint) == UserChoose)

                     {

                         BOX(1,n*16+1,126,(n+1)*16-2,1,1);

                     }

                 

                     DisplayPoint +=1;

                     if ((DisplayPoint) == (MaxItems))

                     {

                         DisplayPoint = 0;

                     }

             }

         }

         else

         {

             for (n = 0;n<MaxItems;n++)

             {

                         

                 LOCATE(n+1,1);

                 PRINT(MenuPoint[DisplayPoint].DisplayString);

                 

                 if ((DisplayPoint) == UserChoose)

                     {

                         BOX(1,n*16+1,126,(n+1)*16-2,1,1);

                     }

                 

                     DisplayPoint +=1;

                     if ((DisplayPoint) == (MaxItems))

                     {

                         DisplayPoint = 0;

                     }

                 

             }

         }

        //BOX(0,0,127,63,2,2);

}



/**************************************************************

*  函数说明:获得键值函数                                     *

**************************************************************/

short GetKeyNum(void)

{

    short TempKeyNum = 0;

        TempKeyNum = F_Key_Scan();       //获取按键值

        *P_IOA_Dir = 0x01ff;

        *P_IOA_Attrib = 0x01ff;       

        *P_IOA_Data = 0x01ff;

            

        return TempKeyNum;



}



/**************************************************************

*  函数说明:主函数                                           *

**************************************************************/

int main()

{                      

    short KeyNum = 0xff;

    

    SystemInitialation();            //系统初始化

    

    ShowMenu();

        while(1)

        {

            ClearWatchDog();             //喂狗

            KeyNum = GetKeyNum();        //获取按键值



            /*******************目录操作*********************/

            

            /***************************************

            *   [按键说明]                         *

            *  ----------------------------------- *

            *   [K1]            UP(向上)           *

            *   [K5]            Down(向下)         *

            *   [K2]            Esc(后退)          *

            *   [K6]            Enter(确定)        *

            *   [K3]            返回根目录         *

            ***************************************/

            if (KeyNum != 0xff)

            {

             ShowMenu();

                 switch(KeyNum)

                 {

                     case UP:

                         UserChoose --;

                         if (UserChoose < 0)

                         {

                             UserChoose = MaxItems-1;

                         }

                         break;

                     case Esc:

                         if (MenuPoint[0].ParentMenus != &Null)

                         {

                             MenuPoint = MenuPoint[0].ParentMenus;

                             UserChoose = 0;

                             DisplayStart = 0;

                         }

                         break;

                     case Down:

                         UserChoose ++;

                         if (UserChoose == MaxItems)

                         {

                             UserChoose = 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;

                 }

                 

                 if ((UserChoose < DisplayStart) || (UserChoose > (DisplayStart+3)))

                 {

                    DisplayStart = UserChoose;

                 }

                 

                 CLS

                 ShowMenu();

                 

            }

            /*******************目录操作*********************/

        }

        



}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
41条回答
xiaoyan
1楼-- · 2019-07-21 20:00
菜单不是最难的,最难处理的是界面。
若水三千
2楼-- · 2019-07-21 21:08
写好了求分享源代码,楼主!!
合肥-文盲
3楼-- · 2019-07-22 01:05
 精彩回答 2  元偷偷看……
ArchiChain
4楼-- · 2019-07-22 02:14
回复【7楼】合肥-文盲:
---------------------------------
我在tft屏上用const char * xxxx{}这样的字符串数组做的菜单显示。等项目忙完了再把能公开的部分整理和大家分享。
xiaoyan
5楼-- · 2019-07-22 08:01
回复【10楼】合肥-文盲:
---------------------------------
界面上,你要设计UI,需要设置各种参数,各种输出响应。功能一复杂,代码就会臃肿。。。
xiaoyan
6楼-- · 2019-07-22 11:06
所以在设计界面的时候,可以采用事件驱动的方式,将消息和响应分离。

一周热门 更多>