This code uses a C++ dll and an ActiveX VB control to hook external programs.
Note: The source is included for both in case you want to change it or just learn from it.
There is another post on this subject that deals with a system wide hook. Here I am posting complete code that allows the user to perform a thread-specific hook on an external program from their VB program and respond to any messages sent to that external program from within the VB Program.
In this method the hook is set in the C++ code so we don't need to mess with passing procedure addresses back and forth. This code handles two types of hooks, and forwards messages along with their complete data structures back to your VB code. This code also allows the VB user to change messages where permitted. See the next post in this thread for more details on how the code works.
There are two parts to the code: a DLL written in C++ (don't worry, it's already compiled for you) that is injected into the thread of the target program, and an ActiveX control that handles communication between the DLL and the developer's VB program.
These components can be used as-is to trap any message sent to external programs, or since I am including the source, can be modified. They handle two types of hooks:
WH_CALLWNDPROC - For sent messages
WH_GETMESSAGE - For posted messages, messages can be changed before being sent on to App
After hooking the target App and setting the messages to monitor, an event will be triggered in the control for each trapped message. The data for each message is supplied to the events in it's original data structure.
After unzipping the files, register the dll and the ocx component. Instructions for using the ActiveX control are included in an html file 'ReadMe.htm'
If anyone finds a problem with this code then let me know so I can fix it.
The following is an example of how to use the Hook Control in a VB App. For another example see Adding Submenus to External Programs.
Example:
This example hooks the text area in Notepad
start a VB project, add the hookcontrol to your tool box and drag it over to your own app.
Add two command buttons cmdHook and cmdUnHook
Before running your app, start Notepad.exe.
NOTES:VB Code:
Option Explicit Const ParentCaption = "Untitled - Notepad" Const ChildClassName = "Edit" Const ChildCaption = "" Private Const WM_LBUTTONDOWN = &H201 Private Const WM_LBUTTONUP = &H202 Private Const WM_SETTEXT = &HC Private Const WM_CHAR = &H102 Private Const WM_KEYDOWN = &H100 Private Const WM_KEYUP = &H101 Private Sub cmdHook_Click() 'This routine sets the hook to monitor specified messages Dim lhWnd As Long With HookControl 'handle to main window lhWnd = .GetTopLevelHandle(ParentCaption) While lhWnd = 0 If MsgBox("Open Notepad", vbOKCancel) = vbCancel Then Exit Sub lhWnd = .GetTopLevelHandle(ParentCaption) Wend 'monitor the following message(s) .AddMessage WM_CHAR, "WM_CHAR" 'handle to the textbox we want to hook .TargethWnd = .GetChildHandle(ChildCaption, ChildClassName, lhWnd) 'Set the hooks If .SetHook Then cmdHook.Enabled = False cmdUnHook.Enabled = True Else cmdUnHook.Enabled = False cmdHook.Enabled = True MsgBox "Error Installing Hook." End If End With End Sub Public Sub cmdUnHook_Click() 'This routine removes the hook If HookControl.RemoveAllHooks Then cmdUnHook.Enabled = False cmdHook.Enabled = True Else cmdHook.Enabled = False cmdUnHook.Enabled = True MsgBox "Error Uninstalling Hook." End If End Sub 'Here is where the posted messages will arrive 'we cannot discard posted messages, but can change them Private Sub HookControl_PostedMessage( _ uMsg As Long, _ wParam As Long, _ lParam As Long _ ) Dim Msg 'display the messages as they arrive For Each Msg In HookControl.Messages If uMsg = Msg.Value Then Debug.Print "Posted: " & Msg.Label & " " & wParam Exit For End If Next 'Here is an example of how to change a message 'Change all a's to ‘X’ If uMsg = WM_CHAR And wParam = Asc("a") Then wParam = Asc("X") 'change message to WM_NULL if key is "s" so Notepad ignores it If uMsg = WM_CHAR And wParam = Asc("s") Then uMsg = WM_NULL End Sub 'reset our buttons if notepad is closed and hook is released Private Sub HookControl_UnHook() cmdHook.Enabled = True cmdUnHook.Enabled = False End Sub
Fixed problem with multiple instances (2/22/2005)
Added Thread local storage to dll to help with multiple instances (2/27/2005)
Fixed problem with decleration in dll that was causing control to crash (3/08/2005)
Fixed problem that prevented control from being used in an array. (10/12/2005)
Uploaded the latest dll source code




Reply With Quote