📄 menu.c
字号:
/*****************************************************
功能:下拉式菜单程序,菜单项可在数组main[]及sub[][]中配置
作者:谷维强
时间:2000.11.1 于桂林
******************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <string.h>
#include <signal.h>
#include <sys/stat.h>
main()
{
int i; //主菜单的第 i 项
int j; //子菜单的第 j 项
int sub_on=0; //开关:判断子菜单当前是否显示, 1--显示,0--不显示
int call_flag; //开关:是否刚调用过子程序
int x0,y0; //主菜单项显示的起始座标
int max_x=0; //主菜单最后一项开始显示的 x 座标
int max_i; //主菜单项最大的数组下标
char ch; //从键盘接收的控制子符
int tmp_x;
int x,y,max_len;
void clear_sub(int y,int x,char * a[]);
void sub_draw_box(int,int,int,int);
void show_sub(int,int,char * a[],int j);
void HShowItem(int y,int x,char * a[],int j);
void ShowItem(int y,int x,char * a[],int j);
void show_main(int y,int x,char *main[],int i);
void show_head(char *);
//主菜单项
//最后一项用 NULL 结束
char * main[]={
"银证转帐业务处理",
"银证通业务处理",
"银证通帐务查询",
"其 它",
NULL
};
//各子菜单项
//子菜单项置于{ }中,用 NULL 结束
//若主菜单项无对应子菜单,相应子菜单项用 {NULL} 填
char * sub[15][15]={
{
"本地流水查询 ",
"取银行后台流水 ",
"银行后台流水查打",
"银行后台流水查打(新)",
"'T+1'帐务解冻 ",
NULL},
{"接收清算信息",
"解冻冻结资金",
"处理清算信息",
NULL},
{"查询清算信息 ",
"查询冻结余额 ",
"查询冻结、撤单废单流水",
NULL},
{
"建'单位编号-94帐号'对照",
"删'单位编号-94帐号'对照",
"查'单位编号-94帐号'对照",
"帮 助 ",
"查看日志 ",
"退 出 ",
NULL}
};
char DIR[80];
memset(DIR,0,80);
sprintf(DIR,"%s",getenv("HOME"));
strcat(DIR,"/bin");
chdir(DIR);
initscr();
refresh();
show_head("★★广西农行银证帐务中心处理系统 (Ver 2.0)★★");
//显示主菜单,并加亮第一项
y0=2;x0=2;
y=y0;x=x0;
tmp_x=x;
draw_box(y-1,0,y+1,78);
for(i=0;main[i]!=NULL;i++){
mvprintw(y,tmp_x,"%s ",main[i]);
tmp_x=tmp_x+strlen(main[i])+2;
}
max_i=i-1;
max_x=tmp_x-strlen(main[max_i])-2;
xxts("");
standout();
mvprintw(y,x,"%s",main[0]);
standend();
refresh();
//被加亮的菜单项随着键的 -->,<-- 的按下移动,
//敲回车键运行子程序
i=0;j=0; //第 i 个子菜单的第 j 项
call_flag=0;
for(;;){
if(call_flag==1){ //重画被子程序破坏掉的菜单
my_clear(4,0,20,79);//清用户区屏幕
xxts("");
show_main(y0,x0,main,i);
show_sub(y+1,x-1,sub[i],j);
call_flag=0;
}
noecho();
ch=getch();
if(ch==27)ch=getch();
echo();
switch(ch){
case '6': // --> 键
case 67:
j=0;
mvprintw(y,x,"%s",main[i]);
clear_sub(y+2,x-1,sub[i]);
x=x+strlen(main[i])+2;
i++;
if(x>max_x){
x=2;
i=0;
}
standout();
mvprintw(y,x,"%s",main[i]);
standend();
if((sub[i][0]!=NULL) && (sub_on==1)) //有子菜单
show_sub(y+1,x-1,sub[i],0);
break;
case '4': // <-- 键
case 68:
j=0;
mvprintw(y,x,"%s",main[i]);
clear_sub(y+2,x-1,sub[i]);
i--;
x=x-strlen(main[i])-2;
if(x<2){
x=max_x;
i=max_i;
}
standout();
mvprintw(y,x,"%s",main[i]);
standend();
if((sub[i][0]!=NULL) && (sub_on==1)) //有子菜单
show_sub(y+1,x-1,sub[i],0);
break;
case '8':
case 65: //往上键
if(sub_on==0){ //子菜单尚未显示
j=0;
sub_on=1;
if(sub[i][0]!=NULL)
show_sub(y+1,x-1,sub[i],0);
break;
}
if(sub[i][0]==NULL) //无子菜单
break;
ShowItem(y+j+2,x+1,sub[i],j);
j--;
if(j<0){
j=0;
while(sub[i][j]!=NULL)
j++;
j=j-1;
}
HShowItem(y+j+2,x+1,sub[i],j);
break;
case '2':
case 66: //往下键
if(sub_on==0){ //子菜单尚未显示
j=0;
sub_on=1;
if(sub[i][0]!=NULL)
show_sub(y+1,x-1,sub[i],0);
break;
}
if(sub[i][0]==NULL) //无子菜单
break;
ShowItem(y+j+2,x+1,sub[i],j);
if(sub[i][j+1]!=NULL)
j++;
else
j=0;
HShowItem(y+j+2,x+1,sub[i],j);
break;
case '0': //0键,清理子菜单
case 27: //ESC键
if(sub_on==0)
break;
clear_sub(y+2,x-1,sub[i]);
sub_on=0;
standout();
mvprintw(y,x,"%s",main[i]);
standend();
break;
case 10: //回车键,据 i,j 不同的值调用不同的子程序
if(sub_on==0){//子菜单尚未显示,显示子菜单,否则调用子程序
j=0;
sub_on=1;
if(sub[i][0]!=NULL)
show_sub(y+1,x-1,sub[i],0);
break;
}
my_clear(4,0,20,79); //清用户区屏幕
call_flag=1; //打开调用子程序的开关
/****************** 在此处插入子程序调用***************/
if((i==0) && (j==0))
;
if((i==0) && (j==1))
;
if((i==0) && (j==2))
;
if((i==0) && (j==3))
;
if((i==0) && (j==4))
;
if((i==1) && (j==0))
;
if((i==1) && (j==1))
;
if((i==1) && (j==2))
;
if((i==2) && (j==0))
;
if((i==2) && (j==1))
;
if((i==2) && (j==2))
;
if((i==3) && (j==0))
;
if((i==3) && (j==1))
;
if((i==3) && (j==2))
;
if((i==3) && (j==3))
;
if((i==3) && (j==4))
;
if((i==3) && (j==5))
goto end;
/*****************************************************/
break;
} //end of switch()
} //end of for()
end :
xxts("");
endwin();
} //end of main()
//子函数:把 show_sub 显示的子菜单清掉
void clear_sub(int y,int x,char * a[])
{
int i=0,j=0,max_len=0;
char buff[80];
for(i=0;a[i]!=NULL;i++){
if(strlen(a[i])>max_len)
max_len=strlen(a[i]);
}
if(x+max_len>76)
x=76-max_len;
memset(buff,' ',max_len+4);
buff[max_len+4]='\0';
for(j=0;j<i+1;j++)
mvprintw(y+j,x,"%s",buff);
refresh();
}
//子函数:画子菜单的匡
void sub_draw_box(int y1,int x1,int y2,int x2)
{
int i;
mvprintw(y2,x1,"%s","┗");
mvprintw(y2,x2,"%s","┛");
for(i=x1+2;i<x2;i=i+2){
mvprintw(y2,i,"%s","━");
}
for(i=y1+1;i<y2;i++){
mvprintw(i,x1,"%s","┃");
mvprintw(i,x2,"%s","┃");
refresh();
}
}
//子函数: 显示子菜单,并加亮第j项
void show_sub(int y,int x,char * a[],int j)
{
int i=0,max_len=0;
if(a[0]==NULL)
return;
for(i=0;a[i]!=NULL;i++){
//mvprintw(y+1+i,x+2,"%s",a[i]);
if(strlen(a[i])>max_len)
max_len=strlen(a[i]);
}
if(x+max_len>76)
x=76-max_len;
for(i=0;a[i]!=NULL;i++)
mvprintw(y+1+i,x+2,"%s",a[i]);
sub_draw_box(y,x,y+i+1,x+max_len+2);
standout();
mvprintw(y+1+j,x+2,"%s",a[j]);
standend();
refresh();
}
//反显子菜单项 j
void HShowItem(int y,int x,char * a[],int j)
{
int i=0,max_len=0;
if(a[0]==NULL)
return;
for(i=0;a[i]!=NULL;i++){
if(strlen(a[i])>max_len)
max_len=strlen(a[i]);
}
if(x+max_len>76)
x=78-max_len;
standout();
mvprintw(y,x,"%s",a[j]);
standend();
}
//显示子菜单项 j
void ShowItem(int y,int x,char * a[],int j)
{
int i=0,max_len=0;
if(a[0]==NULL)
return;
for(i=0;a[i]!=NULL;i++){
if(strlen(a[i])>max_len)
max_len=strlen(a[i]);
}
if(x+max_len>76)
x=78-max_len;
mvprintw(y,x,"%s",a[j]);
}
//子函数:在(y,x)处显示主菜单,并加亮第 i 项
void show_main(int y,int x,char *main[],int i)
{
int j,x_i,tmp_x;
tmp_x=x;
draw_box(y-1,0,y+1,78);
for(j=0;main[j]!=NULL;j++){
if(j==i)
x_i=tmp_x; //记下第 i 项菜单的x座标
mvprintw(y,tmp_x,"%s ",main[j]);
tmp_x=tmp_x+strlen(main[j])+2;
}
standout();
mvprintw(y,x_i,"%s",main[i]);
standend();
refresh();
}
void show_head(char *buff)
{
mvprintw(0,40-strlen(buff)/2,"%s",buff);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -