4

我正在开发一个程序,该程序需要检测用户何时按下键盘或使用鼠标,即使程序已最小化或未聚焦。我想我必须使用windows API,keybd_event(user32),但我不知道如何使用这个事件的“监听器”。我有类似的东西:

    [DllImport("user32.dll")]
    static extern void keybd_event(byte bVk, byte bScan, uint dwFlags,UIntPtr dwExtraInfo);
    void PressKey(byte keyCode)
    {
        //My code here
    }

我做了一些研究,但这是我第一次使用DllImport,所以我不知道如何继续......谢谢(Ps:对不起我的英语不好,这不是我的母语:))

(PPs:我已经阅读了你所有的答案,但是阅读每个链接需要一段时间,所以我今晚会努力,但我想我会找到答案的。无论如何,谢谢大家的链接;))

编辑:所以我刚刚完成了我的代码,它的工作:) 它看起来像:

    [DllImport("user32.dll")]
    public static extern Boolean GetLastInputInfo(ref tagLASTINPUTINFO plii);
    public struct tagLASTINPUTINFO
    {
        public uint cbSize;
        public Int32 dwTime;
    }

    private void timerTemps_Inactif_Tick(object sender, EventArgs e)
    {
        tagLASTINPUTINFO LastInput = new tagLASTINPUTINFO();
        Int32 IdleTime;
        LastInput.cbSize = (uint)Marshal.SizeOf(LastInput);
        LastInput.dwTime = 0;

        if (GetLastInputInfo(ref LastInput))
        {
            IdleTime = System.Environment.TickCount - LastInput.dwTime;
            if (IdleTime > 10000)
            {
                //My code here
            }
        }
    }

感谢您的帮助;)

4

3 回答 3

2

RegisterHotKey通过使用/UnregisterHotKey函数,我总是得到很好的表现。示例代码:

[DllImport("User32")]
public static extern bool RegisterHotKey(
    IntPtr hWnd,
    int id,
    int fsModifiers,
    int vk
);
[DllImport("User32")]
public static extern bool UnregisterHotKey(
    IntPtr hWnd,
    int id
);
public const int MOD_SHIFT = 0x4;
public const int MOD_CONTROL = 0x2;
public const int MOD_ALT = 0x1;
public const int WM_HOTKEY = 0x312;

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_HOTKEY && m.WParam == (IntPtr)0)
    {
        IntPtr lParamCTRLA = (IntPtr)4259842;
        IntPtr lParamB = (IntPtr)4325376;
        if (m.LParam == lParamCTRLA)
        {
            MessageBox.Show("CTRL+A was pressed");
        }
        else if (m.LParam == lParamB)
        {
            MessageBox.Show("B was pressed");
        }
    }
    base.WndProc(ref m);
}

private void Form1_Load(object sender, EventArgs e)
{
    this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);

    RegisterHotKey(this.Handle, 0, MOD_CONTROL, (int)Keys.A);
    RegisterHotKey(this.Handle, 0, 0, (int)Keys.B);
}

private void Form1_FormClosing(Object sender, FormClosingEventArgs e)
{
    UnregisterHotKey(this.Handle, 0);
}

您可以通过模拟所示结构“注册”任意数量的键(或键组合)。所有注册的密钥都将进入条件if (m.Msg == WM_HOTKEY && m.WParam == (IntPtr)0);如果它们被按下(独立于当前选择的程序)。了解被按下的特定键/组合的最简单方法是依赖m.LParam(在使用给定键进行快速测试后,我得到了包含的两个值)。您可以进行快速研究以找出列表LParam或更多constant修饰符(例如鼠标滚轮)。

于 2013-09-09T14:50:11.080 回答
2

最终代码:

[DllImport("user32.dll")]
public static extern Boolean GetLastInputInfo(ref tagLASTINPUTINFO plii);
public struct tagLASTINPUTINFO
{
    public uint cbSize;
    public Int32 dwTime;
}

private void timerTemps_Inactif_Tick(object sender, EventArgs e)
{
    tagLASTINPUTINFO LastInput = new tagLASTINPUTINFO();
    Int32 IdleTime;
    LastInput.cbSize = (uint)Marshal.SizeOf(LastInput);
    LastInput.dwTime = 0;

    if (GetLastInputInfo(ref LastInput))
    {
        IdleTime = System.Environment.TickCount - LastInput.dwTime;
        if (IdleTime > 10000)
        {
            //My code here
        }
    }
}
于 2013-09-10T08:06:02.837 回答
2

您需要使用SetWindowsHookEx函数连接到 Windows 操作系统。您应该阅读 SecureList 发布的文章键盘记录器:它们的工作原理以及如何检测它们,以了解该过程。

于 2013-09-09T14:25:08.713 回答