0

I am using a class i got from this blog: 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);
}

This function get the key code for a single key, i wanted to alter it so i can catch ctrl+C so i altered the above function as follows:

    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);
}

The problem is Control.ModifierKeys always returns NONE, i googled too much with any results, i want to note that i am using this code in class in a separate module in the solution. What am i doing here, please provide a solution.

4

2 回答 2

1

是的,这通常会出错,但尤其是当您的程序本身没有 GUI 或使用隐藏窗口时。Windows 为每个单独的进程维护键盘状态,当程序接收到键盘消息时它会更新。这是必要的,因为击键存储在消息队列中,并在稍后被程序检索,有时甚至更晚。键盘钩子的问题在于它是另一个进程收到消息,而不是你的。你仍然有过时的键盘状态。

为了使其真正可靠,您需要知道其他进程的键盘状态。但这不是你能得到的,GetKeyboardState() 函数只允许允许检索你自己的状态。这通常使得将击键转换为键入键非常困难。WH_KEYBOARD 挂钩是一个更好的解决方案,但您不能在 C# 中编写这样的挂钩。

一种解决方法是自己跟踪 Control 键的状态。或者通过调用 GetAsyncKeyState()来检查 Control 键的实际未缓冲状态。

于 2013-01-10T10:56:41.540 回答
0

那对你不起作用!

Control.ModifierKeys的实现只是调用了Windows API函数GetKeyState() 3次,参数依次为0x10、0x11、0x12,并对结果进行适当的ors。

但是状态与正在处理消息队列中的哪个消息有关。

我认为您需要使用 PInvoke 来调用 Windows API 函数GetAsyncKeyState()

于 2013-01-10T10:36:27.490 回答