我正在尝试为WH_CALLWNDPROC实现一个钩子过滤功能,以便在消息到达单词应用程序之前拦截它们。
我的代码如下:
Imports System.Runtime.InteropServices
''Constants Definition''
Private Const WH_CALLWNDPROC As Integer = 4
Private Const HC_ACTION As Integer = 0
Private Const WM_DESTROY As Integer = &H2
Private Const WM_ACTIVATEAPP As Integer = &H1C
Private IsHooked As Boolean
''DLL Definition
<DllImport("user32.dll")> _
Private Shared Function SetWindowsHookEx(idHook As Integer, callback As MyWndProcDel, hInstance As IntPtr, threadId As UInteger) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function UnhookWindowsHookEx(hInstance As IntPtr) As Boolean
End Function
<DllImport("user32.dll")> _
Private Shared Function CallNextHookEx(idHook As IntPtr, nCode As Integer, wParam As Integer, lParam As IntPtr) As IntPtr
End Function
<DllImport("kernel32.dll")> _
Private Shared Function GetCurrentThreadId() As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function GetWindowThreadProcessId(ByVal hwnd As IntPtr, _
ByRef lpdwProcessId As Integer) As Integer
End Function
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer<System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)> _
Public Structure CWPSTRUCT
Public lParam As IntPtr
Public wParam As IntPtr
Public message As Integer
Public hWnd As IntPtr
End Structure
Private fltrFunc As MyWndProcDel = AddressOf myWndProc
Private Shared lpPrevWndProc As IntPtr = IntPtr.Zero
Private Delegate Function MyWndProcDel(nCode As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr
Public Sub SetWndProcHook()
Dim PID As Integer
Dim WordWND as Long
If IsHooked Then
MsgBox("Already Hooked")
Else
WordWND = FindWindow(vbNullString, "Document1")
lpPrevWndProc = SetWindowsHookEx(WH_CALLWNDPROC, fltrFunc, Nothing, GetWindowThreadProcessId(WordWND, PID))
IsHooked = True
End If
End Sub
Public Function myWndProc(ByVal ucode As Long, ByVal wParam As IntPtr, lParam As IntPtr) As IntPtr
If ucode >= 0 Then
Dim cwp As CWPSTRUCT = DirectCast(Marshal.PtrToStructure(lParam, GetType(CWPSTRUCT)), CWPSTRUCT)
Select Case cwp.message
Case WM_ACTIVATEAPP
cwp.message = 0
MsgBox(cwp.message)
End Select
Else
CallNextHookEx(lpPrevWndProc, ucode, wParam, lParam)
End If
End Function
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
SetWndProcHook()
End Sub
Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
If IsHooked Then
UnhookWindowsHookEx(lpPrevWndProc)
End If
End Sub
我的问题如下: lpPrevWndProc = SetWindowsHookEx(WH_CALLWNDPROC,fltrFunc,Nothing,GetWindowThreadProcessId(WordWND,PID)) 返回0,表示该函数执行失败。 GetWindowThreadProcessId(WordWND,PID))返回打开的Word应用程序的进程ID。返回的值是正确的(我已使用Spy ++实用程序检查过它)。 如果我用GetCurrentThreadId()替换GetWindowThreadProcessId(WordWND,PID))我可以挂钩我正在处理的窗体的WH_CALLWNDPROC。 (在这种情况下,SetWindowsHookEx返回钩子过滤函数的句柄。(表示执行成功)
感谢任何帮助