首页 > 编程 > Java > 正文

文本模式下菜单的实现

2019-09-06 23:33:31
字体:
来源:转载
供稿:网友

                      

作者:KKnD

   

  近几天翻出了上学期写的计算机原理的课设程序,里面的菜单是用TC2.0写的,虽然很简陋,可扩充性几乎没有,但基本的功能还是都有的。回想起大一的时候想写个菜单抓耳挠腮的窘像,心想对要写课设需要菜单的同学们还是有一定帮助的。于是,设计思想和源代码我就公开了。望各位高手不要取笑。

   

  一般用TC写菜单需要包含conio.h,它提供了gotoxy()textbackground()等一系列有用的函数,至于判断键盘输入我喜欢使用bios.h里面的bioskey()函数,它可以精确判断用户究竟按下的是什么键。

   

#include <conio.h>
   #include <bios.h>

   
     菜单边框就是由几个基本的字符组成的,这下字符通常被人称为“制表符”,这些字符无法直接由键盘输入,而是由按住alt键,在数字小键盘上输入字符对应的ascii码,再松开alt键,就会出现选定的字符。

   

下表是常用的制表符和对应的ascii码:

   
                                                                                                                                       
       

         ┌

       
       

         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版的下载仓库下载。  

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选