C_Kurs_Lekt / C_III_семестр / 16-1_Вертикальное_меню
.pdfВертиêальное меню
// Эта проãрамма - пример всплывающеãо меню вертиêальное
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<bios.h>
#include<ctype.h>
#include<string.h>
#include<dos.h>
#define VID_MEM ( ( char far* ) ( 0xB8000000L ) )
void draw_border(int , int , int , int ,int, int, int); void display_menu(char *[], int , int ,int, int, int ); void put_color_text(int ,int ,char *, int );
int user_case(int , int , int , char *[], char *, int, int, int); int popupver( char *[],char *, int , int, int, int, int, int, int); int is_in(char *, char );
void clskbr(void);
void vrest( int , int , int , int , const char far * ); void vsave( int , int , int , int , char far * );
void main(){
int vibor, i,j,c, col;
char *menu_name1[] = { "ВЫБОР ФУНКЦИИ 1", "Выбор №2", "ТРЕТИЙ ПУНКТ МЕНЮ", "ВЫХОД" };
clrscr(); c=32; col=1;
for(i=1; i<=25; i++) for(j=1; j<=80; j++,c++){ if(c>255) c=32; if(col>15) col=1;
if(i!=25 && j!=80) {textcolor(col); putch(c);}
}
do {
_setcursortype(_NOCURSOR);
vibor=popupver( menu_name1, "0123", 4, 3, 3, 1, 8, 0, 15); _setcursortype(_NORMALCURSOR);
gotoxy(10,23); cprintf("Пользователь выбрал пóнêт %d", vibor);
getch();
}
while(vibor != -1);
}
1
/* высвечивание меню в óêазанном месте */
void display_menu(char *menu[], int x, int y,int count,
int tcolor, int foncolor) {
int i;
struct text_info ti; char oldatr; gettextinfo(&ti); oldatr=ti.attribute; textcolor(tcolor); textbackground(foncolor);
for(i=0;i<count;i++,y++){
gotoxy(x,y);
cputs(menu[i]);
}
textattr(oldatr);
}
void draw_border(int x1, int y1, int x2, int y2,
int bord, int linecolor, int
foncolor) {
//Фóнêция обводит рамêою прямоóãольнóю область
//void draw_border(int x1, int y1, int x2, int y2, int color)
//можно добавить цвет (необходимо бóдет заменить putchar на putch )
//можно добавить выбор типа рамêи: 0 - нет; 1 - одинарная; 2 - двойная
unsigned char b[][6] = { { 32, 32, 32, 32, 32, 32 },
{
196, 179, 218, 192, 191, 217 },
{
205, 186, 201, 200, 187, 188 } }; struct text_info ti;
char oldatr; int i, j;
gettextinfo(&ti);
oldatr=ti.attribute;
textcolor(linecolor);
textbackground(foncolor);
for(i=x1+1;i<x2;i++) { gotoxy(i,y1); putch(b[bord][0]); gotoxy(i,y2); putch(b[bord][0]);
}
for(i=y1+1;i<y2;i++) { gotoxy(x1,i); putch(b[bord][1]); for(j=x1+1;j<x2;j++) {
gotoxy(j,i);
putch(32);
}
gotoxy(x2,i);
putch(b[bord][1]);
}
gotoxy(x1,y1); putch(b[bord][2]);
2
gotoxy(x1,y2); putch(b[bord][3]); gotoxy(x2,y1); putch(b[bord][4]); gotoxy(x2,y2); putch(b[bord][5]);
textattr(oldatr);
}
//вывод теêстовой строêи óêазанным цветом и фоном с восстановлением
//прежних атрибóтов теêста
void put_color_text(int x,int y,char *p, int attrib) { struct text_info ti;
char oldatr; gettextinfo(&ti); oldatr=ti.attribute; textattr(attrib); gotoxy(x,y); cputs(p); textattr(oldatr);
}
/* ввести выбор пользователя */
user_case(int x, int y, int count, char *menu[], char *keys,
int tcolor, int foncolor, int usercolor) { union inkey { // объединение для "поддержêи" bioskey т.е. INT 16
char ch[2]; // младший и старший байты int i; // слово целиêом
} c;
int arrow_choice=0,key_choice, textatuser, textatmenu;
/* осветить первый выбор */ gotoxy(x,y);
textatuser = usercolor + (foncolor<<4); textatmenu = tcolor + (foncolor<<4);
put_color_text(x,y,menu[0], textatuser); // Подсвеченный пóнêт clskbr();
for(;;) {
while(!bioskey(1)); /* ждать нажатия */ c.i=bioskey(0); // взять êод из бóфера êлавиатóры
/* вернóть выбор в номальный режим */ gotoxy(arrow_choice,y); put_color_text(x,y+arrow_choice, menu[arrow_choice],
textatmenu);
if(c.ch[0]) { /* обычная êлавиша */ key_choice= is_in(keys,tolower(c.ch[0])); if(key_choice) return key_choice-1; switch(c.ch[0]) {
case '\r' : return arrow_choice;
case ' ' : arrow_choice++; break; /* "пробел" -
на пóнêт ниже */
case 27 : return -1; /* выйти из меню */
}
}
else { /* специальная êлавиша */ switch(c.ch[1]) {
3
case 72 : arrow_choice--; break;/* стрелêа вниз
*/
case 80 : arrow_choice++; break;/* стрелêа вверх
*/
}
}
if(arrow_choice==count) arrow_choice=0; if(arrow_choice<0) arrow_choice=count-1;
/* подсветить выбраннóю опцию */ gotoxy(x+arrow_choice,y); put_color_text(x,y+arrow_choice,menu[arrow_choice],
textatuser);
}
}
/* Фóнêция is_in() возвращает позицию "ãорячей" êлавиши в строêе. Если пользователь нажал не êлючевóю êлавишó,
то is_inвозвращает 0. */ int is_in(char *s, char c){
int i;
for(i=0; *s; i++)
if(*s++ == c) return i+1; return 0;
}
// Очистêа бóфера êлавиатóры
void clskbr( void )
{
asm {
PUSH ES; XOR AX , AX; CLI;
MOV ES , AX;
MOV AX , ES:[41Ah];
MOV ES:[41Ch] , AX; STI;
POP ES;
};
}
/* вывести исчезающее меню и вернóть выбор возвращает -2, если меню не может быть создано
возвращает -1, если пользователь нажал êлавишó ESC в остальных слóчаях она возвращает номер выбранной альтернативы, начиная с 0 */
int popupver( char *menu[],char *keys, int count, int x, int y, int border,
|
|
int tcolor, int foncolor, int usercolor ) |
// |
char *menu[]; |
теêст меню |
// |
char *keys; |
ãорячие êлавиши |
//int count; число альтернатив (пóнêтов меню)
// |
int x,y; |
êоординаты левоãо верхнеãо óãла |
//int border; если 0 то без рамêи
//int tcolor; цвет теêста меню и рамêи
// |
int |
foncolor; |
цвет |
фона |
// |
int |
usercolor; |
цвет |
подсвеченноãо пóнêта |
4
{
int i,len;
int endx, endy, choice;
//char buffer[4096]; unsigned char *buffer;
if((x>80)||(x<1)||(y>25)||(y<1)) { printf(" выход за пределы эêрана"); return -2;
}
/* вычисление размеров */ len=0; for(i=0;i<count;i++)
if(strlen(menu[i]) > len) len=strlen(menu[i]); endx=len+1+x;
endy=count+1+y;
if((endx+1>25) || (endy+1>80)) { printf(" выход за пределы эêрана"); return -2;
}
/* размещение памяти для видео бóфера */ buffer=(unsigned char *)calloc((endx-x+1)*(endy-y+1), 2);
//buffer=(unsigned char *)calloc(80*25*2, 1);
if(!buffer) exit(1); /* Вы можете здесь сами обработать ошибêó
*/
/* сохранение части эêрана */
gettext(x,y,endx,endy,buffer); // vsave(x,y,endx,endy, buffer);
if(border) draw_border(x,y,endx,endy, 1, tcolor, foncolor);
/* высвечивание меню на своем месте */ display_menu(menu,x+1,y+1,count, tcolor, foncolor);
/* ввести выбор пользователя */ choice=user_case(x+1,y+1,count,menu,keys, tcolor, foncolor,
usercolor);
/* восстановление части эêрана */ puttext(x,y, endx, endy, buffer);
//vrest(x,y,endx,endy, buffer);
free(buffer); return choice;
}
void vsave( int l , int t , int r , int b , char far *buf )
{
char far *v , far *tm; register int i;
int lx , ly , j;
lx = b - t + 1; ly = ( r - l + 1 ) * 2; v = VID_MEM + t*160 + l*2;
5
for( j=0; j<lx; j++ ) { tm = v;
for( i=0 ; i<ly; i++ ) *buf++ = *tm++; v += 160;
};
}
void vrest( int l , int t , int r , int b , const char far *buf )
{
char far *v , far *tm; register int i;
int lx , ly , j;
lx = b - t + 1; ly = ( r - l + 1 ) * 2; v = VID_MEM + t*160 + l*2;
for( j=0; j<lx; j++ ) { tm = v;
for( i=0; i<ly; i++ ) *tm++ = *buf++; v += 160;
};
}
6