using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Reflection;
using
System.Runtime.InteropServices;
using
System.Text;
namespace
HookLib
{
public
static
class
HookHelper
{
public
delegate
int
HookProc
(
int
nCode,
IntPtr
wParam,
IntPtr
lParam
);
public
static
int
HookCallback(
int
nCode,
IntPtr
wParam,
IntPtr
lParam)
{
if
(
IntPtr
.Zero == HookPtr ||
null
== HookId)
{
return
0;
}
if
(nCode >= 0)
{
if
(
null
!= HookCallbackEvent)
{
return
HookCallbackEvent(nCode, wParam, lParam);
}
}
return
CallNextHookEx(HookPtr, HookId.Value, wParam, lParam);
}
public
static
IntPtr
SetWindowsHookEx()
{
if
(
null
== HookId)
{
throw
new
Exception
(
"You must set HookId first!"
);
}
HookPtr = SetWindowsHookEx(
HookId.Value,
KeyboardCallback,
Instance,
0);
return
HookPtr;
}
public
static
bool
UnhookWindowsHookEx()
{
if
(
null
== HookPtr ||
IntPtr
.Zero == HookPtr)
{
throw
new
Exception
(
"HookPtr is null"
);
}
return
UnhookWindowsHookEx(HookPtr);
}
public
static
int
WH_KEYBOARD_LL = 13;
public
static
IntPtr
HookPtr;
public
static
int
? HookId = WH_KEYBOARD_LL;
public
static
event
HookProc
HookCallbackEvent;
public
static
HookProc
KeyboardCallback =
new
HookProc
(
HookHelper
.HookCallback);
public
static
IntPtr
Instance =
Marshal
.GetHINSTANCE(
Assembly
.GetAssembly(
typeof
(
HookHelper
)).GetModules()[0]);
#region
Win32API
[
DllImport
(
"User32.dll"
, CharSet =
CharSet
.Unicode, CallingConvention =
CallingConvention
.StdCall,
SetLastError =
true
)]
public
static
extern
IntPtr
SetWindowsHookEx(
int
idHook,
HookProc
lpfn,
//如果是全局钩子,回调函数应该就写在dll内
IntPtr
hMod,
//如果是全局钩子,应该是包含lpfn方法的dll句柄,注意此句柄要保持生命周期
int
dwThreadId
//如果是全局钩子,置为0;否则应该是保护lpfn方法的进程id
);
[
DllImport
(
"User32.dll"
, CharSet =
CharSet
.Unicode, CallingConvention =
CallingConvention
.StdCall,
SetLastError =
true
)]
public
static
extern
int
CallNextHookEx(
IntPtr
hhk,
int
nCode,
IntPtr
wParam,
IntPtr
lParam
);
[
DllImport
(
"User32.dll"
, CharSet =
CharSet
.Unicode, CallingConvention =
CallingConvention
.StdCall,
SetLastError =
true
)]
public
static
extern
bool
UnhookWindowsHookEx(
IntPtr
hhk
);
[
DllImport
(
"Kernel32.dll"
, CharSet =
CharSet
.Unicode, CallingConvention =
CallingConvention
.StdCall)]
public
static
extern
int
GetLastError();
#endregion
}
}