Solved

VC++ Console Application (gotoxy, text colors, function keys)

Posted on 2001-06-02
16
979 Views
Last Modified: 2009-12-16
i'm using vc++ and working on a console program. how do i display text to certain x and y coordinates? how can i change the font colors?

also, how do i accept inputs from function keys? i need something really simple -- perhaps a loop until a function key (or any other keyboard key) is pressed. i don't need an event driven program, just something quick and simple.
0
Comment
Question by:kiphughes
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 4
  • 2
  • +2
16 Comments
 
LVL 30

Expert Comment

by:Axter
ID: 6149756
For input from the function key, you can use getch() function.
When getch() returns a zero, that means the following key is an extended key.
0
 
LVL 2

Expert Comment

by:abesoft
ID: 6149775
Mostly, you'll want to use WriteConsoleOutputCharacter,
SetConsoleTextAttribute, and maybe WriteConsoleOutputAttribute.

I'll let you read up the online doc's yourself.  Ask if anything is still unclear.

Hope this helps....
Gene
0
 
LVL 2

Expert Comment

by:smitty1276
ID: 6149820
Copy and paste this into a file and you can use these functions...  You may want to read the docs on ConsoleScreenBuffers to learn more about input and output, but these will get you started.
------------------------------------------------
HANDLE scr;

void print( char *text )
{
  char buf[1024];
  strcpy(buf, text);
  DWORD num;
  WriteConsole( scr, buf, strlen(text), &num, 0);
}

void setPos( short x, short y )
{
  COORD pos = { y, x };
  SetConsoleCursorPosition(scr, pos);
}

//may not be the most effective way, but it works...
void cls(void)
{
  CloseHandle(scr);
  scr = CreateConsoleScreenBuffer( GENERIC_READ |
       GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
       0, CONSOLE_TEXTMODE_BUFFER, 0 );
  SetConsoleActiveScreenBuffer( scr );
}

void color( WORD attr )
{
  SetConsoleTextAttribute(scr, attr);
}

void conInit( void )
{
  scr = CreateConsoleScreenBuffer( GENERIC_READ |
       GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
       0, CONSOLE_TEXTMODE_BUFFER, 0 );
  SetConsoleActiveScreenBuffer( scr );
}
------------------------------------------------
At the beginning of your program, can conInit().
Then you can use the functions...

For the colors you might want to use these...
I don't know if the color names are correct or not... I just did this once to play with console screen buffers.

Ex: color(ORANGE | BPURPLE); would set the color to orange on a purple background.

#define WHITE        FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN
#define PURPLE       FOREGROUND_RED | FOREGROUND_BLUE
#define AQUA         FOREGROUND_GREEN | FOREGROUND_BLUE
#define BLUE         FOREGROUND_BLUE
#define RED          FOREGROUND_RED
#define GREEN        FOREGROUND_GREEN
#define ORANGE       FOREGROUND_RED | FOREGROUND_GREEN
#define BORANGE      BACKGROUND_RED | BACKGROUND_GREEN
#define BWHITE       BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN
#define BPURPLE      BACKGROUND_RED | BACKGROUND_BLUE
#define BAQUA        BACKGROUND_GREEN | BACKGROUND_BLUE
#define BBLUE        BACKGROUND_BLUE
#define BRED         BACKGROUND_RED
#define BGREEN       BACKGROUND_GREEN
#define BI           BACKGROUND_INTENSITY
#define FI           FOREGROUND_INTENSITY
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:kiphughes
ID: 6150018
axter, thanx for the input. i figured out how to use getch().

smitty1276, i tried cutting and pasting ur code. i can't seem to get it to work. i'm not too sure how this HANDLE thing works.
0
 
LVL 1

Author Comment

by:kiphughes
ID: 6150019
btw, i've looked at the msdn online library and couldn't find a sample code that could help me.
0
 

Expert Comment

by:mohsiniiui
ID: 6151446
The following code may solve ur problem...

while (true)
{
if (getch() == 0)
{
    char ch = getch();

    switch(ch)
    {
    case 59:         // replace 59 with the code of function key u want to check, 59 is code of F1 key,
     // write appropriate code for that function key here
    break;
    case 60:
       .
       .
       .
    }
}
}

u can find the code of ur required function key from the following code.

this small program will also clear that how to use function keys, Axter has told u this thing but it may be more clear from this code...

//////////////////////////////
#include <conio.h>
#include <iostream.h>

void  main()
{
      if (getch()==0); // ignore first byte which is 0
                       // for function keys
      int c = getch();
      cout <<c;
}

//////////////////////////////

run this program and press any function key, it'll tell you the code for that key.

Enjoy........ it's quick and simple.
0
 
LVL 1

Author Comment

by:kiphughes
ID: 6151520
mohsiniiui, as i have already mentioned, i figured out how to use getch(). however, i just realize something odd:

#include <iostream>
using namespace::std;
#include <conio.h>
#include <ctype.h>

void main()
{
     int ch1 = 0, ch2 = 0;
     
     cout << "press any key (this is using getch()): ";
     ch1 = getch();
     cout << endl << "the ascii value of key pressed is " << ch1 << endl;

     cout << "press any key (this is using cin): ";
     cin >> ch2;          // this displays what key was pressed in the getch()
}

how do i prevent displaying what key was pressed in the getch() function?

the sample code i was having trouble finding was in reference to what abesoft and smitty1276 posted.

thanx.
0
 
LVL 2

Expert Comment

by:smitty1276
ID: 6154806
for the HANDLE to work, you must include windows.h.  ConsoleScreenBuffer and HANDLE, etc, etc, all require windows.h.

Try it again, and it should work.
0
 
LVL 1

Author Comment

by:kiphughes
ID: 6155102
thanx smitty1276. after some research, i found out that i need to include windows.h.

does anyone have any input regarding this:

#include <iostream>
using namespace::std;
#include <conio.h>
#include <ctype.h>

void main()
{
    int ch1 = 0, ch2 = 0;
   
    cout << "press any key (this is using getch()): ";
    ch1 = getch();
    cout << endl << "the ascii value of key pressed is " << ch1 << endl;

    cout << "press any key (this is using cin): ";
    cin >> ch2;          // this displays what key was pressed in the getch()
}

how do i prevent displaying what key was pressed in the getch() function?
0
 
LVL 1

Author Comment

by:kiphughes
ID: 6155149
smitty1276,

i've modified ur code a little. i'm trying to turn it into a class. i'm having some problems -- i don't know where to put "HANDLE scr." please take a look.

// console.h
#ifndef CONSOLE_H
#define CONSOLE_H

#include <windows.h>

class console
{
public:
     void cls       (void);
     void print     (char *text);
     void gotoxy    (short x, short y);
     void fontColor (WORD attr);
};
#endif

// console.cpp
#include "console.h"

void cls(void)
{
     CloseHandle(scr);
     scr = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CONSOLE_TEXTMODE_BUFFER, 0 );
     SetConsoleActiveScreenBuffer( scr );
}

void print(char *text)
{
     char buf[1024];
     strcpy(buf, text);
     DWORD num;
     WriteConsole( scr, buf, strlen(text), &num, 0);
}

void gotoxy(short x, short y)
{
     COORD pos = { y, x };
     SetConsoleCursorPosition(scr, pos);
}

void color(WORD attr)
{
     SetConsoleTextAttribute(scr, attr);
}

// consoleMain.cpp
#include "console.h"

void main()
{
     console A;
     A.gotoxy(5,5);
     A.fontColor(FOREGROUND_RED);
     A.print("This is a test");
     A.cls();
}
0
 

Expert Comment

by:mohsiniiui
ID: 6155226
modify ur code as below and check it.

void main()
{
   int ch1 = 0, ch2 = 0;
   
   cout << "press any key (this is using getch()): ";

//////////////my code//////
   if (getch()==0) ;  // ignore if zero
//////////////////////////
   ch1 = getch();
   cout << endl << "the ascii value of key pressed is " << ch1 << endl;

   cout << "press any key (this is using cin): ";
   cin >> ch2;          // this displays what key was pressed in the getch()
}

function keys send two bytes if pressed in response to getch(), they r called extended characters, first byte is always zero for function keys, if u recieve 0 in response to getch(), it means that any function key (extended character) is pressed. the next byte u'll recieve in the next getch() instruction will be the ascii code for that key.

0
 
LVL 2

Expert Comment

by:smitty1276
ID: 6157883
I would place HANDLE scr as a private data member of the class.

class console
{
public:
    void cls       (void);
    void print     (char *text);
    void gotoxy    (short x, short y);
    void fontColor (WORD attr);
private:
    HANDLE scr;
};

-----------------------------------------------------------
Also, if your mixing console IO functions ( getch() )with iostream.h it can cause some annoying problems (like leaving a char in the buffer).

I've always found that inserting
  cin.ignore(1);
after the call to getch() generally fixes the problem.
0
 
LVL 2

Accepted Solution

by:
smitty1276 earned 100 total points
ID: 6157895
In your console class you need a constructor to do all of the initialization.  Just use the conInit() function that I included.  You or the class must call that before any of the functions work properly.

Also, don't forget to use the scope operator in your method implementations in console.cpp... Like so...

void console::cls(void)
{
  ...  
}

void console::print(char *text)
{
   ...
}

etc.

0
 
LVL 1

Author Comment

by:kiphughes
ID: 6158056
smitty1276,

i've already tried tried HANDLE scr in the class' private; still had problems. this is what it looks like when i do it that way:

// console.h
#ifndef CONSOLE_H
#define CONSOLE_H

#include <windows.h>

class console
{
public:
     console();
     void conInit   (void);
     void cls       (void);
     void print     (char *text);
     void gotoxy    (short x, short y);
     void fontColor (WORD attr);
private:
     HANDLE scr;
};

#endif

// console.cpp
#include "console.h"

console::console()
{
     conInit();
}

void conInit(void)
{
     scr = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CONSOLE_TEXTMODE_BUFFER, 0 );
     SetConsoleActiveScreenBuffer( scr );
}

void cls(void)
{
     CloseHandle(scr);
     scr = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CONSOLE_TEXTMODE_BUFFER, 0 );
     SetConsoleActiveScreenBuffer( scr );
}

void print(char *text)
{
     char buf[1024];
     strcpy(buf, text);
     DWORD num;
     WriteConsole( scr, buf, strlen(text), &num, 0);
}

void gotoxy(short x, short y)
{
     COORD pos = { y, x };
     SetConsoleCursorPosition(scr, pos);
}

void color(WORD attr)
{
     SetConsoleTextAttribute(scr, attr);
}

// consoleMain.cpp
#include "console.h"

void main()
{
     console A;
     A.conInit();
     A.gotoxy(5,5);
     A.fontColor(FOREGROUND_RED);
     A.print("This is a test");
     A.cls();
}

this is the error i get:
Compiling...
console.cpp
C:\WINDOWS\Desktop\Old\console.cpp(10) : error C2065: 'scr' : undeclared identifier
C:\WINDOWS\Desktop\Old\console.cpp(10) : error C2440: '=' : cannot convert from 'void *' to 'int'
        This conversion requires a reinterpret_cast, a C-style cast or function-style cast
C:\WINDOWS\Desktop\Old\console.cpp(17) : error C2440: '=' : cannot convert from 'void *' to 'int'
        This conversion requires a reinterpret_cast, a C-style cast or function-style cast
Error executing cl.exe.

consoleMain.exe - 3 error(s), 0 warning(s)
0
 
LVL 1

Author Comment

by:kiphughes
ID: 6158426
oops, i missed the scope operators like u said. everything ok for now. thanks smitty1276.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

630 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question