扩展回调函数

本文关键字:函数 回调 扩展 | 更新日期: 2023-09-27 18:17:41

阅读George Mamaladze c#"全局鼠标键钩"源代码,我试图弄清楚一些代码是如何工作的。这里是"corazon"一般

public delegate IntPtr HookProcedure(int nCode, IntPtr wParam, IntPtr lParam);
private static Handle HookGlobal(int hookId, Callback callback)
{
    HookProcedure hookProc = (code, param, lParam) => MyProc(code, param, lParam, callback);
    Handle handle = SetWindowsHookEx(
            hookId,
            hookProc,
            Process.GetCurrentProcess().MainModule.BaseAddress,
            0);
    return handle;
}
private static IntPtr MyProc(int nCode, IntPtr wParam, IntPtr lParam, Callback callback)
{            
    var callbackData = new CallbackData(wParam, lParam);
    bool continueProcessing = callback(callbackData);
    if (!continueProcessing) 
    { return new IntPtr(-1); }
    return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam);
}

由WinApi函数SetWindowsHookEx设置的消息泵将使用消息数据调用MyProc方法。

HHOOK WINAPI SetWindowsHookEx(
  _In_ int       idHook,
  _In_ HOOKPROC  lpfn,
  _In_ HINSTANCE hMod,
  _In_ DWORD     dwThreadId
);

根据MSDN, HOOKPROC类型定义了指向回调函数的指针。(例子…)MouseProc是应用程序定义的或库定义的函数名的占位符。(有几个占位符过程回调…)

LRESULT CALLBACK MouseProc(
    _In_ int    code,
         WPARAM wParam,
    _In_ LPARAM lParam
);

是否hookProc委托实例保持对lambda的引用,从而在George的代码中对MyProc方法的引用?
以下是Stephen Taub的MSDN博客

中的一个更简单的方法
private delegate IntPtr HookProcedure(int nCode, IntPtr wParam, IntPtr lParam);
private static HookProcedure procedure = Callback;
private static IntPtr _hookID = IntPtr.Zero;        
public static void SetHook()
{
    _hookID = SetWindowsHookEx(
        WH_KEYBOARD_LL,
        procedure,
        Process.GetCurrentProcess().MainModule,
        0);        
}
private static IntPtr Callback(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0)
    {
    }
    return CallNextHookEx(_hookId, nCode, wParam, lParam);
}

它们应该达到同样的目的。乔治要这些扭曲的东西干什么?解释一下可能对我头晕或呼吸短促有帮助。

扩展回调函数

是否hookProc委托实例保持对lambda的引用,从而在George的代码中对MyProc方法的引用?

不,它没有,hookProc可能符合垃圾收集的条件,只要函数退出,你的钩子将不再工作,你需要保持一个引用委托像Stepen的代码来阻止它的发生。