通過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