//形成网树菜单,最简便的嵌入式系统LCD显示界面设计,每一个菜单项有上下左右4个指针,遍历菜单非常方便
typedef struct MenuItemType
{char Name[10]; u32 Class; //菜单项目的名称及特征
int x,y; // 菜单项目的屏幕显示坐标
struct MenuItemType *Up,*Down,*Left,*Right; //指向菜单项目的上下左右相邻
} MenuType;
MenuType Menu[]=
{
{"采样" , 0x00100000,1,2 },
{"定值操作", 0x00200000,1,3 },
{"装置参数", 0x00300000,1,4 },
{"历史报告", 0x00400000,1,5 },
{"功能测试", 0x00500000,1,6 },
{"其他功能", 0x00600000,1,7 },
{"有效值" , 0x00110000,10,2},
{"向量" , 0x00120000,10,3},
{"测量值" , 0x00130000,10,4},
{"开入量" , 0x00140000,10,5},
{"电度量" , 0x00150000,10,6},
{"查看定值" , 0x00210000,10,2},
{"修改定值" , 0x00220000,10,3},
{"运行定值", 0x00211000,19,2},
{"其他定值", 0x00212000,19,3},
{"运行压板", 0x00213000,19,4},
{"额定参数", 0x00211100,28,2},
{"两段保护", 0x00211200,28,3},
{"过流保护", 0x00211300,28,4},
{"堵转保护", 0x00211400,28,5},
{"过负荷", 0x00211500,28,6},
{"不平衡保护", 0x00211600,28,7},
{"过压欠压", 0x00211700,28,8},
{"漏电保护", 0x00211800,28,9},
{"非电量保护", 0x00211900,28,10},
{"辅助功能", 0x00211A00,28,11},
{"运行定值", 0x00221000,19,2},
{"内部定值", 0x00222000,19,3},
{"运行压板", 0x00223000,19,4},
{"额定参数", 0x00221100,28,2},
{"两段保护", 0x00221200,28,3},
{"过流保护", 0x00221300,28,4},
{"堵转保护", 0x00221400,28,5},
{"过负荷", 0x00221500,28,6},
{"不平衡保护", 0x00221600,28,7},
{"过压欠压", 0x00221700,28,8},
{"漏电保护", 0x00221800,28,9},
{"非电量保护", 0x00221900,28,10},
{"辅助功能", 0x00221A00,28,11},
{"日期时钟" , 0x00310000,10,2},
{"运动参数" , 0x00320000,10,3},
{"通信参数" , 0x00330000,10,4},
{"动作报告", 0x00410000,10,2},
{"告警报告", 0x00420000,10,3},
{"通信变位", 0x00430000,10,4},
{"操作记录", 0x00440000,10,5},
{"测试功能", 0x00610000,10,2},
{"运动传动", 0x00611000,19,2},
{"保护传动", 0x00612000,19,3},
{"修改口令", 0x00620000,10,2},
{"模式切换", 0x00630000,10,3},
{"装置状态", 0x00640000,10,4},
{"厂家设置", 0x00650000,10,5},
{"版本信息", 0x00660000,10,6},
};
MenuType *MenuP=Menu; //指向菜单数组的第一项
void Menu_Dis() //显示当前菜单指针所指向的某一例
{
MenuType *MenuP1= MenuP;
do {
PrintGBNew(MenuP1->x,MenuP1->y,MenuP1->Name);
MenuP1 = MenuP1->Down;
}
while (MenuP1 != MenuP);
ReversePrintGBNew(MenuP1->x,MenuP1->y,MenuP1->Name);
}
void Menu_NDis() //取消显示当前菜单指针指向的这一列
{
MenuType *MenuP1= MenuP;
do {
PrintGBNew(MenuP1->x,MenuP1->y," ");
MenuP1 = MenuP1->Down;
}
while (MenuP1 != MenuP);
}
void Menu_Up() //显示当前菜单的前一项,取消反白当前项
{
MenuType *MenuP1=MenuP;
PrintGBNew(MenuP1->x,MenuP1->y,MenuP1->Name);
MenuP = MenuP->Up;
ReversePrintGBNew(MenuP->x,MenuP->y,MenuP->Name);
}
void Menu_Down() //显示当前菜单的下一项,取消反白前一项
{
MenuType *MenuP1=MenuP;
PrintGBNew(MenuP1->x,MenuP1->y,MenuP1->Name);
MenuP = MenuP->Down;
ReversePrintGBNew(MenuP->x,MenuP->y,MenuP->Name);
}
//形成网树菜单
void Menu_Init()
{
int i,j,k;
u32 CSD,CSE;
int MenuSize = sizeof(Menu) / sizeof(MenuType);
for (i=0; i< MenuSize; i++)
{
CSD = 0x0000000F;
CSE = 0xFFFFFFFF;
while ( (Menu[i].Class & CSD ) ==0) //从右边开始取数,碰到第一个非 0
{
CSD <<=4;
CSE <<=4;
}
j = (i+1) % MenuSize;
while ( !
(
(Menu[j].Class & (CSE << 4)) == (Menu[i].Class & (CSE << 4))
&&
(Menu[j].Class & (CSD >> 4)) == (Menu[i].Class & (CSD >> 4))
)
||
(Menu[j].Class & (CSD )) == 0x0
)
j = (++j) % MenuSize ;
if (Menu[i].Down == 0)
Menu[i].Down = &Menu[j]; //形成下指针
if ( Menu[j].Up == 0)
Menu[j].Up = &Menu[i]; //形成上指针
for ( k=0; k < MenuSize; k++)
if (
(Menu[k].Class & CSE ) == (Menu[i].Class & CSE )
&&
(Menu[k].Class & (CSD >> 4)) != (Menu[i].Class & (CSD >> 4) )
&&
(Menu[k].Class & ((CSE >>4) ^ 0xFFFFFFFF) ) == (Menu[i].Class & ((CSE >>4) ^ 0xFFFFFFFF) )
)
{ if ( Menu[k].Left == 0 )
Menu[k].Left = &Menu[i]; //形成左指针
if ( Menu[i].Right == 0 )
Menu[i].Right = &Menu[k]; //形成右指针
}
}
}