Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

C_Kurs_Lekt / C_III_семестр / 16-1_Вертикальное_меню

.pdf
Скачиваний:
9
Добавлен:
13.02.2016
Размер:
40.56 Кб
Скачать

Вертиêальное меню

// Эта проãрамма - пример всплывающеãо меню вертиêальное

#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

Соседние файлы в папке C_III_семестр