通过George Mamaladze阅读c#“全局鼠标键钩”源代码我想了解一些代码是如何工作的。这里是“柯拉”通常扩展回调函数?
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委托实例保持参照拉姆达,从而在乔治的代码MyProc的方法是什么?
下面是斯蒂芬·托布的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);
}
他们应该做到同样的事情更简单的方法。什么是乔治到这个扭曲的东西?解释可能有助于我的头晕或呼吸短促。
乔治Mamaladze的解决方案看起来不可靠,他如何确保'hookProc'不会得到GC'ed?仅仅因为这个原因,我会更信任Stephen Toub的代码。 – Lukazoid
@Lukazoid现在我没有说“通常”关于代码**,但快速浏览mamaladze代码并不能揭示这种机制,这是lambda的使用,我不知道 –
这是一个合理的问题,可怜的标题,我建议你编辑 – Steve