在 .Net 中使用低级键盘钩子屏蔽 Win 键
在微软的文档《HOW TO:在 Visual C# .NET 中设置窗口挂钩 》中,对 .NET 框架中的钩子有如下描述:
在 .NET 框架中不支持全局挂钩
您无法在 Microsoft .NET 框架中实现全局挂钩。若要安装全局挂钩,挂钩必须有一个本机动态链接库 (DLL) 导出以便将其本身插入到另一个需要调入一个有效而且一致的函数的进程中。这需要一个 DLL 导出,而 .NET 框架不支持这一点。托管代码没有让函数指针具有统一的值这一概念,因为这些函数是动态构建的代理。
使用钩子需要用到 3 个 Win32 API 函数: SetWindowsHookEx,CallNextHookEx和UnhookWindowsHookEx,在 C# 中需要声明一下:
class Win32API
{
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(IntPtr hhk, int nCode, uint wParam, int lParam);
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int UnhookWindowsHookEx(IntPtr hhk);
}
struct KeyBoardHookStruct
{
public UInt32 vkCode;
public UInt32 scanCode;
public UInt32 flags;
public UInt32 time;
public UInt32 dwExtraInfo;
}
delegate int HookProc(int nCode, uint wParam, int lParam);
class MaskKey
{
private const int WH_KEYBOARD_LL = 13;
private const int HC_ACTION = 0;
private const int VK_LWIN = 0x5B;
private const int VK_RWIN = 0x5C;
private IntPtr m_hook;
public bool StartMaskKey()
{
if (m_hook != IntPtr.Zero) return false;
IntPtr pInstance = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().ManifestModule);
m_hook = Win32API.SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, pInstance, 0);
if (m_hook == IntPtr.Zero) return false;
return true;
}
public bool StopMaskKey()
{
if (m_hook != IntPtr.Zero)
{
int succeed = Win32API.UnhookWindowsHookEx(m_hook);
if (succeed == 0) return false;
m_hook = IntPtr.Zero;
}
return true;
}
private int LowLevelKeyboardProc(int nCode, uint wParam, int lParam)
{
if (nCode == HC_ACTION)
{
KeyBoardHookStruct khs = (KeyBoardHookStruct)Marshal.PtrToStructure(
new IntPtr(lParam), typeof(KeyBoardHookStruct));
if (khs.vkCode == VK_LWIN || khs.vkCode == VK_RWIN) return 1;
}
return Win32API.CallNextHookEx(m_hook, nCode, wParam, lParam);
}
}
编译成功后会发现程序仍然无法正确运行,这是因为需要修改 VS2005的编译选项,右键选择项目属性,在 Debug 选项卡中取消 Enable the Visual Studio hosting process 前面的选中标记, 重新编译运行,键盘的左右 Win 键已经不能使用了。
0 Comments:
Post a Comment