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)
#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);
}
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.
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
¿Qué tal algo así?
#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:
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 ) );