Windows with Delphi Windows API (94) Windows Filesystem (41) Windows Forms (69) Windows Graphics (38)
Exchange Links About this site Links to us 
|
How can I create a system wide keyboard hook under Win32?
8 comments. Current rating: (4 votes). Leave comments and/ or rate it.
I found the following code posted in a newsgroup. Since it is asked frequently, I add it here.
Comments:
The following example demonstrates creating a system wide windows hook under Win32. The example provides both the code for the system hook dll and an example application. The hook function that we will create will also demonstrate advanced coding techniques such as sharing global memory across process boundaries using memory mapped files, sending messages from the key hook function back to the originating application, and dynamic loading of a dll at runtime.
The example keyboard hook that we create will keep a count of the number of keystrokes a user enters on the keyboard. Further, we will demonstrate trapping the enter key, and passing a message back to the application that initiated the keyboard hook each time the enter key is pressed. Finally, we will demonstrate trapping the left arrow key and instead of letting it through to the current application, we will instead replace it with a right arrow keystroke. (Note: that this can
cause much confusion to a unsuspecting user).
 | |  | | Library TheHook;
uses
Windows, Messages, SysUtils;
type
PHookRec = ^ THookRec;
THookRec = Packed Record
TheHookHandle: HHOOK;
TheAppWinHandle: HWnd;
TheCtrlWinHandle: HWnd;
TheKeyCount: DWord;
end;
var
hObjHandle : THandle;
lpHookRec : PHookRec;
procedure MapFileMemory (dwAllocSize: DWord);
begin
hObjHandle := CreateFileMapping ($FFFFFFFF, Nil, PAGE_READWRITE, 0,
dwAllocSize, 'HookRecMemBlock');
if (hObjHandle = 0) then
begin
MessageBox (0, 'Hook DLL', 'Could not create file map object', mb_Ok);
exit
end ;
lpHookRec := MapViewOfFile (hObjHandle, FILE_MAP_WRITE, 0, 0, dwAllocSize);
if (lpHookRec = Nil) then
begin
CloseHandle (hObjHandle);
MessageBox (0, 'Hook DLL', 'Could not map file', mb_Ok);
exit
end
end;
procedure UnMapFileMemory;
begin
if (lpHookRec <> Nil) then
begin
UnMapViewOfFile (lpHookRec);
lpHookRec := Nil
end ;
if (hObjHandle > 0) then
begin
CloseHandle (hObjHandle);
hObjHandle := 0
end
end;
function GetHookRecPointer : pointer
stdcall;
begin
Result := lpHookRec
end;
function KeyBoardProc (code: Integer; wParam: Integer; lParam: Integer) :
Integer;
stdcall;
var
KeyUp : bool;
{Remove comments for additional functionability
IsAltPressed : bool;
IsCtrlPressed : bool;
IsShiftPressed : bool;
}
begin
Result := 0;
Case code Of
HC_ACTION:
begin
KeyUp := ((lParam and (1 shl 31)) <> 0);
(*Remove comments for additional functionability
if ((lParam and (1 shl 29)) <> 0) then begin
IsAltPressed := TRUE;
end else begin
IsAltPressed := FALSE;
end;
if ((GetKeyState(VK_CONTROL) and (1 shl 15)) <> 0) then begin
IsCtrlPressed := TRUE;
end else begin
IsCtrlPressed := FALSE;
end;
if ((GetKeyState(VK_SHIFT) and (1 shl 15)) <> 0) then begin
IsShiftPressed := TRUE;
end else begin
IsShiftPressed := FALSE;
end;
*)
if (KeyUp <> false) then
begin
inc (lpHookRec^.TheKeyCount)
end ;
Case wParam Of
VK_RETURN:
begin
if (KeyUp <> false) then
begin
PostMessage (lpHookRec^.TheCtrlWinHandle, WM_KEYDOWN, 0, 0);
PostMessage (lpHookRec^.TheCtrlWinHandle, WM_KEYUP, 0, 0)
end ;
Result := 0;
exit
end;
VK_LEFT:
begin
if (KeyUp <> false) then
begin
keybd_event (VK_RIGHT, 0, 0, 0);
keybd_event (VK_RIGHT, 0, KEYEVENTF_KEYUP, 0)
end ;
Result := -1;
exit
end;
end
Result := 0
end;
HC_NOREMOVE:
begin
Result := 0;
exit
end;
end
if (code < 0) then
Result := CallNextHookEx (lpHookRec^.TheHookHandle, code, wParam, lParam)
end;
procedure StartKeyBoardHook
stdcall;
begin
if ((lpHookRec <> Nil) and (lpHookRec^.TheHookHandle = 0)) then
begin
lpHookRec^.TheHookHandle := SetWindowsHookEx (WH_KEYBOARD, @KeyBoardProc,
HInstance, 0)
end
end;
procedure StopKeyBoardHook
stdcall;
begin
if ((lpHookRec <> Nil) and (lpHookRec^.TheHookHandle <> 0)) then
begin
if (UnHookWindowsHookEx (lpHookRec^.TheHookHandle) <> false) then
begin
lpHookRec^.TheHookHandle := 0
end
end
end;
procedure DllEntryPoint (dwReason: DWord);
begin
Case dwReason Of
Dll_Process_Attach:
begin
hObjHandle := 0;
lpHookRec := Nil;
MapFileMemory (sizeof (lpHookRec^))
end;
Dll_Process_Detach:
begin
UnMapFileMemory
end;
end
end;
Exports
KeyBoardProc name 'KEYBOARDPROC',
GetHookRecPointer name 'GETHOOKRECPOINTER',
StartKeyBoardHook name 'STARTKEYBOARDHOOK',
StopKeyBoardHook name 'STOPKEYBOARDHOOK';
begin
DLLProc := @DllEntryPoint;
DllEntryPoint (Dll_Process_Attach)
end.
| |  | |  |
Comments:
|
avvaikuna@yahoo.com from Singapore
|
|
|
|
Could any one tell me where is this project full source code file?
|
|
anonymous from Iran
|
|
|
|
I need to disable # Key In my KeyBoard.
Please Help me .
Note: I am using win Xp Sp1.
Zolfagharsoft@yahoo.com
|
|
kia
|
 |
|
|
Hei nice code there, well for all those that doesn
t know what is this code i think i can help.
Start Delphi -> New -> Other... -> select DLL,
This code is a *.DLL(dynamic link library) this could be loaded by
any program made in C#, C++, VB(not sure coz it sux big time), etc.
compile this code then u obtain a project1.dll file, rename as u want
then make another program that loads dll and sends the command
to hook keyboard.
How can u use a dll in ur program? search on the net 'dll+use+delphi' u will
find some interesting articles there.
|
2007-02-28, 01:45:37 (updated: 2007-02-28, 01:46:15) |
anonymous from India
|
|
|
|
i need to keep track of all the key strokes available in browser...can u help me but in vc++ only
|
|
anonymous from Israel
|
|
|
|
I wish I have it written in C or C++
|
|
bounthongv@gmail.com from Lao People's Democratic Republic
|
 |
|
|
Hi, it is great, I find it very useful.
I have tried with this example, t is good for simulation of keyboard stoke. If anyone knows how we can do to send char (as we were typing it) which has higher virtual code let say 166 or something. I tried this, it does not work. And also, how the program would be, if we want to send unicode character which can have have very high number of code.
Any advises would be very appreciated.
Thong
|
|
bounthongv@gmail.com from Lao People's Democratic Republic
|
 |
|
|
Hi, it is great, I find it very useful.
I have tried with this example, t is good for simulation of keyboard stoke. If anyone knows how we can do to send char (as we were typing it) which has higher virtual code let say 166 or something. I tried this, it does not work. And also, how the program would be, if we want to send unicode character which can have very high number of code.
Any advises would be very appreciated.
Thong
|
|
anonymous from Hungary
|
 |
|
|
; -signes are missing after procedure StartKeyBoardHook; <<= here
stdcall;
|
|