Thread: System calls stopping my function ...

  1. #1
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273

    System calls stopping my function ...

    Hi, this has been bugging me for AGES!

    I know I shouldn't really use system calls (like cls, and whatnot), but it's easier than writing my own and I'd prefer not to resort to OPTION 5. Anyways, my code is below. Essentially you pass a vector of strings each set up as an option in a menu into the function, and it displays them, and you can choose the option you want by clicking with the mouse on the option.

    The parameters are as follows:

    vector<string> Options - Your Menu
    bool CountSpaces=true - you may want to make your code more visually pleasing, so you can 'push_back()' this (""), and by setting this false it won't count them.
    int X_Offset=-1,
    int Y_Offset=-1
    - for positioning the menu. Leave negative for the function do decide where to put it, depending on where the cursor currently is.

    Return value - The position of the option (from 0 to Options.size()

    Anyway. Logically, one would want to clear the menu before/after selection, but when I try this with my lazy way out, the menu function (below), doesn't work. Does anyone know why this may be? (Sorry for the not nice formatting - there was some mess up in copying and pasting).

    Code:
    #include <conio.h> // Most of the headers are not needed, and are used for other purposes in the program
    #include <time.h>
    #include <windows.h>
    #include <tchar.h>
    #include <cctype>
    
    #include <iostream>
    #include <fstream>
    #include <string> 
    #include <vector>
    #include <sstream>
    
    using namespace std; 
     
     
     
     
     
    
    void Color  ( int BackgroundColor, int TextColor )
    {
     int SeclectedColor = (16*BackgroundColor) + (TextColor);
    
     HANDLE hConsole;
     hConsole = GetStdHandle ( STD_OUTPUT_HANDLE );
     SetConsoleTextAttribute ( hConsole, SeclectedColor );
    }
    
     
    
    void GotoXY  ( int X, int Y ) 
    { 
        COORD Cursor_Position; 
    
        Cursor_Position.X = X; 
        Cursor_Position.Y = Y; 
    
        SetConsoleCursorPosition( GetStdHandle ( STD_OUTPUT_HANDLE ), Cursor_Position ); 
    } 
    
    int  Menu  ( vector<string> Options, bool CountSpaces=true, int X_Offset=-1, int Y_Offset=-1 ) 
    // HighlightColor is for the color the item will be highlighted to
    {                 // when mouse hovers over it. X and Y Offsets are for positioning menu 
     DWORD Event_Count, 
        Input_Size; 
    
     INPUT_RECORD  Record_Input; 
     MOUSE_EVENT_RECORD Mouse; 
    
     const int NumOptions  = (int)Options.size(),
        BLACK   = 0,  // Colors for highlighting. 
        GREY   = 8,
        BRIGHTWHITE  = 15;
    
     int   CurrentOption = -1,  // Currently selected option
        Longest   =  1,  // Longest menu option. 
        i    =  0;
    
     bool  OnOption  = false; // Is an option selected? true if yes, false if no
    
     if ( X_Offset < 0 ) // Error checking. 
     {
      X_Offset = 0;
     }
    
     if ( Y_Offset <= 0 ) // If you just want the menu to be at the cursor's current y-position. 
     {
      CONSOLE_SCREEN_BUFFER_INFO YInfo;
    
      GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &YInfo );
      
      Y_Offset = YInfo.dwCursorPosition.Y+1 ;
     }
    
     vector<string>::iterator OptionsIterator;
    
     for ( OptionsIterator=Options.begin(), i=0; 
       OptionsIterator!=Options.end(); 
       OptionsIterator++, i++ )   // Prints the initial menu.
     {
      int  CurrentLength = (int)Options[i].size();
      if ( CurrentLength > Longest ) Longest = CurrentLength; 
    
      GotoXY( X_Offset, i+Y_Offset);
      
      cout<< *OptionsIterator;
     }
    
     for ( int i=0; i<NumOptions; i++ ) // Appends each option to the same length with whitespaces, 
     {         // for highlighting purposes. 
      int TempLen;
      
      TempLen = (int)Options[i].size();
    
      if ( Options[i] != "" )
      {
       for ( int j=TempLen; j<Longest+1; j++ )
       {
        Options[i] += ' ';
       }
      }
     }
     
     int X = 0, // X and Y coordinates of mouse in console window, not 
      Y = 0; // needed, but it makes the code it visually much simpler.
    
     while ( true ) 
     { 
      GetNumberOfConsoleInputEvents ( GetStdHandle ( STD_INPUT_HANDLE ), &Event_Count ); 
    
      if ( Event_Count != 0 ) 
      { 
       ReadConsoleInput ( GetStdHandle ( STD_INPUT_HANDLE ), & Record_Input, 1, & Input_Size ); 
    
       if ( Record_Input.EventType == MOUSE_EVENT ) 
       {
        Mouse = Record_Input.Event.MouseEvent; 
        
        Y = Mouse.dwMousePosition.Y,
        X = Mouse.dwMousePosition.X;
    
        if ( OnOption ) // For if something is already selected. This had to go first cause 
        {    // otherwise multiple things may be selected.
         if ( CurrentOption != Y-Y_Offset || 
           X > (Longest + X_Offset) || 
           X < (0 + X_Offset) )
         {
          OnOption = false;
          GotoXY( X_Offset, CurrentOption+Y_Offset );
          
          Color( BRIGHTWHITE, BLACK ); // Changes color.
          cout<< Options[CurrentOption]; 
          Color( BLACK, BRIGHTWHITE ); // Changes it again. 
         }
         else if ( GetAsyncKeyState( VK_LBUTTON ) ) 
         {
          if ( Options[CurrentOption] != "" ) 
          {
           GotoXY( X_Offset, CurrentOption+Y_Offset ); 
           
           Color( GREY, BRIGHTWHITE ); // Changes color.
           cout<< Options[CurrentOption];
           Color( BRIGHTWHITE, BLACK ); // Changes it again. 
           
           GotoXY( 0, NumOptions + Y_Offset + 1 ); 
    
           int Blanks = 0;
    
           if ( CountSpaces )
           {
            for ( int i=0; i<CurrentOption; i++ )
            {
             if ( Options[i] == "" ) Blanks ++;
            }
           }
    
           return ( CurrentOption - Blanks ); // if button pressed, returns the current option.
          }
         }
        }
    
        if    ( Y >= (0 + Y_Offset) && Y < (NumOptions + Y_Offset) &&
          X >= (0 + X_Offset) && X < (Longest + X_Offset) ) // selects things
        {
         OnOption  = true; // something is selected, so true. 
         CurrentOption = Y - Y_Offset; 
    
         GotoXY( X_Offset, Y );
         
         Color( BLACK, BRIGHTWHITE );
         cout<< Options[CurrentOption];
         Color( BRIGHTWHITE, BLACK );
        }
       } 
      } 
        }
    
     return -1;
    }
    I reckon just try it out with something like this:

    Code:
     vector<string> options;
     int Selection = -1;
      cout<< endl << "Please make a selection from the following options: "
       << endl;
    
      options.clear();
    
      options.push_back( "* Start new game" );
      options.push_back( "" );
      options.push_back( "* Options" );
      options.push_back( "" );
      options.push_back( "* Load old game" ); 
      options.push_back( "* Save this game" );
      options.push_back( "" );
      options.push_back( "* Delete old savegame" );
      options.push_back( "" );
      options.push_back( "* Exit" ); 
    
      Selection = Menu( options, true, 2 );
    and try a

    Code:
    system("cls");
    before it. And it shouldn't work. As I said, this has been bugging me for AGES! Any thoughts would be appreciated.


    EDIT - It's meant for a defaulted white background. So if it's black swap the BLACK and BRIGHTWHITE integers I guess
    Last edited by Ken Fitlike; 06-20-2006 at 05:01 AM. Reason: moved comment to reduce horizontal extent of code

  2. #2
    The Richness... Richie T's Avatar
    Join Date
    Jan 2006
    Location
    Ireland
    Posts
    469
    Call GotoXY (0,0) after you call your menu and it works - don't
    know why exactly, but it does. Maybe that will point you in the
    right direction, since I don't have time to look through all that
    windows specific code.
    No No's:
    fflush (stdin); gets (); void main ();


    Goodies:
    Example of fgets (); The FAQ, C/C++ Reference


    My Gear:
    OS - Windows XP
    IDE - MS Visual C++ 2008 Express Edition


    ASCII stupid question, get a stupid ANSI

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bisection Method function value at root incorrect
    By mr_glass in forum C Programming
    Replies: 3
    Last Post: 11-10-2005, 09:10 AM
  2. Change this program so it uses function??
    By stormfront in forum C Programming
    Replies: 8
    Last Post: 11-01-2005, 08:55 AM
  3. Replies: 4
    Last Post: 06-13-2005, 09:03 AM
  4. Replies: 5
    Last Post: 02-08-2003, 07:42 PM
  5. qt help
    By Unregistered in forum Linux Programming
    Replies: 1
    Last Post: 04-20-2002, 09:51 AM