达.芬奇密码中数字:什么是菜单程序

来源:百度文库 编辑:高考问答 时间:2024/05/05 09:00:25

文章内容:

/*******************************************************************************
*
菜单控制
模块退出时必须向菜单管理发出菜单关闭消息
********************************************************************************
/
#include <iom128v.h>
#include <macros.h>
#include <Eeprom.h>

#include "Const.h"
#include "EepromEnum.h"
#include "News.h"
#include "NewsEnum.h"
#include "Window.h"
#include "Source.h"

#include "LcdDrive.h"
#include "Timer.h"
#include "CpuEeprom.h"
#include "Serial.h"
#include "Math.h"
#include "Sound.h"

enum{
eLEFT,
eRIGHT
};

#define TIME_MENULIMIT 40 //菜单显示时间

static unsigned char mMenu_TimeLimit; //控制菜单显示时间,以秒为单


static unsigned char mMenu_Id; //在使用的菜单的层里面的索引
static unsigned char mMenu_ItemId; //菜单层的项索引
static unsigned char fMenu_Select; //=1菜单选中了,已经离开菜
单,执行功能去了,执行完返回控制给菜单,会清0

static unsigned char fMenu_RequStore; //菜单选择有效请求,模块响应
后,退出时发nMenu_ReturnControl,控制权交回菜单

/******************************************************************
菜单结构定义
******************************************************************/
struct MenuUnit{ //菜单单元结构
unsigned char mX;
unsigned char mY;

unsigned char Str[6]; //显示的字符串

unsigned char mSubId; //选中后执行的子
菜单一层的ID,==0无,和mNewsId关联
unsigned char mNewsId; //选中后执行的消
息ID,==0无,和mSubId关联

unsigned char mReturnId; //退出后执行的菜
单层的ID号,==0相当关闭,由本身
};

static const struct MenuUnit *psMenuCurrentUnit;

/******************************************************************
菜单构造
x,y, 字符串 要执行的ID,要执行的消息 返回执行的ID
******************************************************************/
const struct MenuUnit sMenuUnit_Close[]={ //每行是个SubId.
关闭菜单,ID=0
0,9, "\x097", 0, nXxx0_On, 0, //关闭菜单
};

const struct MenuUnit sMenuUnit_Main[]={ //每行是个SubId.
主菜单,ID=1
0,9, "\x090", 2, 0, 0, //
20,9, "\x091", 0, nXxx1_On, 0, //
40,9, "\x092", 0, nXxx2_SetupOn, 0, //设置
60,9, "\x098", 3, nSetVolume_On, 0, //参数调节,执行
ID=3的菜单
80,9, "\x099", 0, nPrinter_SetupOn, 0, //打印设置
100,9, "\x096", 0, 0, 0, //BACK,向上回去
};

const struct MenuUnit sMenuUnit_Moudel[]={ //每行是个SubId.
模块菜单,ID=2
0,4, "Xxx31", 0, nXxx30_SetupOn, 0, //Xxx30
36,4, "Xxx32", 0, nXxx31_SetupOn, 0, //Xxx31
72,4, "Xxx4", 0, nXxx4_SetupOn, 0, //Xxx4
0,14, "Xxx5", 0, nXxx5_SetupOn, 0, //Xxx5
36,14, "Xxx5", 0, nXxx5_SetupOn, 0, //Xxx5
72,14, "Xxx5", 0, nXxx5_SetupOn, 0, //Xxx5
108,9, "\x096", 1, 0, 0, //BACK,向上回去
};

const struct MenuUnit sMenuUnit_AdjVolume[]={ //每行是个SubId.
参数调节菜单,ID=3
0,9, "\x094", 0, nSetAlarmVolume_On, 4, //声音,返回执行
ID=4,继续报警音量调节
};

const struct MenuUnit sMenuUnit_AdjAlarm[]={ //每行是个SubId.
参数调节菜单,ID=4
0,9, "\x094", 0, nSetLight_On, 5, //声音,返回执行
ID=5,继续亮度
};

const struct MenuUnit sMenuUnit_AdjLight[]={ //每行是个SubId.
参数调节菜单,ID=5
0,9, "\x094", 0, 0, 0, //亮度,返回执行
ID=0.
};

//一层菜单,有很多菜单单元组成
const struct MenuUnit * const psMenuLayer[]={
sMenuUnit_Close, //ID=0,关闭菜单
sMenuUnit_Main, //ID=1,主菜单
sMenuUnit_Moudel, //ID=2,模块选择
sMenuUnit_AdjVolume, //ID=3,设置音量
sMenuUnit_AdjAlarm, //ID=4,设置报警
音量
sMenuUnit_AdjLight, //ID=5,亮度调节
};

const unsigned char mMenuLayerMax[]={
sizeof(sMenuUnit_Close)/sizeof(struct MenuUnit), //ID=0,关闭菜单
sizeof(sMenuUnit_Main)/sizeof(struct MenuUnit), //ID=1,主菜单
sizeof(sMenuUnit_Moudel)/sizeof(struct MenuUnit), //ID=2,模块选择
sizeof(sMenuUnit_AdjVolume)/sizeof(struct MenuUnit), //ID=3,设置音量
sizeof(sMenuUnit_AdjAlarm)/sizeof(struct MenuUnit), //ID=4,设置报警
音量
sizeof(sMenuUnit_AdjLight)/sizeof(struct MenuUnit), //ID=5,亮度调节
};

#define dSPEEDKEY_MenuId 1 //快捷键对应功能
的菜单项
#define dSPEEDKEY_MenuItemId 0 //快捷键对应功能
的菜单项中的选项

/******************************************************************
清除菜单区域
******************************************************************/
void InMenuWindowCls(void)
{
Lcd_SetupId(Eeprom_Read(eP_DW_Menu));
LcdData_ClrScreen( (em_BLACK<<4)+em_BLACK );
}/******************************************************************
显示当前菜单
必须窗口有效
只有一项时不反白显示.这样关闭菜单或单参数菜单不反白。
已经设置好全局的菜单指针
******************************************************************/
void InMeun_DispItem(unsigned char mId)
{
Lcd_SetupId(Eeprom_Read(eP_DW_Menu));
if(LcdData_WindowVisible()==False)return;

psMenuCurrentUnit=&(psMenuLayer[mMenu_Id])[mId]; //得到当前菜单项
的结构指针

LcdData_MoveTo( (*psMenuCurrentUnit).mX,(*psMenuCurrentUnit).mY );
if((mId==mMenu_ItemId)&&(mMenuLayerMax[mMenu_Id]>1)){
//反白显示
LcdData_SwapColor();
}
LcdData_CodeStrings( (*psMenuCurrentUnit).Str,em_CharOverlay );

psMenuCurrentUnit=&(psMenuLayer[mMenu_Id])[mMenu_ItemId]; //得到当前菜
单项的结构指针
}

/******************************************************************
移动
mXxx1=eLEFT,左,否则右
******************************************************************/
void InMeun_MoveItem(unsigned char mXxx1)
{
unsigned char i;

if(mMenu_Id==0){
//展开
mMenu_Id=1;
mMenu_ItemId=0;

for(i=0;i<mMenuLayerMax[1];i++){
InMeun_DispItem(i);
}
}
else {
if(mXxx1==eLEFT){
i=mMenu_ItemId;
if(mMenu_ItemId==0){
mMenu_ItemId=mMenuLayerMax[mMenu_Id]-1;
}
else mMenu_ItemId--;
}
else {
i=mMenu_ItemId++;
if(mMenu_ItemId==mMenuLayerMax[mMenu_Id]){
mMenu_ItemId=0;
}
}
InMeun_DispItem(i);
InMeun_DispItem(mMenu_ItemId);
}
}

/******************************************************************
显示全部菜单项,并设置相应参数
******************************************************************/
void InMenu_DispNewMenuItem(unsigned char mItem)
{
unsigned char i,j;

InMenuWindowCls();
mMenu_ItemId=0;
mMenu_Id=mItem;

j=mMenuLayerMax[mMenu_Id];

for(i=0;i<j;i++)InMeun_DispItem(i);
}

/******************************************************************
菜单确认时执行动作
******************************************************************/
void InMenu_Valid(void)
{
if((fMenu_RequStore)||(fMenu_Select))return;

if( (*psMenuCurrentUnit).mNewsId>0){
//有消息,改变当前消息。
fMenu_RequStore=(*psMenuCurrentUnit).mNewsId; //有选择,等待模
块返回
fMenu_Select=1; //选择有效

News_Push(fMenu_RequStore);
if((*psMenuCurrentUnit).mSubId>0){
//有子菜单命令,执行
InMenu_DispNewMenuItem((*psMenuCurrentUnit).mSubId);
}
}
else {
InMenu_DispNewMenuItem((*psMenuCurrentUnit).mSubId);
}
}

/******************************************************************
主菜单选中时,执行的转换或相应处理
转发消息
******************************************************************/
void InMenu_ChangeNews(void)
{
News_Replace((*psMenuCurrentUnit).mNewsId+1+gNews_Word-eNews_KeySpeed);
}

/******************************************************************
菜单中的消息转换的消息处理:eNews_beign
******************************************************************/
void Menu_NewsPreProcess(void)
{
if(gNews_Word<eNews_KeySpeed){
switch(gNews_Word){
case eNews_KeyPush0: //
Timer3_Switch();
break;

case eNews_KeyPush1: //Xxx5
News_Replace(nXxx5_Ctl_Key);
break;

case eNews_KeyPush2: //
News_Replace(nSound_ClockSwitch);
break;

case eNews_KeyPush3: //保留
News_Pop();
break;
}
return;
}

if( gNews_Word>eNews_KeyPushReturn )return; //只对快捷键,左,右,回车控


mMenu_TimeLimit=0; //清计时器
if(fMenu_Select==1){
InMenu_ChangeNews(); //已经在有效状态,转换消息
return;
}

//在菜单控制下
switch(gNews_Word){
case eNews_KeySpeed: //快捷键
News_Pop();
if(mMenu_Id){
//菜单已经展开,关闭菜单
InMenu_DispNewMenuItem(0);
}
else {
//直接进入快捷键对应的菜单选项
mMenu_ItemId=dSPEEDKEY_MenuItemId;
mMenu_Id=dSPEEDKEY_MenuId;

InMenu_Valid(); //菜单有效
}
break;

case eNews_KeyPushLeft:
News_Pop();
InMeun_MoveItem(eLEFT);
break;

case eNews_KeyPushRight:
News_Pop();
InMeun_MoveItem(eRIGHT);
break;

case eNews_KeyPushReturn: //对当前选中
News_Pop();
InMenu_Valid(); //菜单有效
break;
}
}

/******************************************************************
菜单中的消息滞后处理,处理未被接收和处理的消息。
属于菜单发出的模块消息,未被接收,将是菜单退出,并清除该消息
******************************************************************/
void Menu_NewsLagProcess(void)
{
unsigned char i;
if(gNews_Word==fMenu_RequStore){
//向模块发出的消息未被接受,且菜单在Select状态,退出到上层
fMenu_RequStore=fMenu_Select=0;
InMenu_DispNewMenuItem((*psMenuCurrentUnit).mReturnId); //返回时显示的菜
单项
}
//销毁
i=News_Pop();
while(i){i--;News_Pop();}
}

/******************************************************************
菜单中的消息处理:
模块退出返回的消息
执行当前菜单的返回ID
******************************************************************/
void Menu_NewsProcess(void)
{
unsigned char i;

i=gNews_Word;
News_Pop(); //接受消息

switch(i){
case nMenu_ReturnControl:
fMenu_RequStore=fMenu_Select=0; //选择无效状态
InMenu_DispNewMenuItem((*psMenuCurrentUnit).mReturnId); //返回时
显示的菜单项
break;

case nMenu_OverFlow: //菜单时间到
if(fMenu_Select){
News_PreInsert(eNews_KeySpeed); //快捷
}
else {
fMenu_RequStore=fMenu_Select=0;
InMenu_DispNewMenuItem(0); //菜单回根
}
break;
}
}

/******************************************************************
菜单循环控制,主要显示延时控制
1S进入
******************************************************************/
void Menu_Loop(void)
{
if( (fMenu_Select)||(mMenu_Id) ){

if(++mMenu_TimeLimit>=TIME_MENULIMIT){
//超时,关闭菜单动作
mMenu_TimeLimit=0;
News_Push(nMenu_OverFlow); //菜单时间到
}
}
}

/******************************************************************
菜单初始化
******************************************************************/
void Menu_Init(void)
{
mMenu_TimeLimit=0;
fMenu_RequStore=fMenu_Select=0; //选择无效状态
InMenu_DispNewMenuItem(0); //菜单回根

//预处理消息注册
News_Register(Menu_NewsPreProcess,eNews_beign,eNews_beign);

//滞后处理消息注册
News_Register(Menu_NewsLagProcess,eNews_Lag,eNews_Lag);

//本模块使用的消息处理函数
News_Register(Menu_NewsProcess,nMenu_ReturnControl,nMenu_OverFlow);
}