Click here to Skip to main content
15,878,959 members
Articles / Programming Languages / C++

Handling Mouse Events and Simulating Push Buttons and List Boxes in a Win32 Console

Rate me:
Please Sign up or sign in to vote.
4.21/5 (13 votes)
4 Jun 2010CPOL4 min read 51.5K   1.3K   28   7
Handling mouse events and simulating push buttons and list boxes in a Win32 Console
Image 1

Designing apps in a Win32 Console is an adventure in itself. There exists no user interface libraries, push buttons, list boxes, and so on. This article will demonstrate how to simulate push buttons and list boxes and how to handle mouse events.

In a Win32 console, a push button can be simulated by first defining a rectangular region using the x and y coordinates and then drawing a button image above that rectangular region. And using an if statement, when the mouse is above the defined rectangular x and y region and a mouse button is pressed and released, you can pretty much simulate the behavior of the push buttons in Windows.

And the same applies to list boxes. You define a rectangular region using the x and y coordinates and then you draw a list box above that rectangular region and add an if statement. But before we begin, let's talk about a header file called cMichaelJanssonTextMode.h.

The C Header File cMichaelJanssonTextMode.h contains the functions that are of outmost importance for the application to be able to position the cursor and text characters in the correct x and y location. Also included in the file textmode.h are the functions to draw simple dialogs, draw lines, plot points and of course set a text character's color.

Functions in cMichaelJanssonTextMode.h:

delay()         delays x milliseconds
gotoxy()        Goes to position on 80x25 console screen
setcolor()      Changes text and background color
clrbox()        draws colored box without frames
box()           draws framed box
gotoxy() only works with printf(), cprintf() and not cout<

The gotoxy(int x, int y) Method

The gotoxy(int x, int y) event is called upon to set the cursor at a specific x and y location.

C++
void gotoxy(int x, int y)
{
    COORD coord;
    coord.X = x; coord.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
	return;
}

The setcolor(WORD color) Method

The setcolor(WORD color) event is called upon to set the color of text characters.

C++
void setcolor(WORD color)
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),color);
	return;
}

The clrscr() Method

The clrscr() event is called upon to clear the screen or to fill the screen with a specific color.

C++
void clrscr()
{
    COORD coordScreen = { 0, 0 };
    DWORD cCharsWritten;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    DWORD dwConSize;
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    GetConsoleScreenBufferInfo(hConsole, &csbi);
    dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
    FillConsoleOutputCharacter(hConsole, TEXT(' '), 
		dwConSize, coordScreen, &cCharsWritten);
    GetConsoleScreenBufferInfo(hConsole, &csbi);
    FillConsoleOutputAttribute(hConsole, csbi.wAttributes, 
		dwConSize, coordScreen, &cCharsWritten);
    SetConsoleCursorPosition(hConsole, coordScreen);
	return;
}  

Handling Mouse Events in a Win32 Console

For our application to work, we will have to devise a method in which we will process events. The Console Input Buffer is a queue of input event records and when a console window has the keyboard focus, the console formats each input events like keys being pressed, mouse buttons being clicked or, mouse being moved as an input record and it places in the console's input buffer so that applications can access the records.

Let us look at an example:

C++
 HANDLE handleIn;
 HANDLE handleOut;
 COORD KeyWhere;
 COORD MouseWhere;
 COORD EndWhere;
 INPUT_RECORD recordIn;
 DWORD NumRead;

 handleIn = GetStdHandle(STD_INPUT_HANDLE);
 handleOut = GetStdHandle(STD_OUTPUT_HANDLE);


 while (true)
 {
     ReadConsoleInput(handleIn, &recordIn, 1, &NumRead);

     switch (recordIn.EventType)
     {
     case KEY_EVENT:
                // Do stuff
         break;

     case MOUSE_EVENT:
                // Do stuff
         break;
     }
}

Keyboard Events

When any key is pressed or released, keyboard events are generated and placed in a KEY_EVENT_RECORD structure.

Mouse Events

Mouse events are generated and placed in a MOUSE_EVENT_RECORD structure whenever the user moves the mouse or presses or releases one of the mouse buttons.

And now the application itself.

The project files consistents are:

  • cMichaelJanssonJokeConsole_main.cpp -The main file
  • cMichaelJanssonJokeConsole.cpp - The class definition and method body file
  • cMichaelJanssonJokeConsole.h - The class declaration file
  • cMichaelJanssonTextMode.h - The Console textmode graphics file

Simulated Listboxes

Fast fowarding a bit, we've simulated listboxes by drawing a listbox and defining a set of coordinates on which if a user clicks, listbox action should occur. So if a user clicks on "up", the file list will proceed to scroll up and likewise when down is clicked, the file list will scroll downwards. Now we are ready to process user inputs through mouse events.

C++
//  A SIMULATED LISTBOX IN A CONSOLE WINDOW

if ((mouseX>38) && (mouseX<42) && (mouseY==23))
{
	FileScrollDown();
	currentFile=fileListSelect+fileListScroll;
	unreadFiles=maxFiles-currentFile;
	putFilesList();

	clrbox(39,23,42,24,15);
	gotoxy(40,23);printf(">");
	delay(200);
	clrbox(39,23,42,24,240);
	gotoxy(40,23);printf(">");
}

The cMichaelJanssonJokeConsole::fileSelected() Method

The cMichaelJanssonJokeConsole::fileSelected() method is called upon when the left button is pressed down while above this listBox.
Once the index has changed, this method is called upon and it represents the user changing from one textfile containing jokes to another.

C++
void cMichaelJanssonJokeConsole::fileSelected()
{
   putFilesList();
   JokeFile=fileListSelect+fileListScroll;
   loadFile(files[JokeFile].name);
   putLinesList();
   updateStatus();
   displayJokeLine();
}

The cMichaelJanssonJokeConsole::loadFile(char *file) Method

The cMichaelJanssonJokeConsole::loadFile(char *file) method is called upon to load jokes from a textfile to a char array.

C++
void cMichaelJanssonJokeConsole::loadFile(char *file)
{
	char buffer[8192];
	ifstream in;

    for (int ii=0;ii<200;ii++) 	for (int jj=0;jj<1024;jj++)	line[ii][jj]=' ';

    unreadLines=0;
	in.open(file);
    in.getline(JokeTitle,40);

    //clrbox(0,2,80,15,0);
	clrbox(0,2,80,15,0);
    clrbox(1,1,79,2,224);
	gotoxy(2,1);printf("Random Jokes:");
	setcolor(224);gotoxy(25,1);printf("%s        ",JokeTitle);
	clrbox(1,2,79,15,31);

	if (!in.is_open())
	{
		cout << "Error opening file";
		exit(1);
	}
	int i=0;
	while (!(in.eof()))
	{
		in.getline(buffer,255);
	    strcpy(line[i],buffer);
		//cout<<line[i]><<"\n";
		i++;
	}
	maxLines=i;
	createRandomLines();
	in.close();
}

The cMichaelJanssonJokeConsole::lineSelected() Method

The cMichaelJanssonJokeConsole::lineSelected() method is called upon when the left button is pressed down while above this listBox.
Once the index has changed, this method is called upon and it represents the user changing from one line of joke to another.

C++
void cMichaelJanssonJokeConsole::lineSelected()
{
   putLinesList();
   JokeLine=lineListSelect+lineListScroll;
   displayJokeLine();
   updateStatus();
}

The cMichaelJanssonJokeConsole::displayJokeLine() Method

Finally the cMichaelJanssonJokeConsole::displayJokeLine() method is called upon to display one line of joke from a string array onto the console window.

C++
void cMichaelJanssonJokeConsole::displayJokeLine()
{
	int pos=0,x=0,y=0;

	clrbox(1,2,79,15,31);
	setcolor(31);
	while((line[JokeLine][pos]!='\0') &&(pos<700))
	{
          gotoxy(x+2,y+3);printf("%c",line[JokeLine][pos]);
		  pos++;
		  x++;
		  if ((x>65) && (line[JokeLine][pos]==' '))
		  {
			  x=0 ;
			  y++;
		  }
	}
} 

The Main File

The file cMichaelJanssonJokeConsole_main.cpp is where we create an instance for our class and run our application.

C++
#include "cMichaelJanssonJokeConsole.h"

int main()
{
  cMichaelJanssonJokeConsole  *MichaelJanssonJokeConsole = 
				new cMichaelJanssonJokeConsole(1);
  return 0;
}

And that is how easy it is to create a Joke Jukebox in Win32 Console application.

Thanks for reading.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Sweden Sweden
About me:
I attended programming college and I have a degree in three most famous and successful programming languages. C/C++, Visual Basic and Java. So i know i can code. And there is a diploma hanging on my wall to prove it.
.
I am a professional, I am paid tons of cash to teach or do software development. I am roughly 30 years old .

I hold lectures in programming. I have also coached students in C++, Java and Visual basic.

In my spare time i do enjoy developing computer games, and i am developing a rather simple flight simulator game
in the c++ programming language using the openGL graphics libray.

I've written hundreds of thousands of code syntax lines for small simple applications and games.

Comments and Discussions

 
GeneralMy vote of 4 Pin
jbaolee4-Sep-10 14:10
jbaolee4-Sep-10 14:10 
GeneralExisting library for UIs in console mode Pin
sgllama31-Aug-10 22:43
sgllama31-Aug-10 22:43 
GeneralMy vote of 1 Pin
xliqz4-Jun-10 5:13
xliqz4-Jun-10 5:13 
GeneralMy vote of 1 Pin
eds2-Jun-10 8:44
eds2-Jun-10 8:44 
QuestionSo many Articles in a Single day? Pin
Kunal Chowdhury «IN»30-May-10 1:41
professionalKunal Chowdhury «IN»30-May-10 1:41 
GeneralArticle writing suggestion [modified] Pin
David MacDermot14-May-10 8:31
David MacDermot14-May-10 8:31 
I noticed that you have posted quite a few of these articles over a short period of time. Several of them contain introductions that are rather uninspiring. Take this line for instance:
TopCoder23 wrote:
Designing apps in Win32 Console Mode is pretty boring. There exists no user interface libraries.
Dead | X| Why then should I be interested in reading this? A well thought out introduction will encourage the reader to take the time to consider what you have to say and share. The fact of the matter is that this is an interesting topic and should be introduced as such. I might suggest the following as a better introduction: Roll eyes | :rolleyes:
Not all that long ago, before the recent era of lightning fast workstations with gigabites of storage and lots of cheap ram, applications had to be lean, mean, and... cool. How did the genius coders of yesterday make DOS applications cool and user friendly? In this article I'm going to show you how...


modified on Friday, May 14, 2010 2:42 PM

GeneralRe: Got it. Pin
Software_Developer18-May-10 9:11
Software_Developer18-May-10 9:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.