Test Foro de elhacker.net SMF 2.1

Programación => Programación C/C++ => Mensaje iniciado por: Gunhack en 5 Abril 2015, 20:22 PM

Título: Menú ¿Dinámico? en C
Publicado por: Gunhack en 5 Abril 2015, 20:22 PM
Buenas, no se si tenga algún nombre en especifico este tipo de menús, acabo de hacer esta "plantilla" por así decirlo, sólo que quiero saber si se puede simplificar más o que consejo me darían para hacer los menús así.  ;D

(http://k33.kn3.net/6/9/0/E/F/3/41C.png)

Código (cpp) [Seleccionar]

#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>

using namespace std;
//Define las opciones máximas.
#define opmax 3

void SetBG(int ForgC, int BackC);
void menu ();
int tec(int *o1,int *o2,int *o3,int *y,int *t1,int *t2,int *t3);

main ()
{
 while (1)
 {
   menu();
 }
}
//Define la función de menú
void menu ()
{
 SetBG(15,0);
 static int o1=14,o2=0,o3=0,y=0,t1=0,t2=15,t3=15;

do{
   system("cls");
   cout << "\n   MENU";
   cout << "\n==========";
   SetBG(t1,o1);
   cout << "\n\n*Opcion 1";
   SetBG(t2,o2);
   cout << "\n\n*Opcion 2";
   SetBG(t3,o3);
   cout << "\n\n*Opcion 3";
   SetBG(15,0);
 }while (tec(&o1,&o2,&o3,&y,&t1,&t2,&t3)!=13);

 switch (y)
 {
   case 1: system("cls");cout << "Ejecutando 1";
           break;
   case 2: system("cls");cout << "Ejecutando 2";
           break;
   case 3: system("cls");cout << "Ejecutando 3";
           break;
   default: break;

 }
 getch();
}
//Define la función que lee las teclas usadas por el usuario.
int tec(int *o1,int *o2,int *o3,int *y,int *t1,int *t2,int *t3)
{
   int s;
   s=getch();
   switch (s)
   {
     case char(72):  *y-=1;
                     break;
     case char(80):  *y+=1;
                     break;
     case char(13):  return 13;
                     break;
     default:  break;
   }
   switch (*y)
   {
     case 1: *o1=14;*o2=0;*o3=0;
             *t1=0;*t2=15;*t3=15;
             break;
     case 2: *o1=0;*o2=14;*o3=0;
             *t1=15;*t2=0;*t3=15;
             break;
     case 3: *o1=0;*o2=0;*o3=14;
             *t1=15;*t2=15;*t3=0;
             break;
     default:  break;
   }

   if (*y==0)
     *y+=1;
   if (*y>opmax)
     *y=*y-1;
}

void SetBG(int ForgC, int BackC)
{
 WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);;
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor);
}

Título: Re: Menú ¿Dinámico? en C
Publicado por: ivancea96 en 5 Abril 2015, 21:55 PM
A lo mejor te interesa que menu() retorne la opción elegida, para que no haya sido en vano xD

También puedes pasarle a meno un arreglo de opciones, para no tener que andar tocando la función en sí.

https://github.com/ivancea/Varios/blob/master/C%2B%2B/selector.h (https://github.com/ivancea/Varios/blob/master/C%2B%2B/selector.h)
Ahí un ejemplo de una clase en C++, sin usar windows.h.
Título: Re: Menú ¿Dinámico? en C
Publicado por: Gunhack en 6 Abril 2015, 04:34 AM
Cita de: ivancea96 en  5 Abril 2015, 21:55 PM
A lo mejor te interesa que menu() retorne la opción elegida, para que no haya sido en vano xD

También puedes pasarle a meno un arreglo de opciones, para no tener que andar tocando la función en sí.

https://github.com/ivancea/Varios/blob/master/C%2B%2B/selector.h (https://github.com/ivancea/Varios/blob/master/C%2B%2B/selector.h)
Ahí un ejemplo de una clase en C++, sin usar windows.h.

No se si te entendí bien con lo de la función menu(), pero si retoma la opción o bueno al regresar si se queda seleccionada, solo quería saber si el código que hice se puede simplificar x).
Veré si puedo hacer lo de los arreglos y gracias aunque aún no se programar en C++  :xD
Título: Re: Menú ¿Dinámico? en C
Publicado por: eferion en 6 Abril 2015, 12:17 PM
¿Qué tal algo así?

Código (cpp) [Seleccionar]
#include <iostream>
#include <set>
#include <vector>
#include <conio.h>
#include <windows.h>

class MenuItem
{
 public:

   MenuItem( char tecla,
             const std::string& texto,
             unsigned char backColor,
             unsigned char foreColor )
     : _tecla( tecla ),
       _texto( texto ),
       _backColor( backColor ),
       _foreColor( foreColor )
   { }

   ~MenuItem( )
   { }

   char Tecla( ) const
   { return _tecla; }

   std::string Texto( ) const
   { return _texto; }

   unsigned char BackColor( ) const
   { return _backColor; }

   unsigned char ForeColor( ) const
   { return _foreColor; }

 private:

   char _tecla;
   std::string _texto;
   unsigned char _backColor;
   unsigned char _foreColor;
};

void SetBG(unsigned char ForgC, unsigned char BackC);
void menu();
char mostrarMenu( const std::vector< MenuItem >& items );

main ()
{
while (1)
{
  menu();
}
}

//Define la función de menú
void menu()
{
 std::vector< MenuItem > items;
 items.push_back( MenuItem( '1', "Opción 1", 14, 0 ) );
 items.push_back( MenuItem( '2', "Opción 2", 0, 5 ) );
 items.push_back( MenuItem( 'a', "Opción 3", 4, 7 ) );

 char opcion = mostrarMenu( items );

 switch( opcion )
 {
   case '1':
     system( "cls" );
     std::cout << "Ejecutando 1" << std::endl;
     break;
   case '2':
     system( "cls" );
     std::cout << "Ejecutando 2" << std::endl;
     break;
   case 'a':
     system( "cls" );
     std::cout << "Ejecutando 'a'" << std::endl;
     break;

   default:
     break;
 }

 getch( );
}

char mostrarMenu( const std::vector< MenuItem >& items )
{
 char to_return;
 std::set< char > validAnswer;

 do
 {
   system( "cls" );
   std::cout << "   MENU" << std::endl
             << "===================" << std::endl;
   for( auto& item : items )
   {
     SetBG( item.ForeColor( ), item.BackColor( ) );
     std::cout << "  " << item.Tecla( ) << ". " << item.Texto( ) << std::endl;
     validAnswer.insert( item.Tecla( ) );
   }
   SetBG(15,0);
   std::cin >> to_return;

 } while( validAnswer.count( to_return ) == 0 );

 return to_return;
}

void SetBG(unsigned char ForgC, unsigned char BackC)
{
 WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor);
}


Se podría conseguir un código más claro si se "mapeasen" los colores:

Código (cpp) [Seleccionar]

enum Color : unsigned char
{
  Black,
  DarkBlue,
  DrakGreen,
  DarkAqua,
  DarkRed,
  DarkPurple,
  DarkYellow,
  Silver,
  Gray,
  Blue,
  Green,
  Aqua,
  Red,
  Purple,
  Yellow,
  White
};

// ...

class MenuItem
{
  public:

    MenuItem( char tecla,
              const std::string& texto,
              Color backColor,
              Color foreColor );

    Color BackColor( ) const;

    Color ForeColor( ) const;

  private:

    Color _backColor;
    Color _foreColor;
};

// ...

  items.push_back( MenuItem( '1', "Opción 1", Black, Red ) );
  items.push_back( MenuItem( '2', "Opción 2", Black, Blue ) );
  items.push_back( MenuItem( 'a', "Opción 3", Silver, Purple ) );