mymach 发表于 2005-6-28 15:27:50

有谁能够谈谈LCD中菜单的实现和编程方法?

同上!

ilan2003 发表于 2005-6-28 15:58:44

我没有编写过,我只写过驱动程序

我想主要是记录位置信息,通过反显来表示

Gorgon_Meducer 发表于 2005-6-28 16:59:22

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

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

(以上的是我在羚羊上实现的,但是原理是一样的,特别是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;

struct MenuItem TimeMenu;

struct MenuItem VoiceMenu;

struct MenuItem RobotMenu;

struct MenuItem FlashMenu;



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

*   函 数 声 明 区   *

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

void MainMenuInit(void);

void TimeMenuInit(void);

void VoiceMenuInit(void);

void RobotMenuInit(void);

void FlashMenuInit(void);



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

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

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

void FlashMenuInit(void)

{

    FlashMenu.MenuCount = 5;

    FlashMenu.DisplayString = "Flash Record";

    FlashMenu.Subs = FlashRecord;

    FlashMenu.ChildrenMenus = &Null;

    FlashMenu.ParentMenus = MainMenu;

   

    FlashMenu.MenuCount = 5;

    FlashMenu.DisplayString = "      Play      ";

    FlashMenu.Subs = FlashPlay;

    FlashMenu.ChildrenMenus = &Null;

    FlashMenu.ParentMenus = MainMenu;

   

    FlashMenu.MenuCount = 5;

    FlashMenu.DisplayString = "      Pause   ";

    FlashMenu.Subs = FlashPause;

    FlashMenu.ChildrenMenus = &Null;

    FlashMenu.ParentMenus = MainMenu;

   

    FlashMenu.MenuCount = 5;

    FlashMenu.DisplayString = "Flash Delete";

    FlashMenu.Subs = FlashDelete;

    FlashMenu.ChildrenMenus = &Null;

    FlashMenu.ParentMenus = MainMenu;

   

    FlashMenu.MenuCount = 5;

    FlashMenu.DisplayString = "      Back      ";

    FlashMenu.Subs = NullSubs;

    FlashMenu.ChildrenMenus = MainMenu;

    FlashMenu.ParentMenus = MainMenu;

}



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

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

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

void RobotMenuInit(void)

{

    RobotMenu.MenuCount = 5;

    RobotMenu.DisplayString = "   TurnLeft   ";

    RobotMenu.Subs = RobotTurnLeft;

    RobotMenu.ChildrenMenus = &Null;

    RobotMenu.ParentMenus = MainMenu;

   

    RobotMenu.MenuCount = 5;

    RobotMenu.DisplayString = "   Turn Right   ";

    RobotMenu.Subs = RobotTurnRight;

    RobotMenu.ChildrenMenus = &Null;

    RobotMenu.ParentMenus = MainMenu;

   

    RobotMenu.MenuCount = 5;

    RobotMenu.DisplayString = "    GoAhead   ";

    RobotMenu.Subs = RobotGoAhead;

    RobotMenu.ChildrenMenus = &Null;

    RobotMenu.ParentMenus = MainMenu;

   

    RobotMenu.MenuCount = 5;

    RobotMenu.DisplayString = "   Go Back    ";

    RobotMenu.Subs = RobotGoBack;

    RobotMenu.ChildrenMenus = &Null;

    RobotMenu.ParentMenus = MainMenu;

   

    RobotMenu.MenuCount = 5;

    RobotMenu.DisplayString = "      Back      ";

    RobotMenu.Subs = NullSubs;

    RobotMenu.ChildrenMenus = MainMenu;

    RobotMenu.ParentMenus = MainMenu;

   

}



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

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

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

void VoiceMenuInit(void)

{

    VoiceMenu.MenuCount = 5;

    VoiceMenu.DisplayString = "Voice Record";

    VoiceMenu.Subs = VoiceRecord;

    VoiceMenu.ChildrenMenus = &Null;

    VoiceMenu.ParentMenus = MainMenu;

   

    VoiceMenu.MenuCount = 5;

    VoiceMenu.DisplayString = "      Play      ";

    VoiceMenu.Subs = Play;

    VoiceMenu.ChildrenMenus = &Null;

    VoiceMenu.ParentMenus = MainMenu;

   

    VoiceMenu.MenuCount = 5;

    VoiceMenu.DisplayString = "      Pause   ";

    VoiceMenu.Subs = Pause;

    VoiceMenu.ChildrenMenus = &Null;

    VoiceMenu.ParentMenus = MainMenu;

   

    VoiceMenu.MenuCount = 5;

    VoiceMenu.DisplayString = "Voice Delete";

    VoiceMenu.Subs = VoiceDelete;

    VoiceMenu.ChildrenMenus = &Null;

    VoiceMenu.ParentMenus = MainMenu;

   

    VoiceMenu.MenuCount = 5;

    VoiceMenu.DisplayString = "      Back      ";

    VoiceMenu.Subs = NullSubs;

    VoiceMenu.ChildrenMenus = MainMenu;

    VoiceMenu.ParentMenus = MainMenu;

}



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

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

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

void TimeMenuInit(void)

{

    TimeMenu.MenuCount = 4;

    TimeMenu.DisplayString = "    Time Set    ";

    TimeMenu.Subs = TimeSet;

    TimeMenu.ChildrenMenus = &Null;

    TimeMenu.ParentMenus = MainMenu;

   

    TimeMenu.MenuCount = 4;

    TimeMenu.DisplayString = "    Date Set    ";

    TimeMenu.Subs = DateSet;

    TimeMenu.ChildrenMenus = &Null;

    TimeMenu.ParentMenus = MainMenu;

   

    TimeMenu.MenuCount = 4;

    TimeMenu.DisplayString = "    AlertSet    ";

    TimeMenu.Subs = AlertSet;

    TimeMenu.ChildrenMenus = &Null;

    TimeMenu.ParentMenus = MainMenu;

   

    TimeMenu.MenuCount = 4;

    TimeMenu.DisplayString = "      Back      ";

    TimeMenu.Subs = NullSubs;

    TimeMenu.ChildrenMenus = MainMenu;

    TimeMenu.ParentMenus = MainMenu;

   

}



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

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

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

void MainMenuInit(void)

{

   MainMenu.MenuCount = 3;

   MainMenu.DisplayString = "    Time Set    ";

   MainMenu.Subs = NullSubs;

   MainMenu.ChildrenMenus = TimeMenu;

   MainMenu.ParentMenus = &Null;



   MainMenu.MenuCount = 3;

   MainMenu.DisplayString = "Voice Center";

   MainMenu.Subs = NullSubs;

   MainMenu.ChildrenMenus = VoiceMenu;

   MainMenu.ParentMenus = &Null;

/*

   MainMenu.MenuCount = 3;

   MainMenu.DisplayString = "Robot Control ";

   MainMenu.Subs = NullSubs;

   MainMenu.ChildrenMenus = RobotMenu;

   MainMenu.ParentMenus = &Null;

*/   

   MainMenu.MenuCount = 3;

   MainMenu.DisplayString = "Flash Option";

   MainMenu.Subs = NullSubs;

   MainMenu.ChildrenMenus = FlashMenu;   

   MainMenu.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.MenuCount;

    DisplayPoint = DisplayStart;

        if (MaxItems >= 4)

        {

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

             {

                         

                 LOCATE(n+1,1);

                 PRINT(MenuPoint.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.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();      //获取按键值



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

          

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

          *   [按键说明]                         *

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

          *               UP(向上)         *

          *               Down(向下)         *

          *               Esc(后退)          *

          *               Enter(确定)      *

          *               返回根目录         *

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

          if (KeyNum != 0xff)

          {

             ShowMenu();

                 switch(KeyNum)

                 {

                   case UP:

                         UserChoose --;

                         if (UserChoose < 0)

                         {

                             UserChoose = MaxItems-1;

                         }

                         break;

                   case Esc:

                         if (MenuPoint.ParentMenus != &Null)

                         {

                             MenuPoint = MenuPoint.ParentMenus;

                             UserChoose = 0;

                             DisplayStart = 0;

                         }

                         break;

                   case Down:

                         UserChoose ++;

                         if (UserChoose == MaxItems)

                         {

                             UserChoose = 0;

                         }

                         

                         break;

                   case Enter:

                         if (MenuPoint.Subs != NullSubs)

                         {

                             (*MenuPoint.Subs)();

                         }

                         else if (MenuPoint.ChildrenMenus != &Null)

                         {

                             MenuPoint = MenuPoint.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();

                

          }

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

        }

       



}






-----此内容被Gorgon Meducer于2005-06-28,17:00:01编辑过

Gorgon_Meducer 发表于 2005-6-28 17:04:05

补充一个关于作图的库函数



GRAPH_Command.h

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



#ifndef        __GRAPH_COMMAND_h__

#define        __GRAPH_COMMAND_h__

#include "lab_parameter.h"

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

*函数库说明:图形函数扩展库                           *

*版本:      v1.0                                       *

*支持库:    Splc501sys.asm / Splc501Hardware.asm       *

*作者:      傻孩子                                     *

*日期:      2005年6月8日                               *

*                                                         *

*说明:      在现有系统图形函数基础上,扩展若干使用   *

*            方便的图形函数                           *

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



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

*   系 统 宏 定 义      *

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

# define GRAPH        FG_InitGraphic();

# define CLS      FG_ClearScreen(DG_CLS_ERASE);





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

*    全 局 变 量 定 义    *

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

shortNow_Str_X = 1;

shortNow_Str_Y = 1;



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

*   函数声明      *

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

void BOX(short LT_X,short LT_Y,short RB_X,short RB_Y,short IfEraser,short FillColor);

void LOCATE(short Str_x,short Str_y);

void Print(char *Strings);





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

*函数说明:画矩形框工具                                  *

*      输入:矩框坐标DrawModel FillColor               *

*               [说明]                        *

*         0                   擦除                         *

*         1                   画线                         *

*         2                   填充                         *

*               [说明]                        *

*         0                   白                           *

*         1                   黑                           *

*         2                   反色(XOR)                  *

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

void BOX(short LT_X,short LT_Y,short RB_X,short RB_Y,short DrawModel,short FillColor)

{

    if (LT_X < 0)      LT_X = 0;

    if (LT_Y < 0)      LT_Y = 0;

    if (RB_X > 127)      RB_X = 127;

    if (RB_Y > 63)       RB_Y = 63;

   

    LT_X = 127 - LT_X;

    LT_Y = 64 - LT_Y;

   

    RB_X = 127 - RB_X;

    RB_Y = 64 - RB_Y;

      

    switch (DrawModel)

    {

      case 0:

            if(FillColor == 1)

            {

                FG_SetRectStyle(DG_RECT_ERASE);

            }

            else

            {

                FG_SetRectStyle(DG_RECT_COVER);

            }

            FG_Rectangle(RB_X,RB_Y,LT_X,LT_Y);

            break;

      case 1:

            if (FillColor == 1)

            {

                FG_SetRectStyle(DG_RECT_HOLLOW);

            }

            else if(FillColor == 0)

            {

                FG_SetRectStyle(DG_RECT_HOLLOW_ERASE);

            }

            else if(FillColor == 2)

            {

                FG_SetRectStyle(DG_RECT_SOLID_XOR);

            }

            FG_Rectangle(RB_X,RB_Y,LT_X,LT_Y);

            break;

      case 2:

            if (FillColor == 1)

            {

                FG_SetRectStyle(DG_RECT_COVER);

                FG_Rectangle(RB_X,RB_Y,LT_X,LT_Y);

            }

            else if (FillColor == 0)

            {

                FG_ClearRect(RB_X,RB_Y,LT_X,LT_Y,DG_CLS_ERASE);

            }

            else if (FillColor == 2)

            {

                FG_SetRectStyle(DG_RECT_SOLID_XOR);

                FG_Rectangle(RB_X,RB_Y,LT_X,LT_Y);

            }

            

            break;

    }



}



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

*函数说明:字符串定位函数                              *

*      输入:字符串文本坐标(1:41:16)                   *

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

void LOCATE(short Str_y,short Str_x)

{

    if (Str_x >= 1 && Str_x <=17)

    {

      Now_Str_X = Str_x;

    }

    if (Str_y >= 1 && Str_y <=4)

    {

      Now_Str_Y = Str_y;

    }

}



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

*函数说明:字符串显示函数                              *

*      输入:要显示的字符串                              *

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

void PRINT(char *Strings)

{

    short Temp_X =(Now_Str_X-1)<<3;

    short Temp_Y =(Now_Str_Y-1)<<4;

    if (Temp_X < 0)      Temp_X = 0;

    if (Temp_Y < 1)      Temp_Y = 1;

   

    Temp_X = 127 - Temp_X;

   

    Temp_Y = 63 - Temp_Y;

   

    FG_PutStr(Strings,3,Temp_X,Temp_Y);

}



#endif



-----此内容被Gorgon Meducer于2005-06-28,17:04:45编辑过


-----此内容被Gorgon Meducer于2005-06-28,17:06:00编辑过

Gorgon_Meducer 发表于 2005-6-28 17:13:26

说明一下:

我定义了一个结构体来表示菜单的每一个选项

通过指针来跳转子目录或者调用功能函数



支持滚屏、多级子菜单、网络式超链接方式(非树形)、风格修改简单。



使用这样的结构,可以很方便的通过修改单独的菜单项来更形菜单,不用在主程序里面修改任何东西,扩展方便,节约资源(某种程度上来说是的,不用因为添加了一个新的子菜单,就重新扩展无用的代码)。程序里面有很详细的说明,大家可以看一下哈,交流一下哈。
-----此内容被Gorgon Meducer于2005-06-29,16:48:42编辑过

Gorgon_Meducer 发表于 2005-6-28 20:43:33

没有人给面子哈……郁闷

wzhscj 发表于 2005-6-28 23:19:03

顶一下,我正需要这样的DD参考.谢谢傻孩子!

sgxluck 发表于 2005-6-29 11:23:48

1,通过按键改变变量值,

2,不同的变量对应不同的反显坐标值

3,变量值的不同对应不同的功能。

http://cache.amobbs.com/bbs_upload782111/files_2/armok0154648.jpg

xiaozhang 发表于 2005-6-29 11:51:49

请教旺仔,你有没贴图的例子啊??刚学习单片机,想研究一下

sgxluck 发表于 2005-6-29 14:14:21

有,不过非常遗憾,原程序是商业产品,我不能贴出。

如果你有兴趣,你可以访问金鹏科技有限公司的网站,他能提供非常完善的技术支持。www.gpt.com.cn

我这设计cpu是c51,总线方式。

xiaozhang 发表于 2005-6-29 15:01:35

上去看了一下.不知道怎么问,虽然有完善的技术支持,但那肯定是对于客户来讲的,不是针对个人

coole 发表于 2005-6-29 15:53:41

非常好,学习一下,晚上回去好好研究一下,谢谢奉献!!

Gorgon_Meducer 发表于 2005-6-29 22:48:40

旺仔

能给一个12864B的驱动么?

mymach 发表于 2005-6-30 08:35:21

谢谢!傻孩子!我要仔细学习一下!

josn-lu 发表于 2005-6-30 08:44:33

写的很好,一般界面都用到结构体和指针函数,以及树结构。

感谢傻孩子!

testcode 发表于 2005-6-30 12:45:54

顶一下。

谢谢傻孩子分享!

oxcn 发表于 2005-7-1 09:29:20

我的理解是:菜单是一个位置符号.功能实现可用转移语句,如select case类.

passerby 发表于 2006-8-30 11:08:52

顶一下,正要用到菜单,拜读完Gorgon educer的帖子,好像是入门了,非常感谢Gorgon Meducer大侠.



另,关于程序编写的细节,斗胆提两个建议.请批评指正.



1.结构体数组在定义的时候赋值应该比定义完再逐项赋值节省很多行代码,

        而编译之后的效果,比如占用rom空间之类的,我想应该是一样的.

2.MenuItem结构体中的MenuCount项似乎没什么意义,数组中的每一个元素

        都是一样的值,只是记载了数组中有多少个元素.我想设定一个变量

        也能记载,或者不设定变量,用sizeof运算符也能轻易获得数组中有多少元素.



附程序如下:(tc2.0编译,程序改编自谭浩强的教材)

#include <stdio.h>

struct stu

{

    int num;

    char *name;

    char sex;

    float score;

};



#define STU struct stu



STU boy=

{

        {101,"Li ping",'M',45},

        {102,"Zhang ping",'M',62.5},

        {103,"He fang",'F',92.5},

        {104,"Cheng ling",'F',87},

        {105,"Wang ming",'M',58},

};



int main(void)

{

        printf("sizeof-boy=%d
",sizeof(boy));

        printf("sizeof-boy=%d
",sizeof(boy));

        printf("boy's number=%d
",sizeof(boy)/sizeof(boy));

        return 0;

}



程序运行结果----

sizeof-boy=80

sizeof-boy=16

boy's number=5

CAVR 发表于 2006-8-30 11:38:47

谢谢!正好在学习菜单的编程

maigoxx 发表于 2006-8-30 16:51:44

太感谢了!正在为写菜单发愁呢

ningmeng7294 发表于 2006-8-30 19:14:36

很好!!!顶你

hhrfjz 发表于 2006-8-30 22:24:37

太好了!顶!

passerby 发表于 2006-8-31 14:23:00

发现自己在17楼的理解是错误的,MenuCount是必要的.

故又发一帖.附程序如下:

#include <stdio.h>



#define Null 0



char over=0;                                        //结束标志



//====================================

//结构体类型定义

struct MenuItem   

{

        char MenuCount;                                                                //结构体数组的元素个数

    char *DisplayString;                                                         //当前LCD显示的信息

    void (*Subs)();                                                                         //执行的函数的指针.

    struct MenuItem *Childrenms;                         //指向子节点的指针

    struct MenuItem *Parentms;                                 //指向父节点的指针

};



//====================================

//函数声明

void Nop(void);

void DoSomething(struct MenuItem *manyou);

void GameOver(void);

void Locate(struct MenuItem *manyou);

void Run(struct MenuItem *manyou);



//====================================

//结构体声明

struct MenuItem m0_main;

struct MenuItem m1_file;

struct MenuItem m1_edit;

struct MenuItem m1_view;

struct MenuItem m2_font;

struct MenuItem m1_help;



//====================================

//结构体实现

struct MenuItem m0_main=

{

        {4,"file",Nop,m1_file,Null},

        {4,"edit",Nop,m1_edit,Null},

        {4,"view",Nop,m1_view,Null},

        {4,"help",Nop,m1_help,Null},

};



struct MenuItem m1_file=

{

        {5,"open",DoSomething,Null,m0_main},

        {5,"save",DoSomething,Null,m0_main},

        {5,"save as",DoSomething,Null,m0_main},

        {5,"print",DoSomething,Null,m0_main},

        {5,"exit",GameOver,Null,m0_main},

};



struct MenuItem m1_edit=

{

        {4,"undo",DoSomething,Null,m0_main},

        {4,"redo",DoSomething,Null,m0_main},

        {4,"copy",DoSomething,Null,m0_main},

        {4,"paste",DoSomething,Null,m0_main},

};



struct MenuItem m1_view=

{

        {2,"font",Nop,m2_font,m0_main},

        {2,"color",DoSomething,Null,m0_main},

};



struct MenuItem m2_font=

{

        {3,"songti",DoSomething,Null,m1_view},

        {3,"heiti",DoSomething,Null,m1_view},

        {3,"youyuan",DoSomething,Null,m1_view},

};



struct MenuItem m1_help=

{

        {3,"index",DoSomething,Null,m0_main},

        {3,"online",DoSomething,Null,m0_main},

        {3,"about",DoSomething,Null,m0_main},

};



//====================================

//函数实现

void Locate(struct MenuItem *manyou)

{

        printf("Now we at \"%s\"
",manyou->DisplayString);       

}



void Run(struct MenuItem *manyou)

{

        (*(manyou->Subs))(manyou);

}



void Nop(void)

{}



void DoSomething(struct MenuItem *manyou)

{

        printf("we have done \"%s\"
",manyou->DisplayString);

}



void GameOver(void)

{

        over=1;

        printf("Now Game is Over
");

        getchar();

}



//====================================

//主函数

int main(int argc, char *argv[])

{

        char charin;                                                        //输入的字符

        char menuid={0,0,0};                //某一级的菜单的偏移量的记录数组

        char i=0;                                                                //上面数组的下标值



        struct MenuItem *manyou;                //漫游,在菜单中漫游



        manyou=&m0_main;                        //开始的位置

        Locate(manyou);                                        //输出



        while (!over)                                                        //如果还没完

        {       

                charin=getchar();                                //读取键盘字符

                switch (charin)                                        //根据字符跳转

                {

                        case '0':                                        //到同级菜单的后一项

                                {

                                        menuid++;

                                        if (menuid>manyou->MenuCount-1) menuid=0;//可以看到MenuCount项是必要的

                                        Locate(manyou+menuid);

                                        break;

                                }

                        case '1':                                        //到同级菜单的前一项

                                {

                                        if (menuid==0) menuid=manyou->MenuCount-1;//可以看到MenuCount项是必要的

                                        else menuid--;                                       

                                        Locate(manyou+menuid);

                                        break;

                                }

                        case '+':                                        //到下一级菜单,无下级时执行某功能

                                {

                                        if ((manyou+menuid)->Childrenms !=Null)

                                        {

                                                manyou=(manyou+menuid)->Childrenms;

                                                i++;

                                                menuid=0;

                                                Locate(manyou+menuid);

                                        }

                                        else

                                        {

                                                Run(manyou+menuid);

                                        }

                                        break;

                                }

                        case '-':                                        //到上一级菜单,无上级时给出些提示

                                {

                                        if ((manyou+menuid)->Parentms !=Null)

                                        {

                                                manyou=(manyou+menuid)->Parentms;

                                                i--;

                                                Locate(manyou+menuid);

                                        }

                                        else

                                        {

                                                printf("You are at the top of menu
");

                                        }

                                        break;

                                }       

                        default:                 break;

                }

        }       

        return 0;

}



/*

把Gorgon Meducer大侠的帖子改到了tc2.0环境环境中,--毕竟大家用到凌阳单片机的机会不多.



菜单结构

MAIN→FILE EDIT VIEW HELP

FILE →OPEN SAVE SAVEAS PRINT EXIT

EDIT→UNDO REDO COPY PASTE

VIEW→FONT COLOR

                        FONT→SONGTI,HEITI,YOUYUAN

HELP→INDEX ONLINE ABOUT



功能键

0-同级向后移

1-同级向前移

+下一级或执行某功能

- 上一级



其他注释,漫游的方式是基址加偏移量,

manyou是基址,即为某一级菜单

menuid记录了偏移量,即在该菜单中的位置



走到exit处才能退出程序.



期待批评指正.



*/

编译之后的.exe文件如下:

点击此处下载armok01127737.rar

violit 发表于 2006-9-11 23:15:22

谢谢 傻孩子!!!!!

受益匪浅!!

zdq2002 发表于 2006-10-27 18:06:47

if (MenuPoint.Subs != NullSubs)

   {

   (*MenuPoint.Subs)();

   }

为什么条件总是为真,我将NullSubs设为其它的函数也是同样,我用的是mega128,ICC6.31A

zdq2002 发表于 2006-10-27 18:09:08

Gorgon Meducer 傻孩子,你还在吗?我很希望得到你的帮助!

zdq2002 发表于 2006-10-27 18:12:08

附上我修改的程序,已经运行了,但是遇到了上面的问题,不知是否是编译器的问题

zdq2002 发表于 2006-10-27 18:15:03

不好意思,程序忘记贴了,补上





#include <lcd.h>

#include "Global.h"





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

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

* 作者:      傻孩子                              *

* 日期:      2005年6月9日                        *

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





const charMt=5;



struct MenuItem MainMenu;

struct MenuItemTimeMenu;

struct MenuItem VoiceMenu;

struct MenuItem RobotMenu;

struct MenuItem FlashMenu;



struct MenuItem TH_FlashMenu;





void NullSubs(void)

{

;

}



void state1Subs(void)

{

state=1;

}



//====================================

//结构体实现

const char tFm0[]=" Flash Record1";

const char tFm1[]="   Play1      ";

const char tFm2[]="   Pause1   ";

const char tFm3[]=" Flash Delete1";











struct MenuItem TH_FlashMenu=

{



   {4,tFm0,NullSubs,&Null,FlashMenu},

   {4,tFm1,NullSubs,&Null,FlashMenu},

   {4,tFm2,NullSubs,&Null,FlashMenu},

   {4,tFm3,NullSubs,&Null,FlashMenu},

      





};





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

*函数说明:Flash处理目录初始化函数 struct MenuItem FlashMenu;                         *

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

const char Fm0[]="Flash Record";

const char Fm1[]="      Play      ";

const char Fm2[]="      Pause   ";

const char Fm3[]="Flash Delete";

const char Fm4[]="      Back      ";





struct MenuItemFlashMenu=

{

   {5,Fm0,NullSubs,&Null,MainMenu},

   {5,Fm1,state1Subs,&Null,MainMenu},

   {5,Fm2,NullSubs,&Null,MainMenu},

   {5,Fm3,NullSubs,TH_FlashMenu,MainMenu},

   {5,Fm4,NullSubs,MainMenu,MainMenu},

   

};

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

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

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



const char Rm0[]="   TurnLeft   ";

const char Rm1[]="   Turn Right   ";

const char Rm2[]="    GoAhead   ";

const char Rm3[]="   Go Back    ";

const char Rm4[]="      Back1   ";

const char Rm5[]="      Back2   ";

const char Rm6[]="      Back3   ";

struct MenuItemRobotMenu[]=

{

   {7,Rm0,NullSubs,&Null,MainMenu},

   {7,Rm1,NullSubs,&Null,MainMenu},

   {7,Rm2,NullSubs,&Null,MainMenu},

   {7,Rm3,NullSubs,&Null,MainMenu},

   {7,Rm4,NullSubs,MainMenu,MainMenu},

   {7,Rm5,NullSubs,&Null,MainMenu},

   {7,Rm6,NullSubs,MainMenu,MainMenu},

   

};

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

声音处理目录初始化函数 struct MenuItem VoiceMenu;          *

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

const char Vm0[]="Voice Record";

const char Vm1[]="      Play      ";

const char Vm2[]="      Pause   ";

const char Vm3[]="Voice Delete";

const char Vm4[]="      Back      ";





struct MenuItemVoiceMenu=



{

   {5,Vm0,NullSubs,&Null,MainMenu},

   {5,Vm1,NullSubs,&Null,MainMenu},

   {5,Vm2,NullSubs,&Null,MainMenu},

   {5,Vm3,NullSubs,&Null,MainMenu},

   {5,Vm4,NullSubs,MainMenu,MainMenu},

   

};



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

*时间设定子目录初始化      struct MenuItem TimeMenu;   *

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



const char Tm0[]="    Time Set    ";

const char Tm1[]="    Date Set    ";

const char Tm2[]="    AlertSet    ";

const char Tm3[]="      Back      ";



struct MenuItemTimeMenu=

{

   {4,Tm0,NullSubs,&Null,MainMenu},

   {4,Tm1,NullSubs,&Null,MainMenu},

   {4,Tm2,NullSubs,&Null,MainMenu},

   {4,Tm3,NullSubs,MainMenu,MainMenu},

   

};





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

* 根目录初始化struct MenuItem MainMenu;                                    *

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

const char Mm0[]="    Time Set    ";

const char Mm1[]="Voice Center";

const char Mm2[]="Flash Option";

const char Mm3[]="Robot Option";

struct MenuItemMainMenu=

{

   {4,Mm0,NullSubs,TimeMenu,&Null},

   {4,Mm1,NullSubs,VoiceMenu,&Null},

   {4,Mm2,NullSubs,FlashMenu,&Null},

   {4,Mm3,NullSubs,RobotMenu,&Null},

};

   





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

*   使用说明:                                    *

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

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

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

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

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

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

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

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

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

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

*         函数。                                    *

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











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

*   按键功能键宏定义   *

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

#define UP      0

#define Down      4

#define Enter   5

#define Esc       1

#define Reset   2



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

*   全局变量声明区   *

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



//struct MenuItem (*MenuPoint) = MainMenu;   

struct MenuItem *MenuPoint;   

    //(*MenuPoint) = MainMenu;

   // signed char UserChoose = 0;

   // char DisplayPoint = 0;

//char MaxItems;   

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

*   函 数 声 明 区   *

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





void ShowMenu(void);

unsigned char GetKeyNum(void);

void LOCATE(unsigned char Str_y,unsigned charStr_x);

void PRINTg(const char *Strings);





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

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

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

void ShowMenu(void)

{

    unsigned char n = 0;



    MaxItems = MenuPoint.MenuCount;

    DisplayPoint = DisplayStart;

   if (MaxItems >= 4)

   {

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

      {

                     

            //LOCATE(n+1,1);

            //PRINTg(MenuPoint.DisplayString);

            LCD_displaystrings_12_24_F(MenuPoint.DisplayString,n*24,0);

            if ((DisplayPoint) == UserChoose)

                {

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

                  ;

                                  LCD_L0_DrawBox(0 ,n*24,239 ,(n+1)*24-1,1);

                }

            

                DisplayPoint +=1;

                if ((DisplayPoint) == (MaxItems))

                {

                      DisplayPoint = 0;

                               

                }

      }

    }

    else

    {

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

      {

                     

            LOCATE(n+1,1);

            //PRINTg(MenuPoint.DisplayString);

                       

                        LCD_displaystrings_12_24_F(MenuPoint.DisplayString,n*24,0);

            

            if ((DisplayPoint) == UserChoose)

                {

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

                  ;

                               LCD_L0_DrawBox(0 ,n*24,239 ,(n+1)*24-1,1);

                }

            

                DisplayPoint +=1;

                if ((DisplayPoint) == (MaxItems))

                {

                  DisplayPoint = 0;

                }

            

      }

    }

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

}



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

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

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

unsigned char GetKeyNum(void)

{

    unsigned charTempKeyNum = 0;

   TempKeyNum = 0;       //获取按键值

   return TempKeyNum;



}





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

*函数说明:字符串定位函数                              *

*      输入:字符串文本坐标(1:41:16)                   *

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

void LOCATE(unsigned char Str_y,unsigned charStr_x)

{

    ;

}



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

*函数说明:字符串显示函数                              *

*      输入:要显示的字符串                              *

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

void PRINTg(const char *Strings)

{

;

}

附:Gloabl.h



#ifdef main_GLOBALS

#define main_EXT

#else

#define main_EXT extern

#endif





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

*    目录结构体定义   *

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



struct MenuItem   

{

    char   MenuCount;

    const char *DisplayString;

    void (*Subs)();

    struct MenuItem *ChildrenMenus;

    struct MenuItem *ParentMenus;

};





main_EXT unsigned char display;

main_EXT unsigned char chinese;

main_EXT signed long adc_value;

main_EXT unsigned char strtemp;

main_EXT unsigned char zuobiao_x;





main_EXT unsigned char zuobiao_y;







extern struct MenuItem (*MenuPoint);

extern struct MenuItem MainMenu;

extern struct MenuItemTimeMenu;

extern struct MenuItem VoiceMenu;

extern struct MenuItem RobotMenu;

extern struct MenuItem FlashMenu;

extern struct MenuItem TH_FlashMenu;





main_EXT signed char UserChoose;

main_EXT char DisplayStart;

main_EXT char DisplayPoint;

main_EXT char MaxItems;



extern struct MenuItem MainMenu;



//main_EXT struct MenuItem (*MenuPoint);

main_EXT struct MenuItem Null;





/*

main_EXT struct MenuItem VoiceMenu;







struct MenuItemVoiceMenu=



{

   {5,Vm0,NullSubs,&Null,MainMenu},

   {5,Vm1,NullSubs,&Null,MainMenu},

   {5,Vm2,NullSubs,&Null,MainMenu},

   {5,Vm2,NullSubs,&Null,MainMenu},

   {5,Vm4,NullSubs,MainMenu,MainMenu},

   

}; */

///键盘

main_EXT signed char state;

main_EXT signed char key_age;

main_EXT signed char key_code;

main_EXT signed char key_ok;

main_EXT signed char key_lx;

main_EXT signed char eninput_fast;



/////

zdq2002 发表于 2006-10-28 17:06:16

怎么没有人来逛啊!

问题已经解决了,是编译器的问题,ICC6.31A上手容易,个人感觉不好用,特别是对于结构定义不好用,我用IAR 4.10B 后问题解决了

Recoochang 发表于 2006-11-1 00:06:27

谁能把我打成傻孩子????!!!牛!

wagina 发表于 2007-4-11 10:38:01

谢谢!参考下,可以移植到avr就好了,那位大虾有avr编写的菜单程序啊,想参考下!

climber 发表于 2007-5-5 11:59:26

特别感谢 Gorgon Meducer 傻孩子



谢谢你的无私!

zxw2008 发表于 2007-7-30 22:56:22

一屏四行,当超出四行时如何显示菜单?

fendouboy 发表于 2007-7-31 00:37:02

无语拉,太精彩拉,谁能帮下我啊,我有问题急啊,关于菜单显示的,加我QQ:675760769

谢谢啊

ATmega32 发表于 2007-9-11 12:34:32

GCCAVR支持函数指针。

usbfish 发表于 2007-9-11 16:33:25

【32楼】 zxw2008一屏四行,当超出四行时如何显示菜单?
晕,切屏呗,这还不简单。

pcwinner 发表于 2007-10-4 08:39:51

留个名先。。。。。呵呵

654987 发表于 2007-10-8 00:36:37

谢谢,正需要

microcheng 发表于 2007-10-11 13:56:52

mymach 发表于 2007-10-11 14:27:21

好久前的帖子!!
再来顶一下
哈哈哈~~~~~

HZZCL 发表于 2008-1-9 09:47:44

标记

gdqhik 发表于 2008-1-9 10:45:14

作个标记,要是网站能提供收藏就好了

LQH32316812 发表于 2008-1-9 11:35:28

先学习,以后用的上.

lb6035 发表于 2008-1-9 22:05:49

好帖,顶下

yulutong 发表于 2008-1-25 14:48:14

原来傻孩子在05年的时候就比较牛X了。想想我大学生活是怎么过的,不能比啊。

lixuan 发表于 2008-1-28 17:44:12

vb

lixuan 发表于 2008-1-28 17:44:43

liandao 发表于 2008-1-28 18:31:13

《一个占用内存极少的菜单系统的实现》
http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=798580&bbs_page_no=1&bbs_id=1000

这不是有一个现成可用的框架么?而且文档也有呀。

演示+文档+源代码
目录:
一些手机界面的分析                                          
图标层代码实现分析                                             
条项层代码实现分析                                                
菜单框架的代码实现                                             
模版代码讲解                                                   
动态内容层菜单                                                
动态生成条项菜单内容                                          
数字快捷方式的实现                                             
菜单函数调用图                                                
问答FAQ                                                            
这个东西哪来的?                                                
能在51这种低速CPU上跑不?                                       
我担心我的CPU速度不够快,能用这个菜单不?                        
这个菜单框架的内存耗损大不不大?                                 
怎么移植?                                                      
关于移植的建议                                                   
杂项                        
开机直接执行某些功能
如何实现中断中使用LCD?
数字建快捷方式
关于多国语言切换:
关于内存耗损:
关于更多的改进:
关于快捷方式:
关于如何实现在线帮助提示
如何快速创建一个条项层菜单?
在FramBuffer型LCD上直接使用这份代码                           
为什么公布这份代码,使用的话需要授权什么的么?                  

文件目录:
1. MenuSampleCode目录是代码这份代码我在我的硬件上测试过。
2.说明文档是:一个占用内存极少的菜单系统的实现.pdf
3.menu.gif是一个演示
4.目录说明
MenuSampleCode\SI    Source Insight 3.5 的工程文件
MenuSampleCode\Menu.Uv2Keil 的工程
MenuSampleCode\Src   源代码
MenuSampleCode\Obj   目标文件
MenuSampleCode\Lst   列表文件
可以看MenuSampleCode\Lst\menu.m51最后编译的结果:
代码状况:

Program Size: data=9.0 xdata=110 code=15731
creating hex file from ".\Obj\menu"...
".\Obj\menu" - 0 Error(s), 0 Warning(s).
这是打开动态条项生成功能时的结果。

Program Size: data=9.0 xdata=79 code=15155
creating hex file from ".\Obj\menu"...
".\Obj\menu" - 0 Error(s), 0 Warning(s).
这是关闭动态条项生成功能时的结果。

菜单深度均为4层深度。
25+4*3 = 37Byte 可见占用内存还是挺小的。
源文件说明
CPU.H      CPU相关定义
Main.C       主函数
Ks0108.C   LCD驱动
ASCII.c      8x8 8x16 英文字模
KeyScan.C    键盘扫描
MenuPara.C   菜单函数使用模版
MenuTop.C    顶层菜单和菜单核心代码
MenuFSM.C    菜单核心和FSM代码
MenuFunc.C   功能菜单和动态条项生成代码
MenuLanguage.C   语言切换代码
MenuMeasure.C    空例子
PIC.C            图标
MenuMain.C       菜单主循环
KeyScan.H      
Ks0108.H   
Menu.H
Menu.C         main函数
Chinese.txt      用到的中文
Chinese.C      中文字模

Simulation.exe是uCGUI上移植的演示。
可以通过你的键盘控制菜单:
你的PC键盘的四个方向键:
向上键:确定
向下键:ESC
向左键:向左
向右键:向右
默认语言是英文,你可以进入设置成中文。
PS:不提供这个的代码。请不要问我要。其实Src的源代码的效果也就是这个的运行效果。
包括动态条项生成功能。
自己下载吧。

ylei12 发表于 2008-5-8 22:51:11

好复杂啊,先留个记号,该努力学习了:)

kaif_w 发表于 2008-5-8 22:57:47

如些好贴!!不顶不成啊~~~

glbest 发表于 2008-5-8 23:57:38

mark

Id001 发表于 2008-5-17 11:14:12

好~~~~谢谢

bear1394 发表于 2008-5-17 11:31:43

mark

wenming 发表于 2008-5-17 11:44:37

欢迎傻孩子归来!程序的风格很好。条理清晰,以后教我写软件算了,呵呵~~~~ 看看自己写的代码,由于缺少软件工程的思想,一塌糊涂。
难怪,自己原来是做机械的,~~~

armfans 发表于 2008-5-21 23:27:39

傻孩子的程序结构很清晰,很容易看懂,有时自己写的东西自己都能迷糊,惭愧

TonyCai 发表于 2008-5-21 23:39:16

要的,看了。

zlutian 发表于 2008-5-22 01:33:48

mark

duqinglin 发表于 2008-5-22 08:49:13

非常好

yibin818 发表于 2008-5-22 13:13:48

好贴,顶一下

liyfmc 发表于 2008-5-22 21:38:26

记下,正要写菜单程序

weiwgml 发表于 2008-5-22 22:03:48

Mark

ylshu 发表于 2008-5-29 22:16:54

这样的 经典的 帖子,是一定要顶的!!!感谢傻孩子的奉献!

gerbee 发表于 2008-5-29 22:20:23

很有启发 多谢了

pcwinner 发表于 2008-5-29 22:28:52

..

zhuzi1441 发表于 2008-5-29 23:15:30

记个号,会用得着,谢谢!

our_avr 发表于 2008-5-30 08:45:50

不错。有空要好好研究研究。

lxx_sea_sky 发表于 2008-6-3 09:54:34

鸡蛋里挑骨头
函数void ShowMenu(void) 里“if (MaxItems >= 4)”的两个分支是一样,那么加一句if (MaxItems >= 4) MaxItems = 4;
就可以不用分支了。


--------------------------
想到菜单的所有变量都是不变的,所以想定义在程序区(SRAM是宝贵的:)),结果失败!!!因为程序区变量只能初始化一次,而父菜单指针和子菜单指针互指,不管先定义哪一个,初始化都会引用未定义的菜单地址:(
求教:有没有更好的办法?

sciencehero 发表于 2008-6-3 15:18:12

本坛又多了一位会员啊

xiaokangkang 发表于 2008-6-3 15:55:41

MARK

yzlyear 发表于 2008-6-3 18:06:33

MARK

lxx_sea_sky 发表于 2008-6-18 15:18:06

参考了傻孩子大虾和marker大虾的帖子终于把菜单扔进程序区了,sram区只定义了三个变量:
const struct MenuItem *MenuPoint;                //当前菜单指针
const void (*MenuFunc)(void);                 //当前函数指针
volatile uchar UserChoose;                        //当前菜单用户选项

对67楼的补充:定义并初始化菜单变量之前,先要声明为外部变量

Peasant 发表于 2008-6-18 20:21:56

很早前就有这个困惑了,不知道怎么实现 LCD菜单,,,,多谢啦,,,

346675655 发表于 2008-6-24 16:45:17

mark

bxs19830629 发表于 2008-7-1 20:18:12

mark

lonely88 发表于 2008-7-15 16:33:35

Menumark

heroxue 发表于 2008-7-30 15:49:16

Mark

117433525 发表于 2008-8-18 10:05:30

做个记号

crystal524 发表于 2008-8-20 19:49:25

大家好,我有个问题,能帮帮我吗,定义的void (*Subs)()是不是必须指向参数个数相同的函数,如果可以指向不同类型的函数,比如说参数个数不同的函数,那函数的参数怎样传递呢,小女子在这里谢谢好心人了,呵呵

zuoyou 发表于 2008-8-20 22:07:14

mark

551559339 发表于 2008-8-26 22:48:05

mark~

cuhon 发表于 2008-8-27 09:56:44

留个脚印

raojin 发表于 2008-9-11 14:26:49

/**************************************************************
*函数说明:目录显示函数                                     *
**************************************************************/
void ShowMenu(void)
{
    short n = 0;

    MaxItems = MenuPoint.MenuCount;
    DisplayPoint = DisplayStart;
      if (MaxItems >= 4)
      {
             for (n = 0;n<4;n++)
             {
                        
               LOCATE(n+1,1);
               PRINT(MenuPoint.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.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);
}
这部分看不懂,这n在里面究竟是什么意思,起什么作用呢?

Nicholas_wolf 发表于 2008-9-17 18:30:29

十分感谢作者的倾情奉献。

chuyu111 发表于 2008-9-17 18:36:48

好贴

mark

gaochaoning 发表于 2008-9-17 18:52:47

记下了。谢谢。

chairang 发表于 2008-9-17 19:44:55

收下了

wajlh 发表于 2008-9-17 22:41:31

收下

knight_avr 发表于 2008-9-18 08:37:02

顶啊

spely 发表于 2008-9-18 09:15:08

收下,mark~

heavin_150 发表于 2008-9-18 13:19:59

mark

hlwjx 发表于 2008-9-18 13:45:00

mark

kengao55 发表于 2008-9-18 17:29:13

标记

jettlau 发表于 2008-9-19 08:57:02

&nbsp;&nbsp;&nbsp;学无止境啊!

谢了!

mldmldmld 发表于 2008-9-20 00:10:06

收藏了、谢楼主!

duqinglin 发表于 2008-10-27 15:13:23

收藏!!!

jclhp 发表于 2008-10-27 16:24:18

学习

weq12345 发表于 2008-10-31 12:42:26

不顶不行

armok 发表于 2008-11-1 07:12:05

heizi302 发表于 2008-11-1 10:29:44

好贴,近期正学习LCD方面的驱动,顶!

mfkqqw 发表于 2008-11-1 18:25:30

好贴
页: [1] 2 3 4
查看完整版本: 有谁能够谈谈LCD中菜单的实现和编程方法?