PRB: Cannot Alter Messages with WH_KEYBOARD Hook
ID: Q33690
|
The information in this article applies to:
-
Microsoft Win32 Software Development Kit (SDK)
-
Microsoft Windows Software Development Kit (SDK) versions 3.0, 3.1
-
Microsoft Windows 2000
SYMPTOMS
After creating a program that uses the WH_KEYBOARD hook function to
intercept a user's keystrokes and changing the wParam value before passing
the hook code on to CallNextHookEx() (DefHookProc() for Windows 3.0),
whichever application currently has the focus still receives the original
character typed in rather than the translated character.
CAUSE
Keyboard messages cannot be altered with the WH_KEYBOARD hook. All that can
be done is to "swallow" the message (return TRUE) or have the message
passed on (return FALSE). In a keyboard hook function, when you return
CallNextHookEx() or DefHookProc(), you are passing the event to the next
hook procedure in the potential hook chain, and giving it a chance to look
at the event to decide whether or not to discard it. You are not passing
the message to the system as if you had called DefWindowProc() from a
Window procedure.
RESOLUTION
NOTE: In the discussion below, ignore the references to the WH_CALLWNDPROC
hook for Win32-based applications. Win32 does not allow an application to
change the message in a CallWndProc, as 16-bit Windows does.
To change the value of wParam (and hence the character message that is
received by the window with the focus), you must install the WM_GETMESSAGE
and WH_CALLWNDPROC hooks. The WH_GETMESSAGE hook traps all messages
retrieved via GetMessage() or PeekMessage(). This is the way actual
keyboard events are received: the message is placed in the queue by Windows
and the application retrieves it via GetMessage() or PeekMessage().
However, because applications can send keyboard messages with
SendMessage(), it is best to also install the WH_CALLWNDPROC hook. This
hook traps messages sent to a window via SendMessage().
These hooks pass you the address of the message structure so you can change
it. In Windows 3.0, when you return DefHookProc() within a WH_GETMESSAGE or
WH_CALLWNDPROC hook procedure, you are passing the address of the
(potentially altered) contents of the message structure on to the next hook
function in the chain. In Windows 3.1 and Win32, you should use the
CallNextHookEx() function to pass the hook information to the next hook
function. If you alter the wParam before passing on the message, this will
change the character message eventually received by the application with
the focus.
NOTE: For Windows 3.0, keep in mind that the hook callback procedure must
be placed in a DLL with fixed code so that it will be below the EMS line
and thus will always be present. If the hook callback procedure is not in a
fixed code segment, it could be banked out when it is called, and this
would crash the system. System-wide hooks in Windows 3.1 and in Win32,
however, must still reside in a DLL.
Additional query words:
Keywords : kbHook kbNTOS kbWinOS2000 kbSDKWin32 kbGrpUser kbWinOS
Version : WINDOWS:3.0,3.1
Platform : WINDOWS
Issue type : kbprb