Hali. Ez lesz itten a harmadik nekifutás azügyben, hogy valami ehető féle programot hozzak össze telefonkönyvügyileg. Mivel a téma kezd unalmassá válni most már nagyjából befejezem. A múltkor ott tartottunk, hogy minden működött ugyan, csak egy kicsit tréh módon nézett ki. Valami kis képernyőkezeléssel fel kéne dobni a cuccost, aztán készen is volna. Nosza!

A szöveges képernyő kezeléséhez csak a CONIO.H header-filera lesz szükség. Egy kis alap

Globáis változók a headerből, amira szükség lesz:
  • directvideo azt szabályozza, hogy a kiiratások a BIOS-on keresztül cammognak(alapértelmezés), vagy közvetlen a video memóriába íródnak. Persze nekünk ez utóbbi kell, ezért az értékét 1-re kell állítani.
  • _wscroll engedélyezi, vagy tiltja a képernyő görgetését, ha a kurzor az utolsó karakterpozícióba ér.

  • Az alapértelmezés 1, tehát görget. 0-ra kell állítani.
Függvények
  • textcolor(COLOR) -vajon mi lehet
  • textbackground(BACKGROUND)
  • textattr(newattr)
  • gotoxy(x,y)
  • gettext(x1,y1,x2,y2,buffer); A memóriába menti a meghatározott képernyőterületet. Igen használható. Mivel minden karaktert az attributumával együtt ment, logikus, hogy (x2-x1+1)*(y2-y1+1)*2 byte memória kell.
  • puttext A memóriába mentett cuccot kivágja a képernyőre.
  • _setcursortype(TYPE) Kurzor átállítása. Lehetséges értékek: _NOCURSOR/_SOLIDCURSOR?NORMALCURSOR
  • gettextinfo(struct text_info) Az aktuális beállítások lekérdezése. pl szín, háttér, kurzor helye, ablak mérete stb
Itt egy függvény, ami a kezdeti dolgokat elintézi:
void screeninit(void) { directvideo=1;            //nem a BIOS on keresztul cammog _wscroll=0;               //nem gorgeti a kepernyot textbackground(BLUE); clrscr(); }

Nézzük a menüvezérlést. Az elv nagyon egyszerű. Amelyik menüpont éppen ki van választva, az más színű, mint a többi. Mivel a menüpontok száma változó, egy ilyen kezelőfüggvényt változó paraméterszámúra kell megírni. Ez C-ben nem is olyan nehéz.:

int mnuwin(int x1, int y1, int x2, int y2 , char *cim, int n, char *mnu1, ...) { int t,c; struct text_info ti; char *bck; _setcursortype(_NOCURSOR); gettextinfo(&ti);    //eredeti allapot bck=(char *)malloc((x2-x1+1)*(y2-y1+1)*2); gettext(x1,y1,x2,y2,bck); textbackground(NORMALBCK); textcolor(NORMALCOL); ablak(x1,y1,x2,y2,cim,0);  //keret for(t=0;t<n;t++)                  //kirak {   gotoxy((x1+x2)/2-strlen(*(&mnu1+t))/2,y1+t+1);   cprintf("%s",*(&mnu1+t)); } t=0; do                       //mozog {   textbackground(SELECTEDBCK);   textcolor(SELECTEDCOL);   gotoxy((x1+x2)/2-strlen(*(&mnu1+t))/2,y1+t+1);   cprintf("%s",*(&mnu1+t));   c=getch();   textbackground(NORMALBCK);   textcolor(NORMALCOL);   gotoxy((x1+x2)/2-strlen(*(&mnu1+t))/2,y1+t+1);   cprintf("%s",*(&mnu1+t));   if (c==0)   {    c=getch();    switch(c)    {     case UP: if (t>0) t--; break;     case DOWN: if (t<n-1) t++; break;    }   } } while (c!=ESC && c!=ENTER); if (c==ESC) t=-1; fflush(stdin); puttext(x1,y1,x2,y2,bck); free(bck); _setcursortype(_NORMALCURSOR); return(t); }

A függvény paraméterei a bal feső, és a jobb alsó sarok, az menuablak címe, a menüpontok száma, és utánna sorra a menüpontok. Az összes átadott paramétert könnyen tudjuk kezelni, annak számától függetlenül.

Pl az n. menupont: *(&menu1+n)

annak számától függetlenül.

A &menu1 az első menupont címe a stacken. Mivel a C a paramétereket fordított sorrendben vermeli el, innen a stacken visszafele járva meg fogjuk találni a második, harmadik stb menupontot. tehát ehez az offsethez hozza kell adni. Világos.

A függvény azzal kezd, hogy elmenti maga előtt az éppen aktuális állapotokat, és azzal fejezi be, hogy ezeket visszaállítja. érdemi dolgokat csak a kettő között csinál. Először kiírja az összes mennupontot, ezután lehet mennupontot választani.

Ha menüablakból kell adatokat bekérni, kell valami ilyesféle valamit írni:
 

int linedit(int cx,int cy,char *str) { int x=0,y,l,ex=0; char c; l=strlen(str); // x=l; do {   gotoxy(cx,cy);cprintf("%s",str);   gotoxy(cx+x,cy);   c=getch();   switch(c)   {    case 0: c=getch();     switch(c)     {      case RIGHT: if (x<l-1) x++; break;      case LEFT: if (x>0) x--; break;      case UP:   ex=1; break;      case DOWN: ex=1; break;      case DEL:  memmove(str+x,str+x+1,l-x);str[l-1]=' ';break; //            case INS:     }     break;    case BS: if (x>0) {x--;memmove(str+x,str+x+1,l-x);str[l-1]=' ';} break;    case ESC:   ex=1; break;    case ENTER: ex=1; break;    default: if (x<l-1)      {        memmove(str+x+1,str+x,l-x);str[x]=c;str[l]=0;x++;      }      break;   }  //switch } while(!ex); fflush(stdin); return(c); }

Egy egyszerű kis függvény, ami kezeli a backspace-t, nyilakat, del-t.

Azt hiszem, most a szokásosnál is sikerült zavarosabbnak lennem. A programban a képernyőkezelés egy külön file-ba került, ezért aztán most már egy projekt az egész. Az igazsághoz hozzátartozik, hogy ilyen feladatokat nagyságrendekkel egyszerűbb Turbo Visionban (van cpp-s változata is) megoldani. Ld. OOP rovat.