![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
To access the contents, click the chapter and section titles.
Fast Track Visual C++ 6.0 Programming
That completes our work with journal hooks. Next, we turn to hooks specifically made to handle keyboard events: keyboard hooks. Keyboard HooksIn our next hook example, we support a keyboard hook, which is specifically designed to work with the keyboard. In this case, we let the user press a key combination^Cto open the Windows calculator. The keyboard hook code has to be in a DLL, and we call our DLL LaunchDLL.dll. When we link that DLL into a program, Launch, we call a function in that DLL, InstallLauncher(), to install our hook. Until you end the Launch program, every time the user presses ^C in any program, the Windows calculator appears. We start by creating a new MFC DLL as we did in the last chapter. Creating LaunchDLL.dllUse AppWizard(dll) to create a new, standard DLL project named LaunchDLL. We need two functions in this DLL: a function to install the keyboard hook, InstallLauncher(), and a hook procedure, LauncherHook(). The following example shows how we declare those in LauncherDLL.h: // LaunchDLL.h : main header file for the LAUNCHDLL DLL // #if !defined(AFX_LAUNCHDLL_H__6433B666_A86C_11D1_887F_D 42B07C10710__INCLUDED_) #define AFX_LAUNCHDLL_H__6433B666_A86C_11D1_887F_D 42B07C10710__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #ifndef __AFXWIN_H__ #error include stdafx.h before including this file for PCH #endif #include resource.h // main symbols #define DllExport __declspec( dllexport ) ⇐ DllExport void WINAPI InstallLauncher(); ⇐ LRESULT CALLBACK LauncherHook (int nCode, WORD wParam, DWORD lParam ); ⇐ . . . The code in InstallLauncher() installs our hook, and writing that code will be our first task. Installing the HookAdd the InstallLauncher() function to the end of the LaunchDLL.cpp file, after the declaration of the actual MFC DLL object itself, theApp. CLaunchDLLApp theApp; DllExport void WINAPI InstallLauncher() ⇐ { ⇐ } ⇐ To install a keyboard hook, we pass SetWindowsHookEx() the constant WH_KEYBOARD, a pointer to a hook procedure (which will be our LauncherHook() function), the instance handle of the DLL, and the thread ID of the process to hook. Making that ID 0 means we hook all running threads. One problem here is how to get the instance handle of the DLL, especially because the InstallLauncher() procedure is not part of the CLaunchDLL class. The solution is simple. As we just saw, the actual DLL object in MFC DLLs is named theApp, and that object has a special member named m_hInstance, which is just what we want. We set the hook this way: CLaunchDLLApp theApp; DllExport void WINAPI InstallLauncher() { Hook = (HHOOK)SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)LauncherHook, theApp.m_hInstance, 0); ⇐ } That installs the hook. All we need to do now is write the hook procedure, LauncherHook(). The Hook ProcedureWe start the LauncherHook() procedure much as we started the hook procedures in the last example: by calling the next hook in the chain, if there is one. LRESULT CALLBACK LauncherHook (int nCode, WORD wParam, DWORD lParam ) { LRESULT Result = CallNextHookEx(Hook, nCode, wParam, lParam); ⇐ . . . Were looking for events with the code HC_ACTION, so we check for that first.
LRESULT CALLBACK LauncherHook (int nCode, WORD wParam, DWORD lParam ) { LRESULT Result = CallNextHookEx(Hook, nCode, wParam, lParam); if(nCode == HC_ACTION){ ⇐ . . . We also must check to see whether the user has pressed ^C. The wParam parameter holds the key that the user pressed, but it doesnt include any modifying keys, such as Shift, Ctrl, or Alt (which is one reason why its usually easier to use WM_CHAR when possible). Instead, we get the key state for the current message with GetKeyState(), so we check if the Ctrl key is down. LRESULT CALLBACK LauncherHook (int nCode, WORD wParam, DWORD lParam ) { LRESULT Result = CallNextHookEx(Hook, nCode, wParam, lParam); if(nCode == HC_ACTION){ if ((GetKeyState(VK_CONTROL) < 0) && (wParam == C)){ ⇐ . . . We know that the user has pressed the ^C key, but we dont know whether this is a KeyUp or KeyDown message. We dont want to launch the Windows calculator for both messages, so we check for the WM_KEYUP message. If the user has released the key, the top bit of the lParam parameter will be set. We check that this way: LRESULT CALLBACK LauncherHook (int nCode, WORD wParam, DWORD lParam ) { LRESULT Result = CallNextHookEx(Hook, nCode, wParam, lParam); if(nCode == HC_ACTION){ if ((GetKeyState(VK_CONTROL) < 0) && (wParam == C)){ if(lParam & 0x80000000){ ⇐ . . . At this point, were ready to launch the Windows calculator program c:\windows\calc.exe. We begin that process by setting up the STARTUPINFO and PROCESS_INFORMATION structures we need. LRESULT CALLBACK LauncherHook (int nCode, WORD wParam, DWORD lParam ) { LRESULT Result = CallNextHookEx(Hook, nCode, wParam, lParam); if(nCode == HC_ACTION){ if ((GetKeyState(VK_CONTROL) < 0) && (wParam == C)){ if(lParam & 0x80000000){ STARTUPINFO StartupInfo; ⇐ PROCESS_INFORMATION ProcessInfo; ⇐ memset(&StartupInfo, 0, sizeof(StartupInfo)); ⇐ StartupInfo.cb = sizeof(StartupInfo); ⇐ . . . Then we launch the calculator itself. LRESULT CALLBACK LauncherHook (int nCode, WORD wParam, DWORD lParam ) { LRESULT Result = CallNextHookEx(Hook, nCode, wParam, lParam); if(nCode == HC_ACTION){ if ((GetKeyState(VK_CONTROL) < 0) && (wParam == C)){ if(lParam & 0x80000000){ STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInfo; memset(&StartupInfo, 0, sizeof(StartupInfo)); StartupInfo.cb = sizeof(StartupInfo); CreateProcess(c:\\windows\\calc.exe, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo); ⇐ Result = 0; ⇐ } } } return Result; ⇐ } That finishes the DLL. Create LauncherDLL.dll and LauncherDLL.lib now. We need some way to call the InstallLauncher() function in order to install our new hook, so we put together a new program called Launch to do that.
|
![]() |
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement. |