⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menu.c

📁 通用的菜单界面程序
💻 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 + -