Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Copyright 2000 by Symantec Corporation--------------------------------------
- File : LowLevelKeyHook.cpp
- Purpose : Install a hook prior to the system window procedure to catch
- Alt+Tab, Shift+Alt+Tab, Alt+Esc, Ctrl+Esc
- Author: E. Feldl, July 2000
- ----------------------------------------------------------------------------- */
- // Must be before stdafx.h. Necessary for compile. We later poll the OS to
- // determine if we should run NT/2000 or 98 code.
- #define _WIN32_WINNT 0x0400
- #include <afxwin.h> // AfxGetInstanceHandle();
- #include <windows.h>
- #include <winuser.h>
- #include "lowlevelkeyhook.h"
- #include "globdefs.h" // #define TERMWINDOW_CLASS_NAME (LPSTR)"TERMWindow"
- HHOOK CurrentHook = NULL; // necessary for LowLevelKeyboardProc
- int MajorVersion = 0;
- /* -----------------------------------------------------------------------------
- Routine: "PreSysWndProcKeyHook"
- Purpose: Install the windows hook and register the custom messages.
- Parameter Type Description
- --------- ---- -----------
- NONE
- Initializer Type Description
- ----------- ---- -----------
- m_Hook HHOOK Current Window Hook
- Creation Date: July 2000, E. Feldl
- ----------------------------------------------------------------------------- */
- PreSysWndProcKeyHook::PreSysWndProcKeyHook() : m_Hook(NULL)
- {
- // Please note that WH_KEYBOARD_LL used in SetWindowsHookEx is only valid
- // on Windows NT 4.0 Service Pack 3 or greater. This also serves as a
- // placeholder were code for other operating systems can be added.
- IsNTVersion4OrHigher(MajorVersion);
- if((MajorVersion == 4 && GetServicePack() >= 3)|| MajorVersion >= 5)
- {
- // Please note that RegisterWindowsMessage can perform two functions.
- // It can return a new unique message id or it can look up and existing
- // id. Therefor registering the same call twice does not result in
- // multiple identifiers.
- RegisterWindowMessage(CTRL_ESC_MSG);
- RegisterWindowMessage(ALT_ESC_MSG);
- RegisterWindowMessage(BRINGUPTASKSWITCHER_MSG);
- RegisterWindowMessage(TABNEXTTASK_MSG);
- // Do not install the hook unless this is NT4 SP3.
- m_Hook = InstallWindowHook();
- // We should pass in our current hook into CallNextHookEx and since
- // LowLevelKeyboardProc must be a C function, we need this global
- // to store it's value.
- CurrentHook = m_Hook;
- }
- }
- /* -----------------------------------------------------------------------------
- Routine: "~PreSysWndProcKeyHook"
- Purpose: Uninstall the hook.
- Parameter Type Description
- --------- ---- -----------
- NONE
- Creation Date: July 2000, E. Feldl
- ----------------------------------------------------------------------------- */
- PreSysWndProcKeyHook::~PreSysWndProcKeyHook()
- {
- // No need to call UnhookWindowsHookEx unless we installed the Hook. This
- // also serves as a placeholder for code for other operating systems.
- if((MajorVersion == 4 && GetServicePack() >= 3)|| MajorVersion >= 5)
- {
- UnhookWindowsHookEx(m_Hook);
- CurrentHook = NULL;
- }
- }
- /* -----------------------------------------------------------------------------
- Routine: "InstallWindowHook"
- Purpose: Wrap SetWindowsHookEx with checking.
- Parameter Type Description
- --------- ---- -----------
- NONE
- Returns Type Description
- --------- ---- -----------
- hHook HHOOK Current Window Hook
- Creation Date: July 2000, E. Feldl
- ----------------------------------------------------------------------------- */
- HHOOK PreSysWndProcKeyHook::InstallWindowHook()
- {
- HHOOK hHook = SetWindowsHookEx(WH_KEYBOARD_LL,
- LowLevelKeyboardProc,
- AfxGetInstanceHandle(),
- 0);
- ASSERT(hHook != NULL);
- return hHook;
- }
- /* -----------------------------------------------------------------------------
- Routine: "IsNTVersion4OrHigher"
- Purpose:
- Check to see if this is NT 4.0 or greater. WH_KEYBOARD_LL is only valid on
- these systems.
- Parameter Type Description
- --------- ---- -----------
- version integer reference Used to return the major version number
- Returns Type Description
- --------- ---- -----------
- BOOL True if NT4, False otherwise
- Creation Date: July 2000, E. Feldl
- ----------------------------------------------------------------------------- */
- BOOL PreSysWndProcKeyHook::IsNTVersion4OrHigher(int &version)
- {
- OSVERSIONINFO os;
- os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&os);
- if(os.dwPlatformId == VER_PLATFORM_WIN32_NT &&
- os.dwMajorVersion >= 4 )
- {
- version = os.dwMajorVersion;
- return TRUE;
- }
- else
- {
- version = 0;
- return FALSE;
- }
- }
- /* -----------------------------------------------------------------------------
- Routine: "LowLevelKeyboardProc"
- Purpose: The "C" hook function to install.
- Parameter Type Description
- --------- ---- -----------
- nCode int Hook code passed to hook procedure
- wParam WPARAM Custom messages wParam == NULL
- lParam LPARAM Custom messages lParam == NULL
- Returns Type Description
- --------- ---- -----------
- LRESULT CALLBACK Windows Callback Function
- Creation Date: July 2000, E. Feldl
- ----------------------------------------------------------------------------- */
- LRESULT CALLBACK PreSysWndProcKeyHook::LowLevelKeyboardProc(int nCode,
- WPARAM wParam,
- LPARAM lParam)
- {
- // Allow us to disable CallNextHookEx
- BOOL fEatKeystroke = FALSE;
- // Handle to our terminal window
- HWND hFindWnd = NULL;
- // Used to toggle Alt+Tab, Tab, Tab .... in task switcher
- static BOOL RanOnce = FALSE;
- // Is the scroll key toggled on?
- BOOL ScrollLocked = GetKeyState(VK_SCROLL) & 0x0001;
- // If Scroll not locked don't handle.
- if((nCode == HC_ACTION) && ScrollLocked)
- {
- // Stores the low level keyboard event information.
- PKBDLLHOOKSTRUCT pInfoLowLevelEvent = (PKBDLLHOOKSTRUCT)lParam;
- // hFindWnd must be correct or else PostMessage
- // won't go to correct window proc.
- hFindWnd = FindWindow(TERMWINDOW_CLASS_NAME,NULL);
- // If our window isn't the active one, we shouldn't capture keys.
- if(hFindWnd != GetForegroundWindow())
- {
- return CallNextHookEx(CurrentHook, nCode, wParam, lParam);
- }
- // We must have a window to send the messages to.
- ASSERT(hFindWnd != NULL);
- //if(wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
- switch(wParam)
- {
- case WM_KEYDOWN: case WM_SYSKEYDOWN:
- // Yes we are interested in these keys
- // ALT-DOWN+TAB-DOWN
- if((pInfoLowLevelEvent->vkCode==VK_TAB)&&
- ((pInfoLowLevelEvent->flags&LLKHF_ALTDOWN)!=0))
- {
- if(RanOnce == FALSE)
- {
- // We need to bring up the task switcher.
- SendCustomMessage(hFindWnd,
- RegisterWindowMessage(BRINGUPTASKSWITCHER_MSG));
- fEatKeystroke = TRUE;
- RanOnce =TRUE;
- }
- else
- {
- // We need to tab through the task switcher.
- SendCustomMessage(hFindWnd,
- RegisterWindowMessage(TABNEXTTASK_MSG));
- fEatKeystroke = TRUE;
- }
- }
- else
- {
- // We did something besides Alt+Tab so reset Alt+Tab mechanism.
- // This is required because Alt+Tab can perform two functions.
- // It can bring up the task switcher and it can tab through the
- // tasks in the task switcher. RanOnce determines the correct
- // mode of operation.
- RanOnce = FALSE;
- // Alt+Esc ------------------------------
- if((pInfoLowLevelEvent->vkCode==VK_ESCAPE)&&
- ((pInfoLowLevelEvent->flags&LLKHF_ALTDOWN)!=0))
- {
- SendCustomMessage(hFindWnd,
- RegisterWindowMessage(ALT_ESC_MSG));
- fEatKeystroke = TRUE;
- }
- // Ctrl+Esc ------------------------------
- else if((pInfoLowLevelEvent->vkCode==VK_ESCAPE)&&
- ((GetKeyState(VK_CONTROL) & 0x8000) != 0))
- {
- // Ctrl+Esc does not work on NT4, just 2000
- if(MajorVersion >= 5)
- {
- SendCustomMessage(hFindWnd,
- RegisterWindowMessage(CTRL_ESC_MSG));
- fEatKeystroke = TRUE;
- }
- }
- } // end else
- } // end switch wParam
- } // end if nCode == HC_ACTION && ScrollLocked
- // Call the next hook or eat the key.
- if(fEatKeystroke)
- {
- return 1;
- }
- else
- {
- return CallNextHookEx(CurrentHook, nCode, wParam, lParam);
- }
- }
- /* -----------------------------------------------------------------------------
- Routine: "SendCustomMessage"
- Purpose: Sends the custom message to the window.
- Parameter Type Description
- --------- ---- -----------
- hWnd HWND Handle to our window that will receive the
- message.
- MessageId UINT Custom messages
- Returns Type Description
- --------- ---- -----------
- NONE
- Creation Date: July 2000, E. Feldl
- ----------------------------------------------------------------------------- */
- void PreSysWndProcKeyHook::SendCustomMessage(HWND hWnd, UINT MessageId)
- {
- ASSERT(MessageId != 0);
- BOOL Status = PostMessage(hWnd, MessageId, NULL, NULL);
- ASSERT(Status == TRUE);
- }
- /* -----------------------------------------------------------------------------
- Routine: "GetServicePack"
- Purpose: Gets the NT Service Pack number.
- Parameter Type Description
- --------- ---- -----------
- NONE
- Returns Type Description
- --------- ---- -----------
- iRet int The Service Pack number
- Creation Date: July 2000, E. Feldl, M. Vanloon
- ----------------------------------------------------------------------------- */
- int PreSysWndProcKeyHook::GetServicePack()
- {
- OSVERSIONINFO os;
- int iRet=0;
- os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&os);
- if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)
- {
- if (os.szCSDVersion)
- {
- int pos = strcspn(os.szCSDVersion,"1234567890");
- iRet = atoi(os.szCSDVersion + pos);
- }
- }
- return iRet;
- }
- // End of File: LowLevelKeyHook.cpp -----------------------------------------------
Add Comment
Please, Sign In to add comment