// // AUTHOR // Stef Walter // // LICENSE // This software is in the public domain. // // The software is provided "as is", without warranty of any kind, // express or implied, including but not limited to the warranties // of merchantability, fitness for a particular purpose, and // noninfringement. In no event shall the author(s) be liable for any // claim, damages, or other liability, whether in an action of // contract, tort, or otherwise, arising from, out of, or in connection // with the software or the use or other dealings in the software. // // SUPPORT // Send bug reports to: // #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include #include "hook.h" #ifndef ASSERT #include #define ASSERT assert #endif HMODULE g_hMod = NULL; #pragma data_seg(".shared") HHOOK g_hHook = NULL; LONG g_nCur = 0; #pragma data_seg() BOOL APIENTRY DllMain( HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: g_hMod = hModule; break; case DLL_PROCESS_DETACH: g_hMod = NULL; break; } return TRUE; } LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) { ASSERT(g_hHook); if(code == HC_ACTION) { if(!(HIWORD(lParam) & KF_UP)) { // Although this is not perfect, it's good enough as the // keyboard will usually only be used by one thread at a time InterlockedExchange(&g_nCur, (LONG)(g_nCur + LOWORD(lParam))); } } return (int)CallNextHookEx(g_hHook, code, wParam, lParam); } HOOK_API HRESULT InstallSpeedHook() { ASSERT(g_hMod); g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hMod, 0); if(!g_hHook) return HRESULT_FROM_WIN32(GetLastError()); return S_OK; } HOOK_API HRESULT RemoveSpeedHook() { ASSERT(g_hHook); return UnhookWindowsHookEx(g_hHook) ? S_OK : HRESULT_FROM_WIN32(GetLastError()); } HOOK_API int GetCurSpeedCount() { return g_nCur; } HOOK_API void ClearSpeedCount() { InterlockedExchange(&g_nCur, 0L); }