C# 挂接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 = &

我试图为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 = &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所说。