C# 挂接WH_CALLWNDPROC用于Word应用程序
我试图为WH_CALLWNDPROC实现一个钩子过滤函数,以便在消息到达word应用程序之前拦截它们 我的代码如下:C# 挂接WH_CALLWNDPROC用于Word应用程序,c#,vb.net,visual-studio-2010,winapi,C#,Vb.net,Visual Studio 2010,Winapi,我试图为WH_CALLWNDPROC实现一个钩子过滤函数,以便在消息到达word应用程序之前拦截它们 我的代码如下: 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 = &
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=setWindowsHookXwh_CALLWNDPROC,fltrFunc,Nothing,GetWindowThreadProcessIdWordWND,PID
返回0,表示该函数执行失败。
GetWindowThreadProcessIdWordWND,PID正在返回打开的Word应用程序的进程ID。返回的值是正确的,我已使用Spy++实用程序进行了检查。
如果我用GetCurrentThreadId替换GetWindowThreadProcessIdWordWND,PID,我就能够钩住我正在处理的windows窗体的WH_CALLWNDPROC。在本例中,SetWindowsHookEx返回钩子过滤函数的句柄。这表示执行成功
感谢您的帮助Global WH_CALLWNDPROC hook需要将HOOKPROC函数放置到lpfn参数所指向的DLL。但是这种替代方法有许多缺点:1-如何识别消息发送到的句柄?可能消息正在发送到除我的word app 2之外的其他应用程序-在DLL级别实现解决方案会将钩子注入所有系统进程,开销+低性能这不是替代方案,这是必需的。那么我如何截获仅与我的word文档相关的消息?我有句柄ID、进程ID和线程ID如果目标线程在另一个进程中,则必须使用DLL,如@AlexFarber所说。