Solved

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

Posted on 2001-06-02
16
937 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
  • 7
  • 4
  • 2
  • +2
16 Comments
 
LVL 30

Expert Comment

by:Axter
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 1

Author Comment

by:kiphughes
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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:abesoft
Comment Utility
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 2

Expert Comment

by:smitty1276
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
oops, i missed the scope operators like u said. everything ok for now. thanks smitty1276.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
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 learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

771 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now