• ### Popular Now

• 13
• 15
• 27
• 9
• 9

#### Archived

This topic is now archived and is closed to further replies.

# Regarding Win32 Input...

This topic is 5081 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

How can I get input that distinguishes between every key on the keyboard? The GetAsyncKeyState function, which takes a virtual key code, seems to be a bit too helpful, in that it maps both enters to the same virtual key and, if the numlock is off, all of the special features under the numpad numbers get mapped to their corrispondents in the middle. This is very bad for mapping game controls. Here's a quick and dirty program that demonstrates what I mean:
#include <windows.h>
#include <cstdio>

int main (  )
{
COORD zero;
zero.X = 0;
zero.Y = 0;
while ( true )
{
SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ), zero );
for ( unsigned int i = 0; i < 256; i++ )
{
SetConsoleTextAttribute ( GetStdHandle ( STD_OUTPUT_HANDLE ), BACKGROUND_BLUE | ( ( GetAsyncKeyState ( i ) & 0x80000000 ) ? BACKGROUND_INTENSITY : 0 ) );
printf ( "%X", i%16 );
if ( i%16 == 15 )
{
printf ( "\n" );
}
}
}
return 0;
}

[Edit by Oluseyi: Because horizontal scrolling is just wrong.] please help [edited by - Oluseyi on April 13, 2004 7:36:27 PM]

##### Share on other sites
that didn't help, and in fact didnt work at all. with the following code, none of the keys ever lit up on my screen.

#include <windows.h>#include <cstdio>int main (  ){	COORD zero;	zero.X = 0;	zero.Y = 0;	BYTE state[256];	while ( true )	{		SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ), zero );		GetKeyboardState ( &state[0] );		for ( unsigned int i = 0; i < 256; i++ )		{			SetConsoleTextAttribute ( GetStdHandle ( STD_OUTPUT_HANDLE ), BACKGROUND_BLUE | ( ( state[i] & 0x80 ) ? BACKGROUND_INTENSITY : 0 ) );			printf ( "%X", i%16 );			if ( i%16 == 15 )			{				printf ( "\n" );			}		}		// make sure state is up to date by reading all input records		unsigned long num_inputs;		GetNumberOfConsoleInputEvents ( GetStdHandle ( STD_INPUT_HANDLE ), &num_inputs );		for ( num_inputs; num_inputs > 0; num_inputs-- )		{			INPUT_RECORD record;			unsigned long buf;			ReadConsoleInput ( GetStdHandle ( STD_INPUT_HANDLE ), &record, 1, &buf );		}	}	return 0;}

[edited by - origamiman64 on April 13, 2004 9:24:19 PM]

##### Share on other sites
anyone have any idea whats wrong with that code?

##### Share on other sites
Check out this thread where I posted an example:

http://www.gamedev.net/community/forums/topic.asp?topic_id=219277

Check for errors when you use GetStdHandle...

What exactly happens? Nothing at all? Not any events?

Edit: Never Mind. I didn't notice you were using GetKeyboardState. Though, you should check that for error also. If it returns false, call GetLastError.

[edited by - pjcast on April 14, 2004 10:59:13 PM]

##### Share on other sites
the program displays a 16 by 16 array of chars, and each position corrisponds to a VK code. If that VK is down it should light up. in the first, pressing either enter lights the same char and no others, so I cannot distinguish between them. In the second, nothing ever lights.

##### Share on other sites
From msdn (GetKeyboardState(..)):
quote:

An application can call this function to retrieve the current status of all the virtual keys. The status changes as a thread removes keyboard messages from its message queue. The status does not change as keyboard messages are posted to the thread's message queue, nor does it change as keyboard messages are posted to or retrieved from message queues of other threads. (Exception: Threads that are connected through AttachThreadInput share the same keyboard state.)

I also played with this, and the key status's never changed. I guess you need to use a windows message pump to have the values changed.

What you could try is that example I posted a Link to earlier. Using a combination of GetNumberOfConsoleInputEvents & ReadConsoleEvent, should do what you want. The INPUT_RECORD struct, which contains a KEY_EVENT_RECORD on a key event, should contain all the info you need.

[edited by - pjcast on April 15, 2004 1:23:15 AM]

##### Share on other sites
Though, I am on a labtop, and do not have the extended keys to test for a difference. Though, I used the virtual keycode structure member, if that doesn't work for you, perhaps the scan code structure member of KEY_EVENT might produce what you want.

#include "stdafx.h"#include <windows.h>#include <stdio.h> DWORD main(VOID) {     HANDLE hStdin, hStdOut;    DWORD cNumRead, fdwMode, fdwSaveOldMode, i;     INPUT_RECORD irInBuf[128]; 	DWORD err;	BYTE state[257];	COORD zero;		zero.X = 0;		zero.Y = 0;		memset(state, 0, 257);     // Get the standard input handle.      hStdin = GetStdHandle(STD_INPUT_HANDLE); 	hStdOut= GetStdHandle(STD_OUTPUT_HANDLE);      // Save the current input mode, to be restored on exit.     GetConsoleMode(hStdin, &fdwSaveOldMode);    // Enable the window and mouse input events.     fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;// | ENABLE_ECHO_INPUT;     SetConsoleMode(hStdin, fdwMode);     // Loop to read and handle the input events.      while (1)     {          // Wait for the events. 		GetNumberOfConsoleInputEvents( hStdin, &cNumRead );		if( cNumRead > 0 )		{			ReadConsoleInput(                 hStdin,      // input buffer handle                 irInBuf,     // buffer to read into                 128,         // size of read buffer                 &cNumRead);  // number of records read  			for (i = 0; i < cNumRead; i++) 			{				switch(irInBuf[i].EventType) 				{	 					case KEY_EVENT: // keyboard input 						if(irInBuf[i].Event.KeyEvent.bKeyDown)							//Pressed							state[ irInBuf[i].Event.KeyEvent.wVirtualKeyCode ] = 0x80;						else							//Released							state[ irInBuf[i].Event.KeyEvent.wVirtualKeyCode ] = 0x01;												break;  					case MOUSE_EVENT: // mouse input 						break; 	                case WINDOW_BUFFER_SIZE_EVENT: // scrn buf. resizing 				        break; 					case FOCUS_EVENT:  // disregard focus events 						break;	                case MENU_EVENT:   // disregard menu events 		                break; 	                default: 			            break; 				} 			}		} //End if			SetConsoleCursorPosition ( hStdOut, zero );						for ( unsigned int i = 0; i < 256; i++ )				{						SetConsoleTextAttribute ( hStdOut, BACKGROUND_BLUE | 									  ((state[i] & 0x80) ? BACKGROUND_INTENSITY : 0) );						printf ( "%X", i%16 );						if ( i%16 == 15 )							printf ( "\n" );					}		    } //End while      return 0; }

[edited by - pjcast on April 15, 2004 1:59:01 AM]

##### Share on other sites
if you look at the code I posted, you will see that I am also reading out all available input with the same methods you demonstrated ( GetNumberOfConsoleInputEvents and ReadConsoleInput ). It didn''t help in updating the keyboard state. The original code at the top that uses the virtual key member of the input struct works fine, the only problem I have with it is the definition of a virtual key. I was hoping there would be two separate values, like VK_RETURN and VK_NUMPAD_RETURN, but they both use the same value. Perhaps there is an alternative source of input I could use instead of that declared in wincon?

##### Share on other sites
Actually, in the first example you posted, you used GetAsyncKeyState and in the other example you used GetKeyBoardState. I used niether of those to fill the buffer. I read directly from the input_record structure after an event.

Though, there may be little difference. Like I said, I'm on a laptop right now, and cannot test extended keys. Though, if the Virtual Key Code does not differentiate... Perhaps the Virtual Scan Code will. Did you try to check that variable:

state[ irInBuf[ i ].Event.KeyEvent.wVirtualScanCode

According to MSDN, wVirtualScanCode should record results in a device-dependent mannor (as opposed to virtual key code which is device-independent) straight from the keyoard.

There should be a way for you to turn the num-lock key on yourself, and if someone tries to turn it off, you just reset it. Sounds kinda hackish though. Maybe DirectInput can help you out here.

[edited by - pjcast on April 15, 2004 10:02:10 PM]