I wrote down a program code that recognizes the keyboard as an HID device and gets input (the key pressed) from it. Then displays it on an edit control.

Here is the code :

#include "stdafx.h"
#define _WIN32_WINNT 0x0502
#include <windows.h>
#include "HID Input.h"
#define MAX_LOADSTRING 100

RAWINPUTDEVICE Rid;
USHORT usVKey;
HWND hEdit;

LONG nWidth=200, nHeight=200;
HWND hWnd;
MSG Msg;
LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);

VOID RegisterInput(VOID);
BOOL GetHIDData(LPARAM);
VOID DisplayInput(VOID);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil)
{
    char szClassName[] = "WindowsApp";
    
    WNDCLASSEX WindowClass;
	WindowClass.cbSize			= sizeof (WNDCLASSEX);
	WindowClass.style			= CS_DBLCLKS;	
	WindowClass.lpfnWndProc		= WindowProcedure;
	WindowClass.cbClsExtra		= 0;
	WindowClass.cbWndExtra		= 0;
	WindowClass.hInstance		= hInstance;
	WindowClass.hIcon			= LoadIcon (NULL, IDI_APPLICATION);
	WindowClass.hCursor			= LoadCursor (NULL, IDC_ARROW);
	WindowClass.hbrBackground	= (HBRUSH) COLOR_BACKGROUND;
	WindowClass.lpszMenuName	= NULL;
	WindowClass.lpszClassName	= szClassName;
	WindowClass.hIconSm			= LoadIcon (NULL, IDI_APPLICATION);
	
    if (!RegisterClassEx(&WindowClass)) return 0;
    
    hWnd = CreateWindowEx(	(DWORD)		0,
							(LPCTSTR)	szClassName,
							(LPCTSTR)	"Application",
							(DWORD)		WS_MINIMIZEBOX | WS_SYSMENU,
							(int)		CW_USEDEFAULT,
							(int)		CW_USEDEFAULT,
							(int)		nWidth,
							(int)		nHeight,
							(HWND)		HWND_DESKTOP,
							(HMENU)		NULL,
							(HINSTANCE)	hInstance,
    						(LPVOID)	NULL);
    
    ShowWindow(hWnd, nFunsterStil);
	
	CreateWindowEx(			(DWORD)		NULL,
							(LPCTSTR)	"STATIC",
							(LPCTSTR)	"VKey of keyboard input :",
							(DWORD)		WS_VISIBLE | WS_CHILD,
							(int)		5,
							(int)		5,
							(int)		185,
							(int)		20,
							(HWND)		hWnd,
							(HMENU)		NULL,
							(HINSTANCE) hInstance,
							(LPVOID)	NULL);

	hEdit = CreateWindowEx(	(DWORD)		NULL,
							(LPCTSTR)	"EDIT",
							(LPCTSTR)	NULL,
							(DWORD)		WS_VISIBLE | WS_CHILD,
							(int)		5,
							(int)		35,
							(int)		50,
							(int)		20,
							(HWND)		hWnd,
							(HMENU)		NULL,
							(HINSTANCE) hInstance,
							(LPVOID)	NULL);

	RegisterInput();
	
	while (GetMessage(&Msg, NULL, 0, 0))
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
	return (INT) Msg.wParam;
}

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_INPUT:
			if (GetHIDData(lParam) == FALSE) ErrorTest("Error gethering data.");
			DisplayInput();
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc (hwnd, message, wParam, lParam);
		}
	
	return 0;
}

BOOL GetHIDData(LPARAM hRawInput)
{
	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)
	{
		usVKey = pRawInput->data.keyboard.VKey;
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
VOID RegisterInput(VOID)
{
	Rid.usUsagePage = 0x01; 
	Rid.usUsage		= 0x06; 
	Rid.dwFlags		= 0;
	if (RegisterRawInputDevices(&Rid, 1, sizeof(Rid)) == FALSE) ErrorTest("Error registering input");
}
VOID DisplayInput(VOID)
{
	CHAR szEditText[4];
	_itoa((INT) usVKey, szEditText, 10);
	SetWindowText(hEdit, szEditText);
}

The problem is, it doesn't show the virtual key code when the main program window is not active.

How can I make it work even if it is on the background or minimized?

I also attached the Visual Studio project files.

Modify your RegisterInput function as follows.

VOID RegisterInput(HWND hWnd;)
{
	Rid.usUsagePage = 0x01; 
	Rid.usUsage		= 0x06; 
	Rid.dwFlags		= RIDEV_INPUTSINK;
        Rid.hwndTarget = hWnd; // The Window Handle of your window
	if (RegisterRawInputDevices(&Rid, 1, sizeof(Rid)) == FALSE) ErrorTest("Error registering input");
}

Yes, thanks.
It works now.

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.