Ja - du kan bruge gotoxy() til at positionere dig et bestemt sted på skærmen, og f.eks. textattr() til at skifte forgrund/baggrund farve for de valgte menu-punkter.
Jeg har lavet et lille menu-program der gør sådan (du kan hente det på
http://hjem.get2net.dk/soepro/download/menu.exe), humlen i det er denne funktion, som du kan lade dig inspirere af:
#ifndef __XMENU_CPP__
#define __XMENU_CPP__
#include <inctools.h>
char _XMENU_SaveWindow[4000];
text_info _XMENU_OrgAttr;
int _XMENU_OptX[31], _XMENU_OptY[31];
char _XMENU_OptLtr[31];
char *_XMENU_OptTxt[31];
int _XMENU_MnuX, _XMENU_MnuY,
_XMENU_Hattr, _XMENU_Oattr, _XMENU_SOattr;
int _XMENU_CurOpt, _XMENU_MaxOpt, _XMENU_MaxOptLen;
char *_XMENU_MnuHdrTxt[2];
char *_XMENU_TopLine, *_XMENU_BotLine,
*_XMENU_SepLine, *_XMENU_MiddleLine;
/***************************************************/
void _XMENU_WriteOpt(int OptNbr, int FG, int BK)
/***************************************************/
{
static int Idx;
/* Print the option string character by character to catch and */
/* print option short-key letter correctly. */
gotoxy(_XMENU_MnuX+2+_XMENU_OptX[OptNbr],
_XMENU_MnuY+1+_XMENU_OptY[OptNbr]);
textattr(FG + (BK << 4));
for (Idx = 0; *(_XMENU_OptTxt[OptNbr]+Idx); Idx++)
{
if (*(_XMENU_OptTxt[OptNbr]+Idx) == '~')
{
Idx++;
if (OptNbr != _XMENU_CurOpt)
textattr(BK + ((FG & 0x7) << 4));
else
textattr(FG + (BK << 4));
}
else
textattr(FG + (BK << 4));
putch(*(_XMENU_OptTxt[OptNbr]+Idx));
}; /* Until entire option re-printed. */
} /* _XMENU_WriteOpt */
/**********************************/
int _XMENU_WriteMenu(int DftOpt)
/**********************************/
{
static int Idx, lastY, lastOpt;
static int firstTIME, csrON, showshiftON;
static uint KeyPressed;
gettext(1, 1, 80, 25, &_XMENU_SaveWindow);
gettextinfo(&_XMENU_OrgAttr);
firstTIME = TRUE;
csrON = (char)CursorOn();
showshiftON = (char)isshowshiftON();
setshowshiftOFF();
KeyPressed = SPACE;
while (KeyPressed != ENTER)
{
/* Restore org. window unless 1st time. (To allow move of menu.) */
if (firstTIME)
firstTIME = FALSE;
else
puttext(1, 1, 80, 25, &_XMENU_SaveWindow);
/* Display menu. */
HideCursor();
textattr(_XMENU_OrgAttr.attribute);
gotoxy(_XMENU_MnuX, _XMENU_MnuY);
cputs(_XMENU_TopLine);
gotoxy(_XMENU_MnuX+(_XMENU_MaxOptLen-strlen(_XMENU_MnuHdrTxt[0]))/2+2,
_XMENU_MnuY);
textattr(_XMENU_Hattr);
cputs(_XMENU_MnuHdrTxt[0]);
if (_XMENU_MnuHdrTxt[1][0] != 0)
{
textattr(_XMENU_OrgAttr.attribute);
gotoxy(_XMENU_MnuX, _XMENU_MnuY+1);
cputs(_XMENU_MiddleLine);
gotoxy(_XMENU_MnuX+(_XMENU_MaxOptLen-strlen(_XMENU_MnuHdrTxt[1]))/2+2,
_XMENU_MnuY+1);
textattr(_XMENU_Hattr);
cputs(_XMENU_MnuHdrTxt[1]);
textattr(_XMENU_OrgAttr.attribute);
gotoxy(_XMENU_MnuX, _XMENU_MnuY+2);
cputs(_XMENU_SepLine);
};
lastY = -1;
for (Idx = 0; Idx <= _XMENU_MaxOpt; Idx++)
{
if (_XMENU_OptY[Idx] != lastY)
{
lastY = _XMENU_OptY[Idx];
gotoxy(_XMENU_MnuX,
_XMENU_MnuY+lastY+1);
textattr(_XMENU_OrgAttr.attribute);
cputs(_XMENU_MiddleLine);
};
if (Idx == _XMENU_CurOpt)
_XMENU_WriteOpt(Idx, _XMENU_SOattr & 0x0F, _XMENU_SOattr >> 4);
else
_XMENU_WriteOpt(Idx, _XMENU_Oattr & 0x0F, _XMENU_Oattr >> 4);
};
gotoxy(_XMENU_MnuX, _XMENU_MnuY + _XMENU_OptY[_XMENU_MaxOpt] + 2);
textattr(_XMENU_OrgAttr.attribute);
cputs(_XMENU_BotLine);
/* Read desired option or move request. */
KeyPressed = SPACE;
while (KeyPressed != ENTER && KeyPressed != 0)
{
textattr(_XMENU_OrgAttr.attribute);
lastOpt = _XMENU_CurOpt;
KeyPressed = readkey();
switch (KeyPressed)
{
case ENTER : /* Accept option. */
break;
case ESC : _XMENU_CurOpt = 99;
KeyPressed = ENTER;
break;
case ALTD : _XMENU_CurOpt = DftOpt;
KeyPressed = ENTER;
break;
case LEFT : /* Previous option. */
case UP :
case RIGHT : /* Next option. */
case DOWN : if (KeyPressed == LEFT || KeyPressed == UP)
_XMENU_CurOpt = decr(_XMENU_CurOpt, _XMENU_MaxOpt);
else
_XMENU_CurOpt = incr(_XMENU_CurOpt, _XMENU_MaxOpt);
_XMENU_WriteOpt(lastOpt,
_XMENU_Oattr & 0x0F,
_XMENU_Oattr >> 4);
_XMENU_WriteOpt(_XMENU_CurOpt,
_XMENU_SOattr & 0x0F,
_XMENU_SOattr >> 4);
break;
case SHIFTLEFT:
case CTRLLEFT : /* Move menu left if possible */
if (_XMENU_MnuX > 1)
{
_XMENU_MnuX--;
KeyPressed = 0;
};
break;
case SHIFTRIGHT:
case CTRLRIGHT: /* Move menu right if possible */
if ((_XMENU_MnuX+_XMENU_MaxOptLen+3) < 80)
{
_XMENU_MnuX++;
KeyPressed = 0;
};
break;
case SHIFTUP :
case CTRLPGUP :
case CTRLUP : /* Move menu right if possible */
if (_XMENU_MnuY > 1)
{
_XMENU_MnuY--;
KeyPressed = 0;
};
break;
case SHIFTDOWN:
case CTRLPGDN :
case CTRLDOWN : /* Move menu right if possible */
if ((_XMENU_MnuY+_XMENU_OptY[_XMENU_MaxOpt]+2) < 24)
{
_XMENU_MnuY++;
KeyPressed = 0;
};
break;
default : /* Either valid option or invalid key. */
KeyPressed = toupr((char)KeyPressed);
for (Idx = 0; Idx <= _XMENU_MaxOpt; Idx++)
if (KeyPressed == (uint)_XMENU_OptLtr[Idx])
{
_XMENU_CurOpt = Idx;
KeyPressed = ENTER;
break;
};
putch('\a'); /* Not a short-cut key. */
break;
}; /* Switch pressed key. */
}; /* Until ENTER or "refresh" pressed. */
}; /* Until ENTER pressed. */
puttext(1, 1, 80, 25, &_XMENU_SaveWindow);
window(_XMENU_OrgAttr.wintop, _XMENU_OrgAttr.winleft,
_XMENU_OrgAttr.winbottom, _XMENU_OrgAttr.winright);
textattr(_XMENU_OrgAttr.attribute);
gotoxy(_XMENU_OrgAttr.curx, _XMENU_OrgAttr.cury);
if (csrON)
ShowCursor();
if (showshiftON)
setshowshiftON();
return _XMENU_CurOpt;
} /* _XMENU_WriteMenu */
#endif
Bemærk at funktionen anvender en hel del af mine egne toolbox funktioner, som ikke findes i Ansi C/C++ - readkey() kan dog erstattes med getch(), hvis du koder den ekstra getch() der skal til at håndtere F-taster, og keypressed() med kbhit().