Hello guys. I'm capturing the keyboard input using the class below. And I have no problem doing that.
What I wanna ask is how to understand if a key is pressed, released or being pressed.

Let me explain more...
When ever any key is pressed the member function GetData() returns the virtual key code of the key which is pressed. But, if the user keeps pressing the key, the WM_INPUT message is sent periodically. The frequence of it is set at the control panel of Windows. And also, when the user releases the key, again the WM_INPUT is sent with the same virtual key code.

For example,
When user hits the escape key, 27 returns from GetData() twice. One for pressing, one for releasing.

And, when the 27 returns for the second time from GetData(), I want to find out if the key is still being pressed or the key is just released.

Waiting for your replies...

class HIDInput
{
	private:
	RAWINPUTDEVICE Rid;
	public:
	LPARAM hRawInput;
	HWND hTargetWnd;
	USHORT LastKey;
	
	void Register(void)
	{
		Rid.usUsagePage = 0x01; 
		Rid.usUsage		= 0x06; 
		Rid.dwFlags		= RIDEV_INPUTSINK;
		Rid.hwndTarget		= hTargetWnd;
		if (RegisterRawInputDevices(&Rid, 1, sizeof(Rid)) == FALSE) DebugTest("Error registering input");
	}
	unsigned int GetData(void)
	{
		UINT cbSize;
		GetRawInputData((HRAWINPUT)	hRawInput,
						(UINT)		RID_INPUT,
						(LPVOID)	NULL,
						(PUINT)		&cbSize,
						(UINT)		sizeof(RAWINPUTHEADER));
		LPBYTE lpbBuffer = new BYTE[cbSize];
	
		GetRawInputData((HRAWINPUT)	hRawInput,
						(UINT)		RID_INPUT,
						(LPVOID)	lpbBuffer,
						(PUINT)		&cbSize,
						(UINT)		sizeof(RAWINPUTHEADER));
	
		RAWINPUT * pRawInput = (RAWINPUT *) lpbBuffer;
		if (pRawInput->header.dwType == RIM_TYPEKEYBOARD)
			return LastKey = pRawInput->data.keyboard.VKey;	//This one never returns 0
		else
			return 0;					//Error

	}

Recommended Answers

All 5 Replies

use the

pRawInput->data.keyboard.Message

field. It returns 0x101 when released and 0x100 ( i think it is 0x100, check the documentation just in case ) when it is pressed. You can use an if condition to check the two.

something like

if ( pRawInput->data.keyboard.Message = 0x100 ) // Pressed
{
         // Do processing
}
else
{
      //Ignore
}

As for the user keeping on pressing, Maybe checking for consecutive 0x100 values with the same VKey will do the trick.

Windows sends the key twice. First time it sends the key with a WM_KEYDOWN, and then with a WM_KEYUP message. As a special case, it sends WM_SYSKEYDOWN and WM_SYSKEYUP when ALT key is pressed. No problem so far.

But when either Windows, insert, delete, home, end, pageup or pagedown key is pressed, WM_KEYDOWN and WM_KEYUP messages are sent twice. I mean, 2x2=4 times.
So, what about this situation?

But when either Windows, insert, delete, home, end, pageup or pagedown key is pressed, WM_KEYDOWN and WM_KEYUP messages are sent twice. I mean, 2x2=4 times.
So, what about this situation?

All these Keys are Extended Keys. If you read the documentation for WM_KEYDOWN, WM_KEYUP ..., you will see that the 25th bit of the lParam value of the respective message tells you if the key is extended or not. You will be able to check it with an operation like this in the Windows Message loop.

case WM_KEYDOWN:
      if ( ( LOWORD( lParam) & 0x01000000 ) == 0 ) // NOt an extended key
      { 
             // Do Processing
      }
      else //Extended Key
      {
            //....
       }

But I cannot use WM_KEYDOWN or something else, because I already use WM_INPUT. I recieve the input with WM_INPUT, not with WM_KEYDOWN.

When user hits ALT key, WM_SYSKEYDOWN, WM_KEYUP, WM_SYSKEYDOWN are sent. But, WM_SYSKEYUP is not sent.
Why? Why does WM_SYSKEYDOWN is sent twice?

But I cannot use WM_KEYDOWN or something else, because I already use WM_INPUT. I recieve the input with WM_INPUT, not with WM_KEYDOWN.

When user hits ALT key, WM_SYSKEYDOWN, WM_KEYUP, WM_SYSKEYDOWN are sent. But, WM_SYSKEYUP is not sent.
Why?

WM_SYSKEYUP Notification

The WM_SYSKEYUP message is posted to the window with the keyboard focus when the user releases a key that was pressed while the ALT key was held down. It also occurs when no window currently has the keyboard focus; in this case, the WM_SYSKEYUP message is sent to the active window. The window that receives the message can distinguish between these two contexts by checking the context code in the lParam parameter.

Why does WM_SYSKEYDOWN is sent twice?

I ran a piece of code and I didnt see this behaviour when I pressed the ALT key. It sent only the WM_SYSKEYDOWN and the WM_KEYUP messages.

ALT Key
 Kbd: make=0038 Flags:0002 Reserved:0000 ExtraInformation:00000000, msg=0104 VK=0012 
 Kbd: make=0038 Flags:0003 Reserved:0000 ExtraInformation:00000000, msg=0101 VK=0012

But I cannot use WM_KEYDOWN or something else, because I already use WM_INPUT. I recieve the input with WM_INPUT, not with WM_KEYDOWN.

Here is what I got for some keys.

DELETE Key
 Kbd: make=002a Flags:0002 Reserved:0000 ExtraInformation:00000000, msg=0100 VK=00ff 
 Kbd: make=0053 Flags:0002 Reserved:0000 ExtraInformation:00000000, msg=0100 VK=002e 
 Kbd: make=0053 Flags:0003 Reserved:0000 ExtraInformation:00000000, msg=0101 VK=002e 
 Kbd: make=002a Flags:0003 Reserved:0000 ExtraInformation:00000000, msg=0101 VK=00ff 
 'K' Key
 Kbd: make=0025 Flags:0000 Reserved:0000 ExtraInformation:00000000, msg=0100 VK=004b 
 Kbd: make=0025 Flags:0001 Reserved:0000 ExtraInformation:00000000, msg=0101 VK=004b

You can see that VK=00FF for the one of the KeyUp and key Down pairs of the Extended keys. I dont know if this is universal for all keyboards but for now you can try using it.If the 0xFF comparison does not work I think the values for Make or Flags must be sending that information, but couldn't find any documentation on it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.