/* *Copyright (C) 2004 Harold L Hunt II All Rights Reserved. * *Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the *"Software"), to deal in the Software without restriction, including *without limitation the rights to use, copy, modify, merge, publish, *distribute, sublicense, and/or sell copies of the Software, and to *permit persons to whom the Software is furnished to do so, subject to *the following conditions: * *The above copyright notice and this permission notice shall be *included in all copies or substantial portions of the Software. * *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 HAROLD L HUNT II 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. * *Except as contained in this notice, the name of Harold L Hunt II *shall not be used in advertising or otherwise to promote the sale, use *or other dealings in this Software without prior written authorization *from Harold L Hunt II. * * Authors: Harold L Hunt II */ #include "win.h" /* * References to external symbols */ extern HHOOK g_hhookKeyboardLL; extern DWORD g_dwCurrentThreadID; extern HWND g_hwndKeyboardFocus; /* * Function prototypes */ static LRESULT CALLBACK winKeyboardMessageHookLL (int iCode, WPARAM wParam, LPARAM lParam); #ifndef LLKHF_EXTENDED # define LLKHF_EXTENDED 0x00000001 #endif #ifndef LLKHF_UP # define LLKHF_UP 0x00000080 #endif /* * KeyboardMessageHook */ static LRESULT CALLBACK winKeyboardMessageHookLL (int iCode, WPARAM wParam, LPARAM lParam) { BOOL fPassKeystroke = FALSE; PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam; /* Pass keystrokes on to our main message loop */ if (iCode == HC_ACTION) { #if 0 ErrorF ("vkCode: %08x\tscanCode: %08x\n", p->vkCode, p->scanCode); #endif switch (wParam) { case WM_KEYDOWN: case WM_SYSKEYDOWN: case WM_KEYUP: case WM_SYSKEYUP: fPassKeystroke = ((p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0)) #if 0 || (p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN) #endif ; break; } } /* * Pass message on to our main message loop. * We process this immediately with SendMessage so that the keystroke * appears in, hopefully, the correct order. */ if (fPassKeystroke) { LPARAM lParamKey = 0x0; /* Construct the lParam from KBDLLHOOKSTRUCT */ lParamKey = lParamKey | (0x0000FFFF & 0x00000001); /* Repeat count */ lParamKey = lParamKey | (0x00FF0000 & (p->scanCode << 16)); lParamKey = lParamKey | (0x01000000 & ((p->flags & LLKHF_EXTENDED) << 23)); lParamKey = lParamKey | (0x20000000 & ((p->flags & LLKHF_ALTDOWN) << 24)); lParamKey = lParamKey | (0x80000000 & ((p->flags & LLKHF_UP) << 24)); /* Send message to our main window that has the keyboard focus */ PostMessage (g_hwndKeyboardFocus, (UINT) wParam, (WPARAM) p->vkCode, lParamKey); return 1; } /* Call next hook */ return CallNextHookEx (NULL, iCode, wParam, lParam); } /* * Attempt to install the keyboard hook, return FALSE if it was not installed */ Bool winInstallKeyboardHookLL () { OSVERSIONINFO osvi = {0}; /* Get operating system version information */ osvi.dwOSVersionInfoSize = sizeof (osvi); GetVersionEx (&osvi); /* Branch on platform ID */ switch (osvi.dwPlatformId) { case VER_PLATFORM_WIN32_NT: /* Low-level is supported on NT 4.0 SP3+ only */ /* TODO: Return FALSE on NT 4.0 with no SP, SP1, or SP2 */ break; case VER_PLATFORM_WIN32_WINDOWS: /* Low-level hook is not supported on non-NT */ return FALSE; } /* Install the hook only once */ if (!g_hhookKeyboardLL) g_hhookKeyboardLL = SetWindowsHookEx (WH_KEYBOARD_LL, winKeyboardMessageHookLL, g_hInstance, 0); return TRUE; } /* * Remove the keyboard hook if it is installed */ void winRemoveKeyboardHookLL () { if (g_hhookKeyboardLL) UnhookWindowsHookEx (g_hhookKeyboardLL); g_hhookKeyboardLL = NULL; }