-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathHookHelper.bas
105 lines (73 loc) · 3.99 KB
/
HookHelper.bas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
Attribute VB_Name = "HookHelper"
Option Explicit
' Subclassing Without The Crashes from vbAccelerator
' http://www.vbaccelerator.com/home/vb/Code/Libraries/Subclassing/SSubTimer/article.asp
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Private Declare Function GetProp Lib "user32" Alias "GetPropA" _
(ByVal hWnd As Long, ByVal lpString As String) As Long
Private Declare Function SetProp Lib "user32" Alias "SetPropA" _
(ByVal hWnd As Long, ByVal lpString As String, ByVal hData As Long) As Long
Private Declare Function RemoveProp Lib "user32" Alias "RemovePropA" _
(ByVal hWnd As Long, ByVal lpString As String) As Long
Private Declare Function SetWindowLongW Lib "user32" _
(ByVal hWnd As Long, ByVal nIndex As Long, ByVal wNewWord As Long) As Long
Private Const HOOK_OBJECT_REFERENCE As String = "HOOK_OBJ"
Private Const OLD_WINDOW_PROC As String = "OLD_PROC"
Private m_logger As SeverityLogger
Private Property Get Logger() As SeverityLogger
If m_logger Is Nothing Then
Set m_logger = LogManager.GetLogger("HookHelper")
End If
Set Logger = m_logger
End Property
Public Function CallOldWindowProcessor(sourcehWnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim oldProcessorPointer As Long: oldProcessorPointer = GetProp(sourcehWnd, OLD_WINDOW_PROC)
CallOldWindowProcessor = CallWindowProc(oldProcessorPointer, sourcehWnd, msg, wParam, lParam)
End Function
Public Sub UnhookWindow(ByVal sourcehWnd As Long)
Dim oldWindowProcedure As Long: oldWindowProcedure = GetProp(sourcehWnd, OLD_WINDOW_PROC)
If (oldWindowProcedure <> 0) Then
Call SetWindowLongW(sourcehWnd, GWL_WNDPROC, oldWindowProcedure)
End If
End Sub
Public Function HookWindow(ByVal sourcehWnd As Long, hookObj As IHookSink) As Long
'Exit Function
'set the property, 'HOOK_OBJ' to the pointer of the hookObj on the source hWnd
Call SetProp(sourcehWnd, HOOK_OBJECT_REFERENCE, PtrFromObject(hookObj))
Dim oldWindowProcedure As Long: oldWindowProcedure = GetWindowLong(sourcehWnd, GWL_WNDPROC)
'set the property, 'OLD_PROC' to the pointer of the old/vb6 window procedure
Call SetProp(sourcehWnd, OLD_WINDOW_PROC, oldWindowProcedure)
'switch the default vb6 window processor with the global callback
HookWindow = SetWindowLongW(sourcehWnd, GWL_WNDPROC, AddressOf CallbackFunctionForAllWindows)
End Function
Private Function CallbackFunctionForAllWindows(ByVal hWnd As Long, ByVal msg As Long, ByVal wp As Long, ByVal lp As Long) As Long
Dim hookObject As IHookSink
Dim hookObjectPointer As Long: hookObjectPointer = GetProp(hWnd, HOOK_OBJECT_REFERENCE)
If hookObjectPointer Then
'Get the hookObj from the pointer
Set hookObject = ObjectFromPtr(hookObjectPointer)
'Call the new window processor and pass the result to the caller (windows)
CallbackFunctionForAllWindows = hookObject.WindowProc(hWnd, msg, wp, lp)
Else
Logger.Error "Hook object not found", "CallbackFunctionForAllWindows", msg
End If
End Function
Private Property Get PtrFromObject(ByRef oThis As IHookSink) As Long
' Return the pointer to this object:
PtrFromObject = ObjPtr(oThis)
End Property
Private Property Get ObjectFromPtr(ByVal lPtr As Long) As IHookSink
Dim oThis As IHookSink
' Turn the pointer into an illegal, uncounted interface
CopyMemory oThis, lPtr, 4
' Do NOT hit the End button here! You will crash!
' Assign to legal reference
Set ObjectFromPtr = oThis
' Still do NOT hit the End button here! You will still crash!
' Destroy the illegal reference
CopyMemory oThis, 0&, 4
' OK, hit the End button if you must--you'll probably still crash,
' but this will be your code rather than the uncounted reference!
End Property