Napisałem kiedyś taki programik w C++ i WinAPI
#include <windows.h>
#include <strsafe.h>
HHOOK hHook;
void ShowError(LPTSTR lpszFunction);
inline void SendKey(WORD wVk)
{
static INPUT input[2] = {
{ INPUT_KEYBOARD, 0, 0, 0, 0, 0, 0 },
{ INPUT_KEYBOARD, 0, KEYEVENTF_KEYUP, 0, 0, 0, 0 } };
input[0].ki.wVk = input[1].ki.wVk = wVk;
SendInput(2, input, sizeof(input[0]));
}
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPKBDLLHOOKSTRUCT lpKey)
{
if(nCode >= 0)
{
//Alt + Q zamyka program
if((lpKey->vkCode == 'Q') && (lpKey->flags & LLKHF_ALTDOWN))
PostQuitMessage(0);
else if(lpKey->vkCode == 'P')
{
if(!(lpKey->flags & LLKHF_UP))
{
SendKey('Q');
SendKey('W');
SendKey('E');
}
return 1;
}
}
return CallNextHookEx(hHook, nCode, wParam, (LPARAM) lpKey);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
WNDCLASS wndclass;
HWND hWnd;
ZeroMemory(&wndclass, sizeof(wndclass));
wndclass.lpfnWndProc = DefWindowProc;
wndclass.hInstance = hInstance;
wndclass.lpszClassName = TEXT("KbHookHost");
if(!RegisterClass(&wndclass))
{
ShowError(TEXT("RegisterClass"));
}
else if(NULL == (hWnd = CreateWindow(wndclass.lpszClassName, wndclass.lpszClassName,
0, 0, 0, 0, 0, HWND_MESSAGE, NULL, hInstance, NULL)))
{
ShowError(TEXT("CreateWindow"));
}
else if(NULL == (hHook = SetWindowsHookEx(WH_KEYBOARD_LL,
(HOOKPROC) LowLevelKeyboardProc, hInstance, NULL)))
{
ShowError(TEXT("SetWindowsHookEx"));
}
else
{
while(GetMessage(&msg, NULL, 0, 0))
DispatchMessage(&msg);
DestroyWindow(hWnd);
UnhookWindowsHookEx(hHook);
return msg.wParam;
}
return 0;
}
void ShowError(LPTSTR lpszFunction)
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}