С для профессиональных программистов

       

Простая программа, использующая процедуру pulldown


Все функции для иерархических меню показаны здесь вместе с простой программой-образцом и их можно прямо вводить в ваш компьютер.

/* процедура иерархического меню для текстового режима

и простая программа-пример */

#include "dos.h"

#include "stdlib.h"

#define ESC 27

void save_video(),restore_video();

void display_menu(),draw_border();

char far *vid_mem;

struct menu_frame

int startx,endx,starty,endy;

unsigned char *p;                /*    указатель на информацию экрана */

char **menu;                        /*    указатель на строки меню */

int border;                             /*    рамка включено/выключено */

int count;                               /*    число альтернатив */

int astive;                              /*    активно ли меню сейчас */



 frame[MAX_FRAME];

;

;

char *grape_type[]=

"Конкорд",

"кАнадский",

"Томпсон",

"кРасное пламя"

main()

/* во-первых создадим фреймы меню */

make_menu(1,color,"кжоз",4,9,28,BORDER);

int choice1,choice2,selection;

/* активизация окон по мере надобности */ while((choice1=pulldown(0)) != -1)

switch ( choice1 )

case 0 :  /* яблоко */

while((choice2=pulldown(1)) != -1)

if(choice2 ==0) selection=pulldown(2);/*красное яблоко */

restore_video(2);

restore_video(1);

break;

case 1 :

case 2 : goto_xy(1,0);

printf("неправильный выбор");

break;

case 3 : /* грейпфрут */

selection=pulldown(3);

restore_video(3);

break;

case 4 :

case 5 : goto_xy(1,0);

printf("неправильный выбор");

break;

restore_video(0);

int pulldown(num)

int vmode,choice;

vmode=video_mode();

if((vmode!=2) && (vmode!=3) && (vmode!=7))

printf(" должен быть 80 символьный текстовый режим");

exit(1);

/* присвоить соответствующий адрес видео памяти */

/* узнать активнсть окна */

if( frame[num].border) draw_worder(num);

return get_resp(num);  /* возвратить выбор */


/* вычисление размеров */

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

if(strlen(menu[i]) > len) len=strlen(menu[i]);

endx=count+1+x;

p=(unsigned int *)malloc((endx-x+1)*(endy-y+1));

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

frame[num].startx=x;

frame[num].starty=y;

frame[num].p = p;

frame[num].border = border;

frame[num].count = count;

return 1;

void display_menu(num)

int num;

for(i=0;i<frame[num].count;i++,x++)

write_string(x,frame[num].starty+1,m[i],NORM_VID);

int  num ;

write_char(frame[num].endx  ,frame[num].endy  ,217,NORM_VID);

goto_xy(frame[num].endx  ,frame[num].starty); putchar(192);

get_resp(num)

union inkey

char ch[2];

int i;

 c;

x=frame[num].startx+1;

y=frame[num].starty+1;

goto_xy(x,y);

write_string(x,y,frame[num].menu[0],REV_VID);

/* вернуть выбор в номальный режим */

write_string(x+arrow_choice,y,

frame[num].menu[arrow_choice],norm_vid);

else  /* специальная клавиша */

switch(c.ch[1])

case 72 : arrow_choice--; /* стрелка вниз */

break;

case 80 : arrow_choice++; /* стрелка вверх */

break;

if(arrow_choice==frame[num].count) arrow_choice=0;

if(arrow_choice<0) arrow_choice=frame[num].count-1;

/* подсветить выбранную опцию */ goto_xy(x+arrow_choice,y); write_string(x+arrow_choice,y,

/* вывод строки с определенным атрибутом */

void write_string(x,y,p,attrib)

int x,y;

char *p;

int attrib;

register int i,j;

char far *v;

v=vid_mem;

v += (x*160) + y*2;

for(i=y; *p; i++)

*v++ =*p++; /* запись символа */

*v++ =attrib; /* запись атрибута */

/* запись символа с определенным аттрибутом */

void write_char(x,y,ch,attrib)

int x,y;

char ch;

int attrib;

void save_video(num)

int num;

void restore_video(num)

register int i,j;

char far *v, far *t;

char *buf_ptr;

buf_ptr=frame[num].p;

v=vid_mem;

t=v;

for(i=frame[num].starty;i<frame[num].endy;i++)

for(j=frame[num].startx;j<frame[num].endx;j++)



v = t;

v += (j*160) + i*2;   /* вычисляем адрес */

*v++ = *buf_ptr++;    /* запись символа */

*v = *buf_ptr++;                            /* запись атрибута */

frame[num].active= 0;

/* очистка экрана */

/* установка курсора в x,y */

int x,y;

video_mode()

char *s,c;

В этом примере, если пользователь выберет "Яблоко", то он или она будет запрошен о цвете яблока; если выбран "Красный" цвет, то будет высвечен список красных сортов яблок. Если же будет выбран грейпфрут то пользователь будет запрошен о желаемом типе. Меню для выбора яблок показано на рисунке.

выберите фрукт:

|Яблоко |

|Апельсин |

|Груша |

|гРейпфрут|

|Малин---------

|Клубн|Красный|

-------Желтый |

|Ора-------------------

|Зел|Красный деликатес|

----|Д*ж*о*н*а*т*а*н**|

|Белый налив |

|Антоновка |

Посмотрите внимательно на функцию pd_driver(), которая следует за главной функцией main(). При использовании иерархических меню вы должны создавать функцию, которая управляет системой меню. Основа стратегии управляющей функции должна быть аналогична функции pd_driver() из этого примера. Не забывайте, что эта простая программа только иллюстрирует как активизировать меню. Ваша реальная прикладная программа будет обрабатывать выбранные режимы более разумным образом. Запомните, что для использования иерархических меню нужна следующая последовательность действий.

1. Создать меню, используя make_menu().

2. Активизировать меню, используя pulldown().

3. Восстановить экран, используя restore_video(), при выходе из каждого меню.


Содержание раздела