Dla pojedyńczej sesji - DirectInput, dla wszystkich sesji trzeba czytać bezpośrednio z \Device\KeyboardClass0.
#define DIRECTINPUT_VERSION 0x0500
#pragma comment(lib, "dinput.lib")
#include <dinput.h>
DWORD __stdcall HotkeyThread(HANDLE hExitEvent)
{
BOOL fContinueLoop = TRUE;
IDirectInput *dinput;
IDirectInputDevice *keyboard;
char keys[256];
HANDLE hEvents[2];
DWORD index;
HWND hwnd = GetForegroundWindow();
hEvents[0] = CreateEvent(0,0,0,0);
hEvents[1] = hExitEvent;
if (!DirectInputCreate(GetModuleHandle(0), 0x0500, &dinput, 0))
{
if (!dinput->CreateDevice(GUID_SysKeyboard, &keyboard, 0))
{
keyboard->SetDataFormat(&c_dfDIKeyboard);
keyboard->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE);
keyboard->SetEventNotification(hEvents[0]);
keyboard->Acquire();
while (fContinueLoop)
{
// main loop
index = WaitForMultipleObjects(1, hEvents, FALSE, INFINITE);
if (!index)
{
// jakiś klawisz wciśnięto
keyboard->GetDeviceState(sizeof(keys), keys);
if ((keys[DIK_LCONTROL] & 0x80)
&& (keys[DIK_LMENU] & 0x80) // left alt
&& (keys[DIK_LSHIFT] & 0x80)
&& (keys[DIK_K] & 0x80))
{
// hotkey action
MessageBeep(MB_ICONHAND);
}
}
else if (index == 1)
{
fContinueLoop = false;
}
}
keyboard->Unacquire();
keyboard->Release();
}
dinput->Release();
}
CloseHandle(hEvents[0]);
return 0;
}
Jeżeli masz jakieś okno w programie, to powyższą funkcję uruchamiasz w osobnym wątku:
int __stdcall WinMain(HINSTANCE hinstance,HINSTANCE,LPSTR,int)
{
HANDLE hExitEvent = CreateEvent(0,0,0,0);
DWORD id;
HANDLE hThread = CreateThread(0,0, HotkeyThread, (void*)hExitEvent, 0, &id);
// main loop here
// while (GetMessage())
MessageBox(0, "wciśnij Ctrl+Alt+Shift+K", "", 0);
CloseHandle(hExitEvent); // przerywa while w HotkeyThread
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
return 0;
}