1.4高级应用——菜单实现
1.4.1 一个弹出式菜单
这个程序(例程 3-7)是一个文本方式下的菜单程序,它生成一个弹出式菜单,如图 3-3
所示。程序运行时,首先弹出一个带洋红色框的蓝底菜单,并有一红色光条压在第一项上,
当按 E键时,程序回到系统,压 Down键时,光条移到第二项,压 A时,则列出当前日录
下的各文件目录,再压任意键后则又弹出菜单,当压 B键时,则列出目录,当屏满后,暂
停,按键后,又继续列出,它实际上就是执行 dir /p命令,当按回车键后,又出现菜单,当
按 C键后,便执行 dir /w的 dos命令,以宽行格式列出目录,按回车键后又回到菜单用 UP
键可使光条上移。
图 3-3 弹出式菜单
程序开始时,首先用 do循环反复运行下面的程序,直到按 E键后为止,window(7,8,
19,15)定义了一个用洋红色填充的窗口,接着又定义一个蓝色窗口,它套在洋红色窗口内,
因而形成一个带洋红色粗边框的蓝色窗口,在窗口内写上各菜单项,接着又调用光条上移函
数 upbar(y—1),使红色光条压在第一菜单项上,下面的 do循环则用来构成一个反复检查按
键,并转去执行相应的功能操作,do循环内的第一个 switch(ky)语句用来判断按的是何键,
按键值赋给 y的相应值,并使 ky=key_enter,以结束 do循环,跟着第二个 switch(y)语句则
按 y值转去执行相应的菜单项功能。只有当菜单项功能键是 E时,才使得外层的 do循环结
束而回到系统。
upbar(int y)函数是产生一个上移光条(用 gettext()函数),实际上它第一次被调用时,则用
gettext(i,y,i,y,&t)连续 8次将菜单项 8个字符长的区域 (蓝底无字)存入&t中,用蓝底白
字又放回(用 puttext()函数),而第 2个 gettext()函数则将下移一行的 8个字符长区域(即第一
个菜单项,存入 t中,又以白字红底方式放回原处,即产生一个红色光条压在第一菜单项上。
以后的调用(当按 UP键时)则随 y值不同,而红色光条压在不同菜单项上。
downbar()函数产生下移光条,当按 Down键时,便调用该函数将红底白字的光条压在下
一条菜单项上。
在 Turbo C的 stdlib.h中提供了一个能够执行 DOS命令的函数 system (),其原型为:
int system(char *command);
参数 command所指向的字符串正是 DOS的命令。在这个程序中我们通过调用 system("dir"),
system("dir/p"),system("dir/w")使程序根据菜单选项 A,B,C来分别先执行 DOS命令 dir
(列出当前日录下的各文件目录),dir/p(列出目录,当屏满后,暂停,按键后,又继续列
出),dir/w(以宽行格式列出目录)后再返回程序。
/*例程
3-7*/
#include <process.h>
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
#include <conio.h>
/* define Key Values /* 定义各键的
bioskey(0)的按键返回值 */
#define Key_DOWN 0x5100
#define Key_UP 0x4900
#define Key_A 0x1e41
#define Key_a 0x1e61
#define Key_B 0x3042
#define Key_b 0x3062
#define Key_C 0x2e43
#define Key_c 0x2e63
#define Key_E 0x1245
#define Key_e 0x1265
#define Key_ENTER 0x1c0d
main()
{
int ky,y;
char ch;
textbackground(0);
clrscr();
do
{
textmode(C80);
textbackground(13);
textcolor(RED);
window(7,8,19,15); /* 开一个窗口 */
clrscr();
textbackground(1);
textcolor(RED);
window(8,9,18,14); /* 再开一个当前窗口,套在上一个窗口之中*/
clrscr();
gotoxy(3,3);
cprintf("E:exit/r/n"); /* 窗口中写上红色的菜单项 */
gotoxy(3,4);
cprintf("A:dir/r/n");
gotoxy(3,5);
cprintf("B:dir/p/r/n");
gotoxy(3,6);
cprintf("C:dir/w/r/n");
y=10;
upbar(y-1); /* 调用光条上移函数 */
do
{
ky=bioskey(0); /*得到按键的键值 */
switch(ky)
{
case Key_A: case Key_a:/* A and a key */
{
y=12;
ky=Key_ENTER;
break;
}
case Key_B:case Key_b:/* B and b key */
{
y=13;
ky=Key_ENTER;
break;
}
case Key_C: case Key_c:/* C and c key */
{
y=14;
ky=Key_ENTER;
break;
}
case Key_E:case Key_e:/* E and e key */
{
y=11;
ky=Key_ENTER;
break;
}
case Key_DOWN:/* Cursor down key */
{
if ( y<13 )
{
upbar(y);
y++;
}
break;
}
case Key_UP: /* Cursor up key */
{
if(y>10)
{
downbar(y);
y--;
}
break;
}
}
} while (ky !=Key_ENTER ); /* Enter key */
textcolor(WHITE);
switch(y)
{
case 11:
{
ch='%'; /*返回系统 */
break;
}
case 12:
{
system("dir");
getch(); /*列目录后等待按键 */
break;
}
case 13:
{
system("dir /p");
getch(); /*列目录屏满后暂停,按任意键继续 */
break;
}
case 14:
{
system("dir /w");
getch(); /*用宽行格式列目录 */
break;
}
}
if(ch=='%')
break;
} while(1);
clrscr(); /* 清屏 */
}
/* read bar down */
upbar(int y) /* 光条上移函数 */
{
int i;
typedef struct texel_struct {
unsigned char ch;
unsigned char attr;
} texel;
texel t;
for(i=9;i<=17; i++)
{
gettext(i,y,i,y,&t);
t.attr=0x1f; /* 字符为白色,背景为蓝色 */
puttext(i,y,i,y,&t);
gettext(i,y+1,i,y+1,&t);
t.attr=0x4f; /* 字符为白色,背景为红色 */
puttext(i,y+1,i,y+1,&t);
}
gotoxy(3,y+1);
return;
}
/* red bar up */ /* 光条下移函数 */
downbar(int y)
{
int i;
typedef struct texel_struct {
unsigned char ch;
unsigned char attr;
} texel;
texel t;
for(i=9;i<=17;i++)
{
gettext(i,y,i,y,&t);
t.attr=0x1f; /* 字符为白色,背景为蓝色 */
puttext(i,y,i,y,&t);
gettext(i,y-1,i,y-1,&t);
t.attr=0x4f ; /* 字符为白色,背景为红色 */
puttext(i,y-1,i,y-1,&t);
}
gotoxy(3,y-1);
return;
}