文本模式下菜单的实现
┌ | 218 | ┐ | 191 |
─ | 196 | │ | 179 |
└ | 192 | ┘ | 217 |
定义常量:
int leftUa=218; | //左上角 |
int righUa=191; | //右上角 |
int leftDa=192; | //左下角 |
int righDa=217; | //右下角 |
int lineHc=196; | //横线 |
int lineVc=179; | //竖线 |
画菜单没点颜色也显得单调,于是定义颜色
int MENUBACKCOLOR=7;//灰色
int MENUTEXTCOLOR=0;//黑色
菜单项的间距应该固定,所以有
int MENULEFTEDGE=7;
int MENUDISTANCE=13;
行了,可以先画个主菜单了
void drawMain()
{
gotoxy(1,1);//设定起始点坐标
textbackground(MENUBACKCOLOR);//背景色设成菜单用背景色
textcolor(MENUTEXTCOLOR);//前景色设成菜单用前景色
insline();//将第一行用背景色填充
cprintf("%c%c%c",lineVc,4,lineVc);//输出一个装饰性图案当图标
gotoxy(MENULEFTEDGE,1);
cprintf("%c ML %c",17,16);//菜单项1
gotoxy(MENULEFTEDGE+MENUDISTANCE,1);
cprintf("%c AS %c",17,16);//菜单项2
gotoxy(MENULEFTEDGE+MENUDISTANCE*2,1);
cprintf("%c HL %c",17,16);//菜单项3
gotoxy(74,1);
cprintf(" EXIT ");//“退出”
textbackground(WINDOWBACKCOLOR);
textcolor(WINDOWTEXTCOLOR);//恢复颜色设置
}
上面的代码里面有几条要注意:
1)输出字符的位置并不是确定的,可以酌情调试更改,总之要得到自己满意的效果就多调试
2)开始画菜单之前要更改颜色,画完后一定要把颜色恢复回来,否则有时会出现很奇怪的现象
3)文本模式的屏幕被分成80*25格,每格放一个字符,坐标是从(1,1)开始到(80,25)
有了第一个函数,画出了基本的菜单,现在该考虑画菜单的选择了。其实选择也就是更改背景色和前景色之后,在原字符的位置重新输出该字符就行了。其中mainIndex是菜单项的索引,用来表示选择了哪个菜单项时使用的。
void drawMainSel(int mainIndex)
{
char* mainText;
int i=8;
if(mainIndex==3)//到了“EXIT”了,特殊处理
{
gotoxy(74,1);
textbackground(SELBACKCOLOR);
for(i=0;i<=5;i++)
cprintf(" ");
textcolor(SELTEXTCOLOR);
gotoxy(75,1);
cprintf("EXIT");
textbackground(WINDOWBACKCOLOR);
textcolor(WINDOWTEXTCOLOR);
return;
}
gotoxy(MENULEFTEDGE+MENUDISTANCE*mainIndex,1);//到菜单项所在的坐标
textbackground(SELBACKCOLOR);//设置颜色为“选择”
for(i=0;i<=7;i++)
cprintf(" ");//清除原来的字符
textcolor(SELARROWCOLOR);
gotoxy(MENULEFTEDGE+MENUDISTANCE*mainIndex,1);
cprintf("%c %c",4,4);
textcolor(SELTEXTCOLOR);
gotoxy(10+MENUDISTANCE*mainIndex,1);
switch(mainIndex)
{
case 0:
mainText="ML";
break;
case 1:
mainText="AS";
break;
case 2:
mainText="HL";
break;
}
cprintf("%s",mainText);//为什么这么画呢?实话说:为了好看+偷懒
textbackground(WINDOWBACKCOLOR);
textcolor(WINDOWTEXTCOLOR);
}
选择项移动了怎么办呢?需要一个UnSel函数,将字符再画回去(当然重画主菜单也可以,就是耗时耗资源),然后将菜单项的索引值改变,再调用Sel函数。回头一看,发现我用的也是偷懒的法子,重画了主菜单。但是这方法只对主菜单可以用,子菜单会有很明显的闪烁。
上面的代码画个菜单项不多的主菜单已经足够了,可是不够完美。需要个子菜单的画法。我想下拉式的子菜单不过是一个方框,里面输出字符而已,那么一个画方框的函数就是第一需要了:
void drawDrop(int rowSize,int Rows,int cellX,int cellY)
{
int i=1;
int j=1;
textbackground(MENUBACKCOLOR);
textcolor(MENUTEXTCOLOR);
gotoxy(cellX,cellY);
cprintf("%c",leftUa);//画左上角
for(j=1;j<=rowSize;j++)
cprintf("%c",lineHc);//一行多宽,就画多长的横线
cprintf("%c",righUa);//画右上角
for(i=1;i<=Rows;i++)
{
cellY++;
gotoxy(cellX,cellY);
cprintf("%c",lineVc);
for(j=1;j<=rowSize;j++)
cprintf(" ");
cprintf("%c",lineVc);
}//画上下边框之间的部分
cellY++;
gotoxy(cellX,cellY);
cprintf("%c",leftDa);
for(i=1;i<=rowSize;i++)
cprintf("%c",lineHc);
cprintf("%c",righDa);//画下边框
textbackground(WINDOWBACKCOLOR);
textcolor(WINDOWTEXTCOLOR);
}
有了方框就可以算坐标,然后向里面写字符了,只是正像前面所说的,子菜单不能没有一个UnSel函数。可以自己酌情编写。
画菜单的函数都写的差不多了,只缺一个调用这些函数,并且判别菜单选择的函数,这里首先要有一个死循环,用于接收消息;然后是判断键盘输入,都按下了那些键,按着键值来判断该执行什么功能,当按下回车时尤其重要,这时就要根据菜单索引值来执行程序的功能了,那当然程序不是只画个菜单就能了事的,只有菜单没内容,课设是过不去的。废话少说看下面:
int i=0;//接受输入的键值用
int j=0;//主菜单索引
int k=0;//子菜单索引
clrscr();
drawMain();
drawClear();
drawMainSel(j);//菜单初始化
while(1)
{
i=bioskey(0);//等待键盘输入
switch(i)
{
case 19712://用户按下“左箭头”
j++;
if(j==4) j=0;
drawMain();
drawClear();
drawMainSel(j);
if(MENUSHOWN==TRUE)
{
k=0;
drawSub(j);
drawSubSel(j,k);
}
break;
...
...
...
MENUSHOWN是一个变量,它标志着子菜单的状态是已经展开还是收着不动,不过没什么大用,纯是好看。上面的函数只是一小部分,本身函数太长,贴不下...
我自己的菜单里还有其他一些华而不实的东西,而且就是为了课设而专门作的,所以内容和形式很杂乱,设计思想我觉得差不多就是这些了,重要的还是这些思想嘛。好了,话说得差不多了,想要源代码的话请点击此处或去Turbo C版的下载仓库下载。