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

C_Kurs_Lekt / C_III_семестр / 16-2_Горизонтальное_меню

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

Горизонтальное меню

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

#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_gor(char *[], int , int ,int, int *, int, int, int );

void put_color_text(int ,int ,char *, int );

int user_case_gor(int , int , int , int *, char *[], char *, int, int, int);

int popupgor( 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=popupgor( menu_name1, "0123", 4, 3, 3, 2, 8, 0, 15); _setcursortype(_NORMALCURSOR);

gotoxy(10,23); cprintf("Пользователь выбрал пóнêт %d", vibor);

getch();

}

while(vibor != -1);

}

1

/* высвечивание меню в óêазанном месте */

void display_menu_gor(char *menu[], int x, int y,int count, int *menuXpos,

int bord, int tcolor, int

foncolor) {

unsigned char b[][3] = { { 32, 32, 32 },

{

194, 179, 193 },

{

203, 186, 202 } }; int i;

struct text_info ti; char oldatr; gettextinfo(&ti); oldatr=ti.attribute; textcolor(tcolor); textbackground(foncolor);

for(i=0;i<count;i++){

gotoxy(menuXpos[i],y);

cputs(menu[i]); if ( i<count-1) {

gotoxy(menuXpos[i+1]-2,y-1); putch(b[bord][0]); gotoxy(menuXpos[i+1]-2,y); putch(b[bord][1]); gotoxy(menuXpos[i+1]-2,y+1); putch(b[bord][2]);

}

}

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);

2

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]); 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_gor(int x, int y, int count, int *menuXpos, 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(menuXpos[arrow_choice],y,menu[0], textatuser); //

Подсвеченный пóнêт clskbr();

for(;;) {

while(!bioskey(1)); /* ждать нажатия */ c.i=bioskey(0); // взять êод из бóфера êлавиатóры

3

//
textatuser);

/* вернóть выбор в номальный режим */ gotoxy(arrow_choice,y); put_color_text(menuXpos[arrow_choice],y,

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 27 : return -1; /* выйти из меню */

}

}

else { /* специальная êлавиша */ switch(c.ch[1]) {

case 75 : arrow_choice--; break;/* стрелêа вниз

*/

case 77 : arrow_choice++; break;/* стрелêа вверх

*/

}

}

if(arrow_choice==count) arrow_choice=0; if(arrow_choice<0) arrow_choice=count-1;

/* подсветить выбраннóю опцию */ gotoxy(menuXpos[arrow_choice],y); put_color_text(x,y+arrow_choice,menu[arrow_choice],

put_color_text(menuXpos[arrow_choice],y,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;

4

};

}

/* вывести исчезающее меню и вернóть выбор возвращает -2, если меню не может быть создано

возвращает -1, если пользователь нажал êлавишó ESC в остальных слóчаях она возвращает номер выбранной альтернативы, начиная с 0 */

int popupgor( 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;

цвет подсвеченноãо пóнêта

{

 

 

int i,len;

int endx, endy, choice, *menuXpos; unsigned char *buffer;

if((x>80)||(x<1)||(y>25)||(y<1)) { printf(" выход за пределы эêрана"); return -2;

}

menuXpos=(int *)calloc(count, 1);

if(!menuXpos) exit(1); /* Вы можете здесь сами обработать ошибêó

*/

/* вычисление размеров */ len=0; for(i=0;i<count;i++) {

menuXpos[i]= x + len + 2; len += strlen(menu[i])+3; }

endx= x + len; endy= y + 2;

if(( endx > 80) || ( endy > 25)) { 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);

draw_border(x, y, endx,endy, border, tcolor, foncolor);

/* высвечивание меню на своем месте */

5

display_menu_gor(menu,x+1,y+1,count, menuXpos, border, tcolor, foncolor);

/* ввести выбор пользователя */ choice=user_case_gor(x+1,y+1,count, menuXpos, menu,

keys, tcolor,

foncolor, usercolor);

/* восстановление части эêрана */ puttext(x,y, endx, endy, buffer);

//vrest(x,y,endx,endy, buffer); free(menuXpos);

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;

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_семестр