Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

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

Posted on 2001-06-02
16
Medium Priority
?
993 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
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 400 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

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

Question has a verified solution.

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

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
Article by: evilrix
Looking for a way to avoid searching through large data sets for data that doesn't exist? A Bloom Filter might be what you need. This data structure is a probabilistic filter that allows you to avoid unnecessary searches when you know the data defin…
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.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

916 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