Avatar billede funtex Nybegynder
28. august 2002 - 17:34 Der er 1 kommentar og
1 løsning

Menu med cursor valg

Hej
Jeg vil gerne lave en menu i c++ console mode, hvor man vælger med pile tasterne.
Nogen forslag?

//Funtex
Avatar billede soepro Nybegynder
29. august 2002 - 08:24 #1
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().
Avatar billede funtex Nybegynder
04. september 2002 - 21:54 #2
Tak
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester