Hello Everyone!
That's my first post on this forum and I'd like to greet Everyone

I got a question about getting the last key pressed without stopping the programm. I know that getchar(), cin, getch() commands don't allow to do that. Have You any idea how to solve this problem?

I 'd like to do sth like that:

while(play){
char a;
a=get_last_key_without_stopping_the_programm(); // Do You know a function similiar to that?
switch(a){
case: 'W' :
do_sth();
break;
case 'S' :
do_sth_else();
break;
default:
do_default();
break;
}
a='*';
}

8
Contributors
10
Replies
14
Views
12 Years
Discussion Span
Last Post by zeroliken

>I know that getchar(), cin, getch() commands don't allow to do that.
getch (and getche) does, but it isn't a standard function and won't exist on all implementations. What compiler and operating system do you use?

Well, i think i know what you mean but it may help to know what kind of program you want to make. If it's a win32 application, checking for keyboard input during a loop is easy, but if this isnt a win32 application, keyboard input can still be checked, its just a bit more complicated.

Well, i think i know what you mean but it may help to know what kind of program you want to make. If it's a win32 application, checking for keyboard input during a loop is easy, but if this isnt a win32 application, keyboard input can still be checked, its just a bit more complicated.

First post here...I found this site looking for similar information. I'm using win32, but am totally unfamilliar with the windows.h header. I currently only know standard c++. How would one go about capturing keystrokes without waiting for <return> to be pressed. If you could demonstrate a compilable snippet, I'd be grateful.

MM

Ok well, the reason why it's easy in win32 to check for keyboard input is because you can check for a window message WM_KEYDOWN. Each key has a specific virtual key code, but, you can figure that out. Heres a simple code snippet that checks for if the key pressed was the esc key. (this is compilable if you know where to put it in your program)

switch(message)
{
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE: //the virutal key code for esc
PostQuitMessage(0);
break;
}
break;
/*
rest of the window procedure
*/
}

Ok well, the reason why it's easy in win32 to check for keyboard input is because you can check for a window message WM_KEYDOWN. Each key has a specific virtual key code, but, you can figure that out. Heres a simple code snippet that checks for if the key pressed was the esc key. (this is compilable if you know where to put it in your program)

switch(message)
{
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE: //the virutal key code for esc
PostQuitMessage(0);
break;
}
break;
/*
rest of the window procedure
*/
}

Thanks for your help. I ended up doing it another way. I'm going to use something like the following. Do you see problems other than non-portability to systems that don't use ascii 13 for <return>?

#include <windows.h>
#include <string>
#include <iostream>

using namespace std;

int main(){

while (true){

cout << " Input Password: ";

cout << "\nPassword mismatch.  Try again\n";
}

system("pause");
}

CHAR buffer[1] = "";
DWORD w;
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE keyboard = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD input[1];

string pw;

while(true) {

// Process a key down input event.
if(input[0].EventType == KEY_EVENT
&& input[0].Event.KeyEvent.bKeyDown)
{

// Retrieve the character that was pressed.
buffer[0] = input[0].Event.KeyEvent.uChar.AsciiChar;

if(buffer[0] == 13){ break;}  // enter pressed
if(buffer[0] == 8){           // backspace
pw.erase(pw.size()-1, 1);
cout << "\b \b";
continue;
}

if(buffer[0] != 0) {  // 0 is function keys, shift, ctrl, etc.
cout << '*';
pw += buffer[0];
}
}
}
cout << endl;
return pw;
}

>I know that getchar(), cin, getch() commands don't allow to do that.
getch (and getche) does, but it isn't a standard function and won't exist on all implementations. What compiler and operating system do you use?

I use Linux and Windows OS both and I'd like to make an application that is compatible with both of them(or needs just a few little changes). I try to make some snake-similar game in ASII. Compiler for Windows I use is Borland c++ builder 6.0 and for Linux g++).

How would I do a similar thing using TC(required for school), which cannot use Windows.h? (Uses DOS)

About the solution given by Mango Maniac, does anyone knows how to do the same but using a Matlab mex file? I runned a modified version of his program in Visual C++ and it worked, but when I put the same code in the Matlab "mexfuction" the program compile and runs, but it doesn't respond when I press the keys. Here is the code:

#include <windows.h>
#include <string>
#include <iostream>
#include <stdio.h>
#include "C:\MATLAB7\extern\include\mex.h"

CHAR buffer[1] = "";
DWORD w;
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE keyboard = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD input[1];

void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]) {

mexPrintf("para cima");
while (1) {
if(input[0].EventType == KEY_EVENT && input[0].Event.KeyEvent.bKeyDown) {
buffer[0] = input[0].Event.KeyEvent.uChar.AsciiChar;
if(buffer[0] == 13) { break;}
if(buffer[0] == 56) {mexPrintf("para cima");}
if(buffer[0] == 50) {mexPrintf("para baixo");}
if(buffer[0] == 52) {mexPrintf("esquerda");}
if(buffer[0] == 54) {mexPrintf("direita");}

}
}
}


I'm using a windows XP, Matlab 7 and Visual C++ 6.0

Edited by pyTony: fixed formating

The advice by Warburg is a valuable hint, but the WIN32 API funcion ReadConsoleInput waits for a keypress or a mouseclick. It must be supplemented with a wait function. The following function returns zero when nothing was pressed and ASCII code when something "ASCII" was pressed. I hope that this solution really works (even in "console" applications), but nothing is 100% ...

int keytest( void )
{
CHAR ch;
DWORD dw;
HANDLE keyboard;
INPUT_RECORD input;

keyboard = GetStdHandle(STD_INPUT_HANDLE);

dw = WaitForSingleObject( keyboard, 0 );
if( dw != WAIT_OBJECT_0 )
return 0;
dw = 0;

ch = 0;
// Process a key down input event.
if( !(     input.EventType == KEY_EVENT
&& input.Event.KeyEvent.bKeyDown )  )
{
return 0;
}

// Retrieve the character that was pressed.
ch = input.Event.KeyEvent.uChar.AsciiChar;

// Function keys filtration
if( input.Event.KeyEvent.dwControlKeyState &
( LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED |
RIGHT_CTRL_PRESSED )
)
return 0;

// if( ch == 13 )
//  ...;  // enter pressed

return ch;
}

The advice by Warburg is a valuable hint, but the WIN32 API funcion ReadConsoleInput waits for a keypress or a mouseclick. It must be supplemented with a wait function. The following function returns zero when nothing was pressed and ASCII code when something "ASCII" was pressed. I hope that this solution really works (even in "console" applications), but nothing is 100% ...

int keytest( void )
{
CHAR ch;
DWORD dw;
HANDLE keyboard;
INPUT_RECORD input;

keyboard = GetStdHandle(STD_INPUT_HANDLE);

dw = WaitForSingleObject( keyboard, 0 );
if( dw != WAIT_OBJECT_0 )
return 0;
dw = 0;

ch = 0;
// Process a key down input event.
if( !(     input.EventType == KEY_EVENT
&& input.Event.KeyEvent.bKeyDown )  )
{
return 0;
}

// Retrieve the character that was pressed.
ch = input.Event.KeyEvent.uChar.AsciiChar;

// Function keys filtration
if( input.Event.KeyEvent.dwControlKeyState &
( LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED |
RIGHT_CTRL_PRESSED )
)
return 0;

// if( ch == 13 )
//  ...;  // enter pressed

return ch;
}