本人刚接触这个时间不长,所以把学到的点滴记录下来,以备今后参考。
之前做过一个液晶显示的,因为做的是顺序菜单,没有分叉,所以比较简单,但是现在这个是有分叉的,而且要选择,所以感觉就有点摸不着头脑,下面先看这个菜单的一个小部分,其实总体结构也是这样的。
要求选中的项要反白显示,下面给出一种在次菜单中循环显示的方法:
uint8 MainMenuDisplay(uint8 MenuNum)
{
uint8 CurrentMenuNum;
uint8 PreMenuNum,i;
// uint8 MenuRow;
// uint8 MenuCol;
uint8 MaxMenuNum;
uint16 TimeoutCnt = 0; //记录超时次数
uint16 code* mmenu_ptr=(uint16 code*)main_menu[0].menu_ptr;
CurrentMenuNum = MenuNum;
Key = 0xff;
MaxMenuNum = main_menu[0].menu_num;
if(CurrentMenuNum > MaxMenuNum)
{
CurrentMenuNum = 0;
}
while((Key!=K_ENTER)&&(Key!=K_ESC))
{
if(ScreenStatus!=SCR_MAIN_MENU) //这部分是显示最初的状态,就是屏幕从上一个屏幕切换到当前屏幕
{
ScreenStatus = SCR_MAIN_MENU;
PreMenuNum = CurrentMenuNum;
LcdClearGBuff(0);
LcdGraphToGBuff((main_menu[0].start_row +PreMenuNum)*16, main_menu[0].start_col*2, 2, 16, MenuShading3Code, PAGE0); // 预置底纹
OSSemPend(SEM_LCD_WR,0);
LcdClearDDRam();
LcdClearGDRAM();
i = (main_menu[0].start_row)*16;
LcdPaintArea(i, main_menu[0].start_col*2, i+15, main_menu[0].start_col*2+1, 0);
LcdGraphOn();
for(i=0;i<MaxMenuNum;i++)
{
LcdWriteStr(1 + i, 1,mmenu_ptr , main_menu[0].menu_max_len);
mmenu_ptr += main_menu[0].menu_max_len;
}
OSSemPostBin(SEM_LCD_WR);
}
TaskCnt[OSRunningTaskID()] = 0;
if(PreMenuNum != CurrentMenuNum)//刷新光标,随着菜单号的改变,不同的选项反白显示,表示选中
{
LcdGraphToGBuff((main_menu[0].start_row +PreMenuNum)*16, main_menu[0].start_col*2, 2, 16, MenuShading3Code, PAGE0);
LcdGraphToGBuff((main_menu[0].start_row +CurrentMenuNum)*16, main_menu[0].start_col*2, 2, 16, MenuShading3Code, PAGE0);
OSSemPend(SEM_LCD_WR,0);
i = (main_menu[0].start_row +PreMenuNum)*16;
LcdPaintArea(i, main_menu[0].start_col*2, i+15, main_menu[0].start_col*2+1, 0);
i = (main_menu[0].start_row +CurrentMenuNum)*16;
LcdPaintArea(i, main_menu[0].start_col*2, i+15, main_menu[0].start_col*2+1, 0);
OSSemPostBin(SEM_LCD_WR);
PreMenuNum = CurrentMenuNum;
}
if(OSQPend(&Key, Q_KeyValue, 8) == OS_Q_TMO)
{
Key = K_NONE;
TimeoutCnt++;
if(TimeoutCnt>50) // 50*8*25ms = 10s
{
OSSemPend(SEM_LCD_WR,0);
LcdClearDDRam();
LcdGraphOff();
OSSemPostBin(SEM_LCD_WR);
Key = K_NONE;
return(0xff); // 取消
}
}
else
{
TimeoutCnt = 0;
}
switch(Key)
{
case K_DOWN:
CurrentMenuNum++;
if(CurrentMenuNum >= MaxMenuNum) CurrentMenuNum = 0;
break;
case K_UP:
CurrentMenuNum--;
if(CurrentMenuNum >=MaxMenuNum) CurrentMenuNum = MaxMenuNum-1;
break;
default:
break;
}
}
OSSemPend(SEM_LCD_WR,0);
LcdGraphOff();
LcdClearDDRamLine(3);
OSSemPostBin(SEM_LCD_WR);
if(Key == K_ESC) //取消则返回上级菜单
{
Key = K_NONE;
return(0xff); // 取消
}
Key = K_NONE;
return(CurrentMenuNum); //回车则返回当前菜单号,进入相应的下一级菜单显示
}
代码的大致结构是这样的:
。。。。
while(条件)
{
刷新内容;
刷新光标;(当菜单号改变的时候,光标永远在当前菜单号上,即当前菜单号反白显示)
检测按键;
(因为按键的不同,菜单号加减)
如果按键式回车,则函数返回当前菜单号,函数跳转到相应菜单号的子函数;
}
这个现实思路还是比较清晰的,先记下这个吧。因为接触的比较少,不知道是否还有比这个更简单吗?
|