我正在使用我从这个博客获得的课程: http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)vkCode);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
这个函数获取单个键的密钥代码,我想改变它,所以我可以捕获ctrl + C所以我改变了上面的函数如下:
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if ((Keys)(vkCode) == Keys.C && (Control.ModifierKeys == Keys.Control))
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)vkCode);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
问题是Control.ModifierKeys总是返回NONE,我搜索任何结果太多了,我想要注意我在课程中使用此代码在解决方案的单独模块中。我在这做什么,请提供解决方案。
答案 0 :(得分:1)
是的,这通常会出错,尤其是当您的程序本身没有GUI或使用隐藏窗口时。 Windows维护每个进程的键盘状态,在程序收到键盘消息时更新。这是必要的,因为键击存储在消息队列中并且稍后由程序检索,有时甚至更晚。键盘钩子的问题在于它是另一个获取消息的进程,而不是你的。你仍然有陈旧的键盘状态。
为了使其真正可靠,您需要知道其他进程的键盘状态。但这不是你可以得到的东西,GetKeyboardState()函数只允许检索你自己的状态。这通常使得将键击转换为键入键非常困难。 WH_KEYBOARD钩子是一个更好的解决方案,但你不能在C#中编写这样的钩子。
解决方法是自己跟踪Control键的状态。或者通过pinvoking GetAsyncKeyState()来检查Control键的实际无缓冲状态。
答案 1 :(得分:0)
这对你不起作用!
Control.ModifierKeys的实现只调用Windows API函数GetKeyState()三次,依次调用参数0x10,0x11和0x12,并适当地调整结果。
但是状态与正在处理来自消息队列的消息有关。
我认为您需要使用PInvoke来调用Windows API函数GetAsyncKeyState()。