Jump to content
  • Advertisement

Archived

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

OrigamiMan64

Regarding Win32 Input...

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
I have tied your example, though, instead use ReadConsole Events.
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 this post


Link to post
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 this post


Link to post
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]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!