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

📄 menu.cpp

📁 这是一个基于dos的dbms
💻 CPP
字号:
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <stdlib.h>
#include <myfunc.h>
#include <key.h>
#include <menu.h>
/*Marco Definitions*/
/*///////////////////////////////////////////////*/
PMI FindMI(PSM sm,PMI mi);
PMI FindByKey(PSM sm,word key);
PMI FirstMI(PSM sm);
PMI LastMI(PSM sm);
PSM FirstSM();
PSM LastSM();
PSM FindSM(PSM sm);
void Bar(int x,int y,int len);
void UnBar(int x,int y,int len);
void PrintMI(PSM sm,PMI mi);
void UnselectSM(PSM sm);
void PutName(char *n);
/*///////////////////////////////////////////////*/
/*Gobal Variables*/
void VOID(){}
TMenu Menu={0,NULL,NULL};
int MenuBack=BLACK;
int SMSelBack=BLACK;
int SMSel=WHITE;
int MenuKey=YELLOW;
int SMBox=RED;
int SMBoxBack=WHITE;
int BarBack=BLUE;
int BarNor=BLACK;
int DisableColor=CYAN;
int MAXSM=20;
int MAXMI=100;
/*///////////////////////////////////////////////*/
PMI FindMI(PSM sm,PMI mi){
 PMI t=sm->MIS;
 while(t)
  if(t->ShortKey==mi->ShortKey||t->KeyCode==mi->KeyCode) return t;
  else t=t->Next;
 return t;
}
/*///////////////////////////////////////////////*/
PMI FindByKey(PSM sm,word key){
 PMI t=sm->MIS;
 int n=sm->MIN;
 while(n--)
  if(t->ShortKey==key||t->KeyCode==toupper(key&0x00ff)) return t;
  else t=t->Next;
 return NULL;
}
/*///////////////////////////////////////////////*/
PSM FindSM(PSM sm){
  PSM t=Menu.SMS;
  while(t)
   if(t->ShortKey==sm->ShortKey||t->KeyCode==sm->KeyCode) return t;
   else t=t->Next;
  return NULL;
 }
/*///////////////////////////////////////////////*/
void Bar(int x,int y,int len){
 struct text_info old;
 gettextinfo(&old);
 textbackground(BarBack);
 gotoxy(x,y);
 while(len--) putch(' ');
 textattr(old.attribute);
 }
/*///////////////////////////////////////////////*/
void UnBar(int x,int y,int len){
 gotoxy(x,y);
 while(len--) putch(' ');
 }
/*///////////////////////////////////////////////*/
PMI NewMI(char *n,word sk,word hc,char *hint,void (*act)(),PSM sm){
 PMI t=(PMI)malloc(sizeof(TMI));
 if(t){
   strcpy(t->Name,n);
   t->ShortKey=sk;
   t->HlpCtx=hc;
   t->Hint=hint;
   t->Action=act;
   t->State=ENABLE;
   t->Prev=t->Next=NULL;
   t->SM=sm;
   { char *p=n; while(*p!='&'&&*p) p++; t->KeyCode=*(p+1);}
  }
 return t;
}
/*///////////////////////////////////////////////*/
PSM NewSM(int x,int y,int len,char *n,word sk,word hc){
 PSM t=(PSM)malloc(sizeof(TSM));
 if(t){
   strcpy(t->Name,n);
   t->X=x;t->Y=y;
   t->ShortKey=sk;
   t->HlpCtx=hc;
   t->Len=len;
   t->R.A.X=x-1;
   t->R.A.Y=y+1;
   t->R.B.X=x+len;
   t->R.B.Y=y+2;
   t->MIN=0;
   t->MIS=t->CurMI=NULL;
   t->Prev=t->Next=NULL;
   { char *p=n;while(*p!='&'&&*p) p++; t->KeyCode=*(p+1);}
   }
 return t;
}
/*///////////////////////////////////////////////*/
void AddMI(PSM sm,PMI mi){
 InsMI(sm,1000,mi); /* It won't exceed 1000 MIS :)*/
}
/*///////////////////////////////////////////////*/
void InsMI(PSM sm,byte before,PMI mi){
 PMI t=sm->MIS;
 if(sm->MIN==MAXMI) return;
 if(FindMI(sm,mi)!=NULL) return;
 if(sm->MIS==NULL){
      sm->MIS=sm->CurMI=mi;
      sm->MIN=1;
      sm->R.B.Y++;
      sm->CurMI=mi;
      return;
      }
 while((t->Next!=NULL)&&(before--)) t=t->Next;
 sm->MIN++;
 sm->R.B.Y++;
 mi->Next=t->Next;
 mi->Prev=t;
 if(t->Next) t->Next->Prev=mi;
 t->Next=mi;
}
/*///////////////////////////////////////////////*/
void AddSM(PSM sm){
 InsSM(100,sm);
}
/*///////////////////////////////////////////////*/
void InsSM(int before,PSM sm){
 PSM t=Menu.SMS;
 if(Menu.SMN==MAXSM) return;
 if(FindSM(sm)!=NULL) return;
 Menu.SMN++;
 if(Menu.SMS==NULL){
   Menu.SMS=Menu.CurSM=sm;
   return;
   }
 while(t->Next&&before--) t=t->Next;
 sm->Next=t->Next;
 if(t->Next) t->Next->Prev=sm;
 t->Next=sm;
 sm->Prev=t;
 t=t->Next;
 while(t) {
   t->X+=strlen(sm->Name)+3;
   t->R.A.X+=strlen(sm->Name)+3;
   t->R.B.X+=strlen(sm->Name)+3;
   t=t->Next;
   }
}
word GetKey(){
  while(!bioskey(1));
  return bioskey(0);
  }
/*///////////////////////////////////////////////*/
void DelMI(PSM sm,PMI mi){
 PMI t;
 if((t=FindMI(sm,mi))==NULL) return;
 if(t==sm->CurMI) sm->CurMI=t->Prev;
 sm->MIN--;
 sm->R.B.Y--;
 if(t->Next) t->Next->Prev=t->Prev;
 if(t->Prev) t->Prev->Next=t->Next;
 free(t);
}
/*///////////////////////////////////////////////*/
void DelSM(PSM sm){
 PSM t,p;
 int len;
 if((t=FindSM(sm))==NULL) return;
 if(t==Menu.CurSM) Menu.CurSM=t->Prev;
 Menu.SMN--;
 len=strlen(t->Name)+3;
 p=t->Next;
 free(t);
 while(p){
  p->R.A.X-=len;
  p->R.B.X-=len;
  p=p->Next;
  }
}
/*///////////////////////////////////////////////*/
PMI FirstMI(PSM sm){ return sm->MIS;}
/*///////////////////////////////////////////////*/
PMI LastMI(PSM sm){
 PMI t=sm->MIS;
 while(t->Next) t=t->Next;
 return t;
 }
/*///////////////////////////////////////////////*/
PSM FirstSM(){ return Menu.SMS;}
/*///////////////////////////////////////////////*/
PSM LastSM(){
 PSM T=Menu.SMS;
 while(T->Next) T=T->Next;
 return T;
 }
/*///////////////////////////////////////////////*/
void EnableMI(PMI mi){
 mi->State=ENABLE;
}
/*///////////////////////////////////////////////*/
void EnableSM(PSM sm){
 sm->State=DISABLE;
}
/*///////////////////////////////////////////////*/
void DisableSM(PSM sm){
 sm->State=DISABLE;
}
/*///////////////////////////////////////////////*/
void DisableMI(PMI mi){
 mi->State=ENABLE;
}
/*///////////////////////////////////////////////*/
void SelectSM(PSM sm){
 int i,Cur;
 PMI t;
 word Key;
 struct text_info old;
 gettextinfo(&old);
 HideCursor();
 if(sm==NULL) goto ret;
 sm->Buffer=(char*)malloc((sm->R.B.X-sm->R.A.X)*(sm->R.B.Y-sm->R.A.Y)*2);
 if(sm->Buffer==NULL) return;
 gettext(sm->R.A.X,sm->R.A.Y,sm->R.B.X,sm->R.B.Y,sm->Buffer);
 textbackground(MenuBack); textcolor(SMSel);
 gotoxy(sm->X,sm->Y);
 PutName(sm->Name);
 textcolor(SMBox);  textbackground(SMBoxBack);
 Rectangle(sm->R.A.X,sm->R.A.Y,sm->R.B.X,sm->R.B.Y);
 window(sm->R.A.X+1,sm->R.A.Y+1,sm->R.B.X-1,sm->R.B.Y-1);
 textbackground(BLACK);
 textcolor(YELLOW);
 clrscr(); /*Is here OK!:)*/
 window(1,1,80,25);
 for(t=sm->MIS,i=1;i<=sm->MIN;t=t->Next,i++){
  gotoxy(sm->R.A.X+1,sm->R.A.Y+i);
  if(t==sm->CurMI) Cur=sm->R.A.Y+i;
  PrintMI(sm,t);
  }
 Bar(sm->R.A.X+1,Cur,sm->Len);
 textbackground(BarBack);
 gotoxy(sm->R.A.X+1,Cur);
 PutName(sm->CurMI->Name);
 textbackground(BLACK);
 if(sm->CurMI->Hint!=NULL) Hint(sm->CurMI->Hint);
 textbackground(BLACK);
 while(1){
  if(sm->CurMI->Name[0]=='\\')
   Hint("                                                                             ");
  Key=GetKey();
  if(Key==kbEsc) { UnselectSM(sm);goto ret;}
  switch(Key){
   case kbUp: UnBar(sm->R.A.X+1,Cur,sm->Len);
	      gotoxy(sm->R.A.X+1,Cur);
	      PrintMI(sm,sm->CurMI);
	   ag:   Cur=Cur==sm->R.A.Y+1?sm->MIN+sm->R.A.Y:Cur-1;
	      sm->CurMI=sm->CurMI->Prev!=NULL?sm->CurMI->Prev:LastMI(sm);
	      gotoxy(sm->R.A.X+1,Cur);
	      if(sm->CurMI->Name[0]=='\\') goto ag;
	      Bar(sm->R.A.X+1,Cur,sm->Len);
	      gotoxy(sm->R.A.X+1,Cur);
	      textbackground(BarBack);
	      PrintMI(sm,sm->CurMI);
	      textbackground(BLACK);
	      if(sm->CurMI->Name[0]!='\\') Hint(sm->CurMI->Hint);
	      break;
  case kbDown: UnBar(sm->R.A.X+1,Cur,sm->Len);
	       gotoxy(sm->R.A.X+1,Cur);
	       PrintMI(sm,sm->CurMI);
	       textbackground(BLACK);
	    ag1: Cur=Cur==sm->MIN+sm->R.A.Y? sm->R.A.Y+1:Cur+1;
	       sm->CurMI=sm->CurMI->Next!=NULL? sm->CurMI->Next:FirstMI(sm);
	       gotoxy(sm->R.A.X+1,Cur);
	       if(sm->CurMI->Name[0]=='\\') goto ag1;
	       Bar(sm->R.A.X+1,Cur,sm->Len);
	       gotoxy(sm->R.A.X+1,Cur);
	       textbackground(BarBack);
	       PrintMI(sm,sm->CurMI);
	       textbackground(BLACK);
	       if(sm->CurMI->Name[0]!='\\') Hint(sm->CurMI->Hint);
	       break;
  case kbEnter:
		Hint("                                                                             ");
		if(sm->CurMI->Name[0]=='\\') break;
		if(sm->CurMI->Name[0]=='\\') break;
		if(sm->CurMI->SM!=NULL) SelectSM(sm->CurMI->SM);
		else {
		 UnselectSM(sm);(*sm->CurMI->Action)();
		 }
		 goto ret;
  case kbLeft: if(sm->CurMI->Name[0]=='\\') break;
	       Hint("                                                                             ");
	       UnselectSM(sm);
	       Menu.CurSM=Menu.CurSM->Prev==NULL?LastSM():Menu.CurSM->Prev;
	       SelectSM(Menu.CurSM);goto ret;
  case kbRight:
	       Hint("                                                                             ");
	       if(sm->CurMI->Name[0]=='\\') break;
		UnselectSM(sm);
	       Menu.CurSM=Menu.CurSM->Next==NULL?FirstSM():Menu.CurSM->Next;
	       SelectSM(Menu.CurSM);goto ret;
     default: t=FindByKey(sm,Key);
	     if(t!=NULL){
		UnselectSM(sm);
		(t->Action)();
		goto ret;
		}
   }
  }
 ret:
  ShowCursor();
  RESTORE
}
/*///////////////////////////////////////////////*/
void PrintMI(PSM sm,PMI mi){
 int num=sm->Len;
 struct text_info old;
 gettextinfo(&old);
 if(mi->State==DISABLE) textcolor(DisableColor);
 if(mi->Name[0]=='\\') while(num--) putch(196);
 else PutName(mi->Name);
 if(mi->State==DISABLE) textattr(old.attribute);
}
/*///////////////////////////////////////////////*/
void UnselectSM(PSM sm){
 if(sm==NULL||sm->Buffer==NULL) return;
 gotoxy(sm->X,sm->Y);
 PutName(sm->Name);
 puttext(sm->R.A.X,sm->R.A.Y,sm->R.B.X,sm->R.B.Y,sm->Buffer);
}
/*///////////////////////////////////////////////*/
void PutName(char *n){
 struct text_info old;
 gettextinfo(&old);
 while(*n)
  if(*n=='&'){
    textcolor(RED);
    putch(*(n+1));
    n+=2;
    textattr(old.attribute);
    }
 else  putch(*n++);
}
/*///////////////////////////////////////////////*/
void MenuDraw(){
 PSM p=Menu.SMS;
 while(p){
  gotoxy(p->X,p->Y);
  PutName(p->Name);
  p=p->Next;
  }
}
PSM HaveShortKey(word key){
 PSM t=Menu.SMS;
 while(t)
  if(t->ShortKey==key) return t;
  else t=t->Next;
 return NULL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -