Click here to Skip to main content
Click here to Skip to main content

KeyBoard Hooks

By , 23 Jul 2001
 

Introduction

Hooks are one of the most powerful features of Windows. We can hooks to trp all the events in the Windows environment. This example shows how to trap keyboard events and save the keys to a text file.

In the Microsoft® Windows™ operating system, a hook is a mechanism by which a function can intercept events (messages, mouse actions, keystrokes) before they reach an application. The function can act on events and, in some cases, modify or discard them. Functions that receive events are called filter functions and are classified according to the type of event they intercept. For example, a filter function might want to receive all keyboard or mouse events. For Windows to call a filter function, the filter function must be installed — that is, attached to a Windows hook (for example, to a keyboard hook). Attaching one or more filter functions to a hook is known as setting a hook. If a hook has more than one filter function attached, Windows maintains a chain of filter functions. The most recently installed function is at the beginning of the chain, and the least recently installed function is at the end.

When a hook has one or more filter functions attached and an event occurs that triggers the hook, Windows calls the first filter function in the filter function chain. This action is known as calling the hook. For example, if a filter function is attached to the Computer Based Training (CBT) hook and an event that triggers the hook occurs (for example, a window is about to be created), Windows calls the CBT hook by calling the first function in the filter function chain.

To maintain and access filter functions, applications use the SetWindowsHookEx and the UnhookWindowsHookEx functions.

An Example

The CALLBACK function in my example is given below..

LRESULT __declspec(dllexport)__stdcall  CALLBACK KeyboardProc(int nCode,WPARAM wParam, 
                            LPARAM lParam)
{
    char ch;            
    if (((DWORD)lParam & 0x40000000) &&(HC_ACTION==nCode))
    {        
        if ((wParam==VK_SPACE)||(wParam==VK_RETURN)||(wParam>=0x2f ) &&(wParam<=0x100)) 
        {
            f1=fopen("c:\\report.txt","a+");
            if (wParam==VK_RETURN)
            {
                ch='\n';
                fwrite(&ch,1,1,f1);
            }
            else
            {
                   BYTE ks[256];
                GetKeyboardState(ks);

                WORD w;
                UINT scan=0;
                ToAscii(wParam,scan,ks,&w,0);
                ch = char(w); 
                fwrite(&ch,1,1,f1);
            }
        fclose(f1);
        }
    }

    LRESULT RetVal = CallNextHookEx( hkb, nCode, wParam, lParam );
    return  RetVal;
}

The installhook function that is installing the hook function in my example is given below.

BOOL __declspec(dllexport)__stdcall installhook()
{
    f1=fopen("c:\\report.txt","w");
    fclose(f1);
    hkb=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hins,0);

    return TRUE;
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

H. Joseph
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionHow to set Key combination (like SHIFT+F9 etc.) as hookmemberMember 783682923 Aug '11 - 19:57 
How to set Key combination (like SHIFT+F9 etc.) as hook. I am trying it from last 3-4 days but not able to do it.
 
Thanks in advance
 
Regards
 
Khalid
QuestionExample in Assembly LanguagememberMember 810561222 Jul '11 - 9:38 
If anyone's looking for an example of how to do this in assembly language, I have written a guide that explains how at my website: The Portable Coder.
 
Please feel free to check it out.
GeneralThanks very muchmemberachui198031 Mar '11 - 16:45 
I'm a beginer ,learning hook program now , for your article ,I have learn more information about hook ,thanks
GeneralHook not working fine if Keyboard Language is Changemembereg_Anubhava1 Feb '11 - 1:30 
Hello experts
 
I need to use Hindi language in .net, I m added Unicode font through control panel> Regional Language > Language and Install, but in language bar there is only two Hindi key bore one is "Hindi" traditional and other is "devnagri INSCRIPT".
 
Then i want to monitor Keyboard it is not working fine it shows same result as US Keyboard Language.
If you can think then I Can.

Generalapplication crash when click on iexplore 7membercjsc20 Mar '10 - 10:08 
Hello Sir
 
I am using your code it's relay nice and smart.Thanks for give us nice article.
 
Sir i am getting assertion when i click on iexplore 7.error is
f:\dd\vctools\crt_blb\self_86\crt\src\fwrite.c line:77 Expression:(stream!=NULL)
Please help me
AnswerRe: application crash when click on iexplore 7memberBMaguire24 May '11 - 8:02 
ieplorer7 operates in protected mode. You mightbot have write access to the key log file. Do a Google search for "SHGetKnownFolderPath FOLDERID_LocalAppDataLow" to find out how to write out a log file in IE7.
GeneralWhich hook is good for trapping Windows Key + some other Key as shortcutmemberArif Saiyed27 Jan '10 - 2:29 
Hi ,
I want to know if Can We have Windows Key + Some other
alphabetical key as shorcut?
 
I yes which Hook I should user WH_KEYBOARD or WH_KEYBOARD_LL or just
WH_GETMESSAGE will do ?
 

I read a little bit at
 

http://msdn.microsoft.com/en-us/library/ms644959(VS.85).aspx#wh_keybo...
 

but I could not understand the much difference between WH_KEYBOARD or
WH_KEYBOARD_LL
 

Do they mean that WH_KEYBOARD_LL hook will not sit(loaded) inside
each application ? and
WH_KEYBOARD will sit inside each application ?
 

My requirement is to have hook inside each running application ...like
WH_GETMESSAGE hook does...
 

Please suggest me which of these hook will useful for me ...
 

I want to capture WinKey + Some Alphbetical key in all application
and then take appropriate action....
 
http://groups.yahoo.com/group/programmers-town/

QuestionDiscard EventmemberErin McCarty9 Jun '09 - 15:51 
How do you discard a keyboard event? Intercept the key "A" before it reaches the computer and throwing it away.
QuestionMessageBox within Hook-Functionmembernoxmortis12 Aug '08 - 1:17 
Hi,
 
I have a simple win32 Hook-Dll that is installs a keyboard-hook.
The keyboard-hook function works perfect but within that hook function no MessageBox comes up onces the hook-function is triggered by the WH_KEYBOARD event.
 

...
hook = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hins,0); //OK
 
LRESULT CALLBACK KeyboardProc(
int nCode,
WPARAM wParam,
LPARAM lParam)
{
MessageBox(NULL, LPCSTR("KeyboardProc() reached"), NULL, MB_OK);
...
LRESULT RetVal = CallNextHookEx(hook , nCode, wParam, lParam );
 
return RetVal;
 
}
 

 
Can anyone explain why the messagebox does not appear once KeyboardProc() is called?
GeneralPlease help memembersomnuc8 Aug '08 - 17:05 
I am doing my graduated design now,i have to make Lao input method....but when i am using my program with msn,yahoo...it can't be deleted English letter that i type.
 
These are my sample code.
 

#include "stdafx.h"
#include "hodll.h"
 
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
 

#pragma data_seg(".SHARDAT")
static HHOOK hkb=NULL;
FILE *f1;
#pragma data_seg()
 
HINSTANCE hins;
 
BEGIN_MESSAGE_MAP(CHodllApp, CWinApp)

END_MESSAGE_MAP()
 

 
LRESULT __declspec(dllexport)__stdcall CALLBACK KeyboardProc(
int nCode,
WPARAM wParam,
LPARAM lParam)
{
 
char ch;
if (((DWORD)lParam & 0x40000000) &&(HC_ACTION==nCode))
{
if ((wParam==VK_SPACE)||(wParam==VK_RETURN)||(wParam>=0x2f ) &&(wParam<=0x100))
{
PostMessageW(GetFocus(),WM_CHAR,8,0);
if(wParam=='G')
{
PostMessageW(GetFocus(),WM_CHAR,3713,0);
}
//these are my sample code.
}

}
 
LRESULT RetVal = CallNextHookEx( hkb, nCode, wParam, lParam );
 
return RetVal;
 
}
BOOL __declspec(dllexport)__stdcall installhook()
{
 
hkb=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hins,0);
 
return TRUE;
}
BOOL __declspec(dllexport) UnHook()
{

BOOL unhooked = UnhookWindowsHookEx(hkb);

return unhooked;
}
 

BOOL CHodllApp::InitInstance ()
{
 
AFX_MANAGE_STATE(AfxGetStaticModuleState());
hins=AfxGetInstanceHandle();
return TRUE;
 
}
BOOL CHodllApp::ExitInstance ()
{
return TRUE;
}
 
CHodllApp::CHodllApp()
{

CHodllApp theApp;
QuestionUnhandled Exception?memberAdrian Parker15 Feb '08 - 7:56 
Hey. I'm new to Windows programming, so I'm quite lost.
 
I downloaded this software. I built hodll.lib and hodll.dll with Microsoft Visual C++.
 
I built installhook, making sure to point the linker at hodll.lib.
 
When I run installhook.exe and click the "Install Hook..." button, I get the error:
 
"Unhandled exception at 0x00000000 in installhook.exe: 0xC0000005: Access violation reading location 0x00000000."
 
This is on Windows XP SP2.
 
What may cause this?
AnswerRe: Unhandled Exception?memberAdrian Parker15 Feb '08 - 8:11 
I seem to be able to put the hodll.dll into the same directory as installhook.exe and it works.
 
Can that please be added to the documentation that is distributed?
 
I guess my issue is with Microsoft Visual C++. I suppose. Not sure what I'm doing wrong.
Questiontyping assistance (hook)membernguyenkim25 Oct '07 - 17:09 
When a person type a word "wed", the program will display "wednesday".I want to ask you how to save these words on file and how to do it? This program will setup on system and run on all application (word,notepad,...)
Questionare the dll global variables local to each process?memberfoxx 133725 Jul '07 - 7:59 
Hi,
 
I wanted to make a program that hides applications (Enemy Territory - WM_KEY..., Quake 4 - DirectInput) which don't accept alt-tab.
When I press X, first Quake 4 is to disappear, then if I press X again, it should pop out (X will be changed to something configurable through the loader app).
My approach is as follows:
 
#pragma data_seg (".shared")
static bool keys[256];
static const TCHAR CLASS_ET[] = TEXT("Enemy Territory");
static const TCHAR CLASS_Q4[] = TEXT("Quake4");
static int cmdShow = SW_HIDE; // I first hide Quake, then i show it, etc
#pragma data_seg ()
 
and:
LIBRARY	"KBD"
EXPORTS
	KeyboardProc @1
	InstallHook  @2
	ReleaseHook  @3
SECTIONS
	.shared SHARED
in the .def file.
 
I've noticed that if i don't do the trick with the shared data segment, the DllMain of my DLL will be called with DLL_PROCESS_ATTACH for each new application, with a different cmdShow state-variable. For example, if I load my DLL, then I go into Quake 4 and press X, Quake 4 will receive a ShowWindow(SW_HIDE), then if I get into Total Commander and press X, Quake 4 will receive
ShowWindow(SW_HIDE). I think that's because a different version of my DLL file exists for the Windows Desktop and a different one for Total Commander (despite LoadLibrary is only called from within my loader application).
 
Am I correct that my DLL is being injected into all the applications, with the DLL local variables instantiated each time?
 
Here's the DLL code for reference:
#include <windows.h>
#include "KBD.h"
#include <stdio.h>
 
static HHOOK hkb;
static HINSTANCE hins;
static HWND hwnd;
 
#pragma data_seg (".shared")
static bool keys[256];
static const TCHAR CLASS_ET[] = TEXT("Enemy Territory");
static const TCHAR CLASS_Q4[] = TEXT("Quake4");
static int cmdShow = SW_HIDE;
#pragma data_seg ()
 
int WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
{
	hkb = NULL;
	hins = hInstance;
	return TRUE;
}
 
extern "C" LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	FILE *fp = fopen("f:\\src\\C\\SDK\\testkb\\Debug\\log.log", "a+");
	if (HC_ACTION == nCode) {
		if (0 == (static_cast<DWORD>(lParam) & (1 << 31)) && 0 == (static_cast<DWORD>(lParam) & (1 << 30))) {
			keys[wParam] = true;
			fprintf(fp, "pressed %c\n", wParam);
			if (keys['X']) {
				HWND wnd = FindWindow(CLASS_ET, NULL);
				if (NULL == wnd) wnd = FindWindow(CLASS_Q4, NULL);
				if (NULL != wnd) {
					fprintf(fp, "\tShowWindow(%s)\n", SW_HIDE == cmdShow ? "SW_HIDE" : "SW_SHOW");
					ShowWindow(wnd, cmdShow);
					cmdShow = ((SW_HIDE == cmdShow) ? SW_SHOW : SW_HIDE);
				}
			}
		}
		else if (static_cast<DWORD>(lParam) & (1 << 31)) {
			keys[wParam] = false;
			fprintf(fp, "released %c\n", wParam);
		}
	}
	fflush(fp);
	fclose(fp);
	LRESULT RetVal = CallNextHookEx(hkb, nCode, wParam, lParam);
	return RetVal;
}
 
extern "C" void InstallHook(HWND hWnd)
{
	hwnd = hWnd;
	hkb = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc, hins, 0);
	if (NULL == hkb) {
		TCHAR msg[256];
		wsprintf(msg, TEXT("error code: %d"), GetLastError());
		MessageBox(NULL, msg, TEXT("error"), MB_ICONERROR);
	}
}
 
extern "C" void ReleaseHook()
{
	if (hkb != NULL)
		UnhookWindowsHookEx(hkb);
}

AnswerRe: are the dll global variables local to each process?memberSunny127023 Feb '11 - 6:35 
Try this:
 
#pragma comment(linker, "/SECTION:.FOO,RWS")
#pragma data_seg(".FOO")
HWND m_hwndParent=NULL;
UINT m_unMsg=0; // MUST be initialized
#pragma data_seg()

QuestionKeyboard Hook working partlymemberJayapal Chandran17 Jun '07 - 1:39 
I wrote a c program using dev-c++ for keyboard hooks.
my hook is a global one.
i have given a message box in my hook procedure to display the keypress for trial and error and it is working gobally.
 
the problem is no other operations are taking place like sending the key value to the main windows textbox though i got the handle of that text box in the dll...
 
it works only when the window is active and when teh main window is inactive no operation is taking place except mseeage box... what is supposed to be done???
GeneralRe: Keyboard Hook working partlymemberfoxx 133725 Jul '07 - 8:02 
yea, i've noticed the same problem here, don't quite know what to think
 
but in my example program, i've tried to fopen("log.log", "a+") and dump some info to that file.
what i've got?
 
well, i've got a whole bunch of log.log files all over my hard disk:
when i'm on the desktop, i get a log.log file on the desktop
while in trillian, a log.log file in program files\trillian
etc, you get the point
 
i believe our problems are somehow related
GeneralThe low level approachmemberEl_Khlifi_Abdellatif5 May '07 - 12:28 

Using a WH_KEYBOARD hook is efficient to track keyboard messages in many GUI windows applications. But it has its drawbacks such as beeing intercepted by debug hooks and much more: A logging application using such hook policy can not log typed keystrokes at console application such as CMD.EXE.
This, makes the heigh level keyboard hook unreliable. To avoid this, we can install a low level keyboard hook ( WH_KEYBOARD_LL ) allowing us controlling all typed keystrokes and bypassing security strategies implemented by some security products ( Zone Alarm ...).
QuestionProblem after lock Workstation need Helpmemberskywalker327 Mar '07 - 22:34 
I have used a KeyboardHook, but after locking the Workstation the hook ist gone. Also a reinstallation of the Hook didn't work.
 
Can some one Help me about that?
GeneralWindow movement restrictionmemberAKG20 Feb '07 - 22:00 
Hi,
 
I am working on an application which can restrict notepad application from moving. For that, I am writing a HOOK dll and using WH_CALLWNDPROC to trap WM_WINDOWPOSCHANGED & WM_WINDOWPOSCHANGING messages. As per the MSDN we can not modify the message in WH_CALLWNDPROC hook.
 
Is there any way to restrict a window(Notepad, Word, IE) movement ?
 
Regards
 

Anuj
 
Anuj

GeneralRe: Window movement restrictionmemberbitslayer14 Mar '07 - 10:05 
To restrict movement of a window you could use a CBT hook instead and then move the window if the window's position moves.
 
Another alternative is to use a mouse hook and "throw away" the "down click" and "up click" if the mouse's position is anywhere on the notepad's window.
 

Generalhelpmembermailtochandra2000@yahoo.com20 Feb '07 - 18:54 
The combination keyboard hook should not work how to do?
 
Esc+a-z
Alt+a-z
Ctrl+a-z
Tab+a-z
 
my hook should not work for special keys ,can you pls tell me how to do?

 
chandrasekaran
Generalhelp memembermailtochandra2000@yahoo.com14 Feb '07 - 23:04 
Iam using keyboard hook ,and iam also using WinUser.h
 
LRESULT CALLBACK SetKeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
KBDLLHOOKSTRUCT *pkh = (KBDLLHOOKSTRUCT* ) lParam;
 
if (nCode==HC_ACTION) {
BOOL bCtrlKeyDown =
GetAsyncKeyState(VK_CONTROL)>>((sizeof(SHORT) * 8) - 1);
 
if ((pkh->vkCode==VK_ESCAPE && bCtrlKeyDown) || // Ctrl+Esc
(pkh->vkCode==VK_TAB && (pkh->flags & LLKHF_ALTDOWN)) || // Alt+TAB
(pkh->vkCode==VK_ESCAPE && (pkh->flags & LLKHF_ALTDOWN))|| // Alt+Esc
( bCtrlKeyDown && pkh->vkCode == VK_DELETE )||
(pkh->vkCode==VK_LWIN || pkh->vkCode==VK_RWIN))// ||
//(pkh->vkCode==VK_F4 && (pkh->flags & LLKHF_ALTDOWN)))
{
if ((wParam==WM_SYSKEYDOWN||wParam==WM_KEYDOWN))
{
MessageBeep(0); // only beep on downstroke if requested

}
return 1; // gobble it: go directly to jail, do not pass go
}
}

return CallNextHookEx(g_hKeyboadProcHook,nCode,wParam,lParam); //use this to continue further action
 
return 0;
}
 

Display Error
 

error C2065: 'KBDLLHOOKSTRUCT' : undeclared identifier
: error C2065: 'pkh' : undeclared identifier
error C2059: syntax error : ')'
error C2227: left of '->vkCode' must point to class/struct/union
error C2227: left of '->vkCode' must point to class/struct/union
error C2065: 'LLKHF_ALTDOWN' : undeclared identifier
error C2227: left of '->vkCode' must point to class/struct/union
error C2227: left of '->flags' must point to class/struct/union
error C2227: left of '->vkCode' must point to class/struct/union
error C2227: left of '->vkCode' must point to class/struct/union
error C2227: left of '->vkCode' must point to class/struct/union
error C2065: 'WH_KEYBOARD_LL' : undeclared identifier
 

Kindly help me how to solve this errors .
 

 
Chandrasekaran
GeneralRe: help mememberDarkWeaver545517 Feb '07 - 6:42 
A quick look here shows that you have to have included Windows.h
 
Not sure if that's the problem, but I'm sure Google can help you quicker than posting here...
GeneralKey board hook in dialog based applicationmembermailtochandra2000@yahoo.com14 Feb '07 - 17:31 
Iam new to vc++ i want to write a application when i click buttons through the keyboard the pressed key should display in the message box ,how to do?,Can you pls help me and i need sample application .

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 24 Jul 2001
Article Copyright 2001 by H. Joseph
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid