1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
//-----------------------------------------------------------//
// This is just a dummy application to test a low-level //
// keyboard hook process. Most of it is just normal //
// windows overhead. It installs the hook procedure, then //
// runs the message loop until the window is closed, at //
// which point it unhooks the hook, and exits. //
//-----------------------------------------------------------//
#include <windows.h>
#include <stdio.h>
#include <string.h>
using namespace std;
//window procedure, hook proc proto, and an error function
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
LRESULT __stdcall LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
char* GetLastErrorString(void);
//handle for the hook
HHOOK KBHook = NULL;
//window class name
char szClassName[ ] = "HookWindow";
// process entry
int WINAPI WinMain(HINSTANCE hThisInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nShow)
{
// normal windows variables
HWND hwnd;
MSG messages;
WNDCLASSEX wincl;
// normal windows programming overhead
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof (WNDCLASSEX);
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
// Register the window class, and if it fails quit the program
if (!RegisterClassEx(&wincl))
{
return 0;
}
// create the window
hwnd = CreateWindowEx (0, szClassName, "Low Level Keyboard Hook", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 300, 200,
HWND_DESKTOP, NULL, hThisInstance, NULL);
// make sure window is visible
ShowWindow (hwnd, nShow);
// store address of hook proc
HOOKPROC lpfnHookProc = &LowLevelKeyboardProc;
// try to set hook
KBHook = SetWindowsHookEx(WH_KEYBOARD_LL, lpfnHookProc, GetModuleHandle(NULL), 0);
// if hook was not installed, get the last error code, and string and
// show them both in a messagebox()
if(KBHook == NULL)
{
DWORD n;
char lpBuffer[50];
char* errorString = GetLastErrorString();
sprintf(lpBuffer, "keyboard hook not installed\n"
"error code: %d\n", (int)GetLastError());
strcat(lpBuffer, errorString);
MessageBox(HWND_DESKTOP, lpBuffer, "keyboard hook could not be installed!", MB_OK);
}
// start a basic message loop (only if the hook was properly installed)
while (GetMessage(&messages, NULL, 0, 0) && (KBHook != NULL))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
// if there is a valid hook procedure, uninstall it
if(KBHook)
{
// if unhookwindowshookex fails, show the last error as a string
if(!UnhookWindowsHookEx(KBHook))
{
char* errorString = GetLastErrorString();
MessageBox(HWND_DESKTOP, errorString, "Last Error", MB_OK);
}
}
return messages.wParam;
}
char* GetLastErrorString(void)
{
LPTSTR pszMessage;
DWORD dwLastError = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&pszMessage,
0, NULL );
return pszMessage;
}
// skeleton window procedure to run app
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
// your hook procedure
LRESULT __stdcall LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
//MessageBox(HWND_DESKTOP, "", "", MB_OK);
KBDLLHOOKSTRUCT *KeyInfo = (KBDLLHOOKSTRUCT*)lParam;
HWND hwndActiveWin = GetForegroundWindow();
unsigned long idActive = GetWindowThreadProcessId(hwndActiveWin, NULL);
HWND hwndFocused = 0;
char lpKBState[256];
if (AttachThreadInput(GetCurrentThreadId(), idActive, TRUE) )
{
GetKeyboardState((BYTE*)lpKBState); // keyboard state of the window with keyboard input
hwndFocused = GetFocus (); // focused control within the active window, i.e. focus throughout the screen
AttachThreadInput(GetCurrentThreadId(), idActive, FALSE);
}
else
{
GetKeyboardState((BYTE*)lpKBState);
hwndFocused = hwndActiveWin;
}
unsigned long idControlActive = GetWindowThreadProcessId(hwndFocused, NULL);
unsigned short textWritten[10];
HKL dwhkl = GetKeyboardLayout(idControlActive);
int charsWritten = ToAsciiEx(KeyInfo->vkCode, KeyInfo->scanCode, (BYTE*)lpKBState, textWritten, 0, dwhkl);
return CallNextHookEx(KBHook, nCode, wParam, lParam);
}
|