Click here to Skip to main content
15,860,943 members
Articles / Programming Languages / C++

Mouse and KeyBoard Hooking utility with VC++

Rate me:
Please Sign up or sign in to vote.
4.93/5 (38 votes)
21 Mar 2010CPL4 min read 181.1K   27K   146   39
Test Automation software's code revealed with the help of mouse and keyboard hooking!!!

Introduction

A good white box testing is essential for the success of software. Testing is usually done with human interaction, which is both slow and expensive. Testing is a long process which needs a lot patience and keen observation. If it is a white box testing, then we need to follow some steps and run a lot of scenarios whenever we make a small change in our software’s code. Usually, the same steps are done by testers repeatedly. To overcome this problem, a lot of Test Automation tools are available in the market. Some of the famous GUI testing tools are IBM Rational Functional Tester from IBM and Phantom Automation Language from Microsoft.

This article is concentrated mainly on creating a miniature of a Test Automation tool, with the help of mouse and keyboard hooking. Keyboard and mouse hooking is no longer an undocumented activity. It is available in plenty on the internet. As we know, whenever a good technology is introduced, it has pros and cons. If we record the mouse and keyboard events without the knowledge of a user, then it is Trojan horse, key logger or a virus. But if it is done purposefully, then it is automation. The next few sections mentioned below will be fully concentrated on creating a Test Automation miniature with the help of global mouse and keyboard hooking. So hooking is a simple activity by which, we will be able to get the keyboard and mouse events in our application. Let us go in detail.

Background

Hooking of keyboard and mouse can be usually done in two ways:

  1. Thread wise Hooking

    As the name reveals, it is only limited to a thread in a process. This can be useful in our software. So hook procedure can be placed either on an EXE or a DLL. 

  2. Global Hooking

    Global Hooking is a system wide hooking. The entire keyboard or mouse event is diverted to our hook procedure. The hooking function must be placed on a separate DLL in this case.

We achieve the mouse and keyboard hooking with he help of the Windows provided SetWindowHookEx WINAPI (Hooks many types of events ). To unhook the event, we need to give UnhookWindowsHookEx WINAPI.

To demonstrate the usage of hooking, I came up with an application RecordPlayer.exe. So let me introduce the application to you. It mainly consists of three components.

  • RecordPlayer.exe
    • The application that manages the keyboard and mouse hook events from the corresponding DLL.The playback operation of the recorded steps.
  • KeyBoardHook.dll
    • Hooking the keyboard events
  • HookDll.dll
    • Hooking the mouse events

Our application consists of two operations, recording and playback. Recording is done with the help of DLLs and playback is done with the help of two APIs mainly - keybd_event and mouse_event. Now let us go under the hood. I will demonstrate the hooking activity with the help of keyboard hooking.

Using the Code

To start the keyboard hooking, firstly make a WIN32 DLL. Let us start with the header file of DLL.

Then Export the functions from the DLL, so that it can be accessible from our native application that is going to get the data from the hook procedure.

The code inside KeyBoardHookLib.h:

C++
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#define LIBSPEC __declspec(dllexport)
// Our install Hook procedure.
 LIBSPEC BOOL InstallKeyBoardHook(HWND hWndParent);
// Our uninstall hook procedure.
LIBSPEC BOOL UnInstallKeyBoardHook(HWND hWndParent);
#undef LIBSPEC

The named events that registers to send the window message to RecordPlayer.exe.

C++
#define UWM_KEYBOARD_MSG ("UWM_KEYBOARD_USER_MSG")

Let us become familiar with KeyBoardHookLib.cpp.

The below steps are done to share the HANDLE mentioned inside that #pragma to be shared among DLL or to the native application from this DLL.

C++
#pragma data_seg(".SHARE")

UINT UWN_KEYSTROKE;
HWND hWndServer = NULL;
#pragma data_seg()

#pragma comment(linker,
"/section:.SHARE,rws")

The below mentioned step is done to register the window message so that we can send the keyboard events received inside the Hook function to the native executable.

C++
UWN_KEYSTROKE= ::RegisterWindowMessage(UWM_KEYBOARD_MSG);

The below mentioned static function is a keyboard procedure which receives the global keyboard events.

C++
static LRESULT CALLBACK KeyBoardMsgProc( int nCode, WPARAM wParam, LPARAM lParam)

We start the hooking of the keyboard events once InstallKeyBoardHook is called from the parent executable.

In the SetWindowHookEx, we have specified the first parameter as WH_KEYBOARD to hook the keyboard event.

C++
hook= SetWindowsHookEx( WH_KEYBOARD, (HOOKPROC)KeyBoardMsgProc, hInst, 0);

The CallNextHookEx is a optional procedure but it is highly recommented by Microsoft. If it is not called, there is a chance that other processes that have installed hook may not get the events correctly.

C++
CallNextHookEx(hook, nCode, wParam,lParam);

To uninstall the hook procedure, we need to call the UnhookWindowsHookEx specifying the Handle of returned by SetWindowHookEx.

C++
BOOL unhooked = UnhookWindowsHookEx(hook);

Points of Interest

This tool is a miniature implementation to the test automation software. But I am sure, it will give you an idea about mouse and keyboard hooking. SetWindowsHookEx can be used to inject a DLL into another process. In this article, we are dealing with WH_KEYBOARD which monitors keystroke message. The keyboard input can come from the local keyboard driver or from calls to the keybd_event function. If the input comes from a call to keybd_event, the input is "injected". WH_KEYBOARD_LL hook is not injected into another process, so it’s better. WH_SHELL can be used to get notification of the shell events. SetWindowHookEx is a very useful API, but for a good work we have to pay, so let's do so. Hooks tend to slow down the system because they increase the amount of processing the system must perform for each message. So use judiciously. If my Allah allows me, I will write more articles.

History

  • Version 1.0

License

This article, along with any associated source code and files, is licensed under The Common Public License Version 1.0 (CPL)


Written By
Software Developer (Senior) Philips HealthCare
India India
I am always looking for new technical challenges.
If you face it, contact me, I will solve it.

Comments and Discussions

 
PraiseVery good article with working code Pin
PeterMB14-May-18 22:57
professionalPeterMB14-May-18 22:57 
QuestionAssign space bar as enter in Catia Pin
Member 1145003413-Feb-15 2:27
Member 1145003413-Feb-15 2:27 
QuestionHook in background application Pin
Lafacce19-Dec-14 0:40
Lafacce19-Dec-14 0:40 
QuestionSlow responsive Pin
Bill Lee Vn29-Oct-14 23:05
Bill Lee Vn29-Oct-14 23:05 
AnswerRe: Slow responsive Pin
Adam Roderick J3-Nov-14 18:23
Adam Roderick J3-Nov-14 18:23 
Questionit does not capture mouse clicks on Desktop Pin
sb13623-Jun-14 18:21
sb13623-Jun-14 18:21 
Questionimplementing step by step Pin
sb136219-Apr-14 16:12
sb136219-Apr-14 16:12 
AnswerRe: implementing step by step Pin
Adam Roderick J12-May-14 2:29
Adam Roderick J12-May-14 2:29 
GeneralRe: implementing step by step Pin
sb13623-Jun-14 18:19
sb13623-Jun-14 18:19 
GeneralRe: implementing step by step Pin
Adam Roderick J24-Jun-14 18:16
Adam Roderick J24-Jun-14 18:16 
GeneralRe: implementing step by step Pin
sb136224-Jun-14 18:22
sb136224-Jun-14 18:22 
GeneralRe: implementing step by step Pin
Adam Roderick J11-Jul-14 19:30
Adam Roderick J11-Jul-14 19:30 
GeneralMy vote of 5 Pin
thanh_bkhn13-Jun-13 23:34
professionalthanh_bkhn13-Jun-13 23:34 
QuestionUsing Hooks with pure Win32 API Pin
Robert France 201112-Mar-13 6:49
Robert France 201112-Mar-13 6:49 
AnswerRe: Using Hooks with pure Win32 API Pin
Adam Roderick J3-Apr-13 1:44
Adam Roderick J3-Apr-13 1:44 
GeneralRe: Using Hooks with pure Win32 API Pin
Robert France 20113-Apr-13 3:05
Robert France 20113-Apr-13 3:05 
QuestionBuild Error Pin
Kavyn911-Dec-12 22:00
Kavyn911-Dec-12 22:00 
AnswerRe: Build Error Pin
Adam Roderick J29-Jan-13 2:05
Adam Roderick J29-Jan-13 2:05 
AnswerRe: Build Error Pin
FreeKick00113-Apr-13 7:06
FreeKick00113-Apr-13 7:06 
AnswerRe: Build Error Pin
Yongsung Kim17-Oct-13 4:27
Yongsung Kim17-Oct-13 4:27 
GeneralMy vote of 5 Pin
gndnet1-Nov-12 0:53
gndnet1-Nov-12 0:53 
Questionhow to stop the Delete keyboard event Pin
Rocky_Bas4-Oct-12 23:44
Rocky_Bas4-Oct-12 23:44 
Hello,

I have tracked the event of Keyboard delete event by using the Virtual key VK_DELETE in the keystroke function,but how to stop that event to proceed.I mean to say i want the user not to do delete through keyboard,so for that i have to keep some condition after tracking the Delete event,can u kindly tell me how to implement this.
AnswerRe: how to stop the Delete keyboard event Pin
Adam Roderick J23-Oct-12 2:08
Adam Roderick J23-Oct-12 2:08 
Suggestioncan't catch the ie explorer event Pin
ainichenwei27-Aug-12 16:34
ainichenwei27-Aug-12 16:34 
GeneralRe: can't catch the ie explorer event Pin
Adam Roderick J19-Sep-12 3:42
Adam Roderick J19-Sep-12 3:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.