📄 menute.cpp
字号:
/* name menute.cpp
pop-up menu routines for text mode operation that use dos video service.
int menu(char *menu[],int x,int y)
the menu must end with '&' and you can use some character for some functions
"&-<cnn
01234567890
&:end -:push any key <:can use left and right key
cnn:nn is the high color
*/
#include "iostream.h"
#include"stdlib.h"
#include"string.h"
#include "readkey.cpp"
#include "locate.cpp"
#define LT (char)218
#define TD (char)194
#define RT (char)191
#define LR (char)195
#define CC (char)197
#define RL (char)180
#define LD (char)192
#define DT (char)193
#define RD (char)217
#define SH (char)179
#define HE (char)196
#define esc 27
#define highlight 0x70
#define norm_vid 7
void save_video(int startx,int starty,int endx,int endy,unsigned int *buf_ptr);
void restore_video(int startx,int stary,int endx,int endy,unsigned int *buf_ptr);
void write_video(int x,int y,char *p,int attrib);
void display_menu(char *menu[],int x,int y,int count);
void draw_border(int startx,int starty,int endx,int endy);
int get_resp(int x,int y,int count0,int count,char *menu[],int len,int color);
int readscream(int ,int);
int read(int x,int y,int len,int color);
/*Display a pop-up menu and return selection.
This function returns -2 if menu can't be constructed;
it return -1 if use hits escape key;
ortherwise the item number is returned starting with 0
as then first (topmost)entry.*/
class WINDOW
{
private:
unsigned int *_p;
int _x,_y,_endx,_endy;
void destroy();
public:
WINDOW();
~WINDOW();
int set(int,int,int,int);
};
WINDOW::WINDOW()
{
_p=0;
}
WINDOW::~WINDOW(){destroy();}
void WINDOW::destroy()
{
restore_video(_x,_y,_endx,_endy,_p);
delete []_p;
_p=0;
}
int WINDOW::set(int x,int y,int endx,int endy)
{
if(x<1||y<1)return-2;
if(endy>23||endx>75)return -2;
/*allocate enough memory to hold the current contents of screen*/
x--;y--;
_p=new unsigned int[(endx-x+1)*(endy-y+1)];
if(!_p)return-1; //return for not enough memery
/*save what is currently onthe screen*/
save_video(x,y,endx,endy,_p);
draw_border(x,y,endx,endy);
_x=x;
_y=y;
_endx=endx;
_endy=endy;
return 0;
}
int menu(char *menu[],int x,int y)
{
WINDOW window;
int i,len,color=-1;
int endx,endy,count,count0=0;
if(y>23||y<1||x>74||x<1)
{
cout<<"range errop";
return -2;
}
/*make sure that the menu will fit*/
for(i=0,len=0;;i++)
{
if(menu[i][0]=='-')count0=i+1;
if(menu[i][0]=='&')break;
if(strlen(menu[i])>len)len=strlen(menu[i]);
}
count=i;
if(menu[i][3]>='c')color=(menu[i][4]-'0')*10+menu[i][5]-'0';
if(color<0)color=highlight;
endx=x+len;
endy=y+count;
window.set(x,y,endx+1,endy);
/*display the menu*/
display_menu(menu,x,y,count);
return get_resp(x,y+count0,count0,count,menu,len,color);
}
/*
void main()
{
char *p[]={ "qwerwegqgqwrt",
"--------------",
"qregqegrqer",
"rgqerqqrgqwerq","& < "};
int i;
for(i=0;i<=25;i++)
cout<<"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"<<endl;
for(i=168;i<230;i++)cout<<(char)i<<" "<<i<<";";
menu(p,12,2);
}
*/
/*display the menu in its priper location.*/
void display_menu(char *menu[],int x,int y,int count)
{
int i;
for(i=0;i<count;i++,y++)
{
locate(x,y);
cout<<menu[i];
}
}
/*draw borde*/
void draw_border(int startx,int starty,int endx,int endy)
{
register int i;
/*draw line*/
for(i=starty;i<endy;i++)
{
locate(startx,i);
cout<<SH;
locate(endx,i);
cout<<SH;
}
/*draw h-line*/
for(i=startx;i<endx;i++)
{
locate(i,starty);
cout<<HE;
locate(i,endy);
cout<<HE;
}
/*draw corners*/
locate(startx,starty);cout<<LT;
locate(startx,endy);cout<<LD;
locate(endx,starty);cout<<RT;
locate(endx,endy);cout<<RD;
}
/*input*/
int get_resp(int x,int y,int count0,int count,char *menu[],int len,int color)
{
union inkey{char ch[2];int i;}c;
int arrow_choice=0;
if(menu[count][1]=='-'){locate(0,0);c.i=readkey(0);return c.ch[1];}
/*higlight the first selection*/
for(;;)
{
c.i=read(x,y+arrow_choice,len,color);
/*reset the selection to normal video*/
if(c.ch[0])
{
/*check enter or space bar*/
switch(c.ch[0])
{
case '\r':return arrow_choice;
case ' ':arrow_choice++;
break;
case esc:return -1;
}
}
else{/*is special key*/
switch(c.ch[1])
{
case 72:arrow_choice--;break;
case 80:arrow_choice++;break;
}
if(menu[count][2]=='<')
if(c.ch[1]==75||c.ch[1]==77)return c.ch[1];
};
if(arrow_choice==(count-count0))arrow_choice=0;
if(arrow_choice<0)arrow_choice=count-count0-1;
}
}
/*display a string with specified attribute*/
void write_video(int x,int y,char *p,int attrib)
{
union REGS r;
int i;
for(i=x;*p;i++)
{
locate(i,y);
r.h.ah=9;
r.h.bh=0;
r.x.cx=1;
r.h.al=*p++;
r.h.bl=attrib;
int86(0x10,&r,&r);
}
}
/*save screem*/
unsigned int *saveline(int startx,int y,int endx,unsigned int* buf_ptr)
{
union REGS r;
int i;
for(i=startx;i<=endx;i++)
{
locate(i,y);
r.h.ah=8;
r.h.bh=0;
*buf_ptr++=int86(0x10,&r,&r);
cout<<' ';
}
return buf_ptr;
}
void save_video(int startx,int starty,int endx,int endy,unsigned int *buf_ptr)
{
int i,j;
for(i=starty;i<=endy;i++)
buf_ptr=saveline(startx,i,endx,buf_ptr);
}
/*restore screem*/
unsigned int* restoreline(int startx,int y,int endx,
unsigned int* buf,int attrib=-1)
{
union REGS r;
unsigned char*p;
int i;
p=(unsigned char*)buf;
for(i=startx;i<=endx;i++)
{
locate(i,y);
r.h.ah=9;
r.h.bh=0;
r.x.cx=1;
r.h.al=*p++;
if(attrib==-1)r.h.bl=*p++;
else
{
r.h.bl=attrib;
p++;
}
int86(0x10,&r,&r);
}
return (unsigned int*)p;
}
void restore_video(int startx,int starty,int endx,int endy,
unsigned int *buf_ptr)
{
int i,j;
for(i=starty;i<=endy;i++)
buf_ptr=restoreline(startx,i,endx,buf_ptr);
}
int readscream(int x,int y)
{
locate(x,y);
asm{
mov ah,8;
mov bh,0;
int 0x10;
}
return _AX;
}
int read(int x,int y,int n,int c)
{
int i;
unsigned int p[80];
if(n>79)return -1;
saveline(x,y,x+n,p);
restoreline(x,y,x+n,p,c);
locate(0,0);
i=readkey(0);
restoreline(x,y,x+n,p);
return i;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -