【问题标题】:Expressing the C# conditional, "if a mouse/keyboard action has not occurred in the last 'n' seconds"表达 C# 条件,“如果在最后 'n' 秒内没有发生鼠标/键盘操作”
【发布时间】:2014-11-06 00:29:45
【问题描述】:

问题是如何让 C# 程序(在 Windows 中运行)检查在过去的一段时间内是否按下了按键,或者是否移动/单击了鼠标。

我发现的一个解决方案使用“KeyPress”事件,但这仅在控件(或应用程序)具有焦点时才有效。我正在寻找一种即使在程序在后台运行时也能正常工作的解决方案。

此外,最好有办法从条件中排除某些事件(即键“Z”)。

【问题讨论】:

标签: c# winforms events conditional


【解决方案1】:

WinAPI 中有一个函数可以做到这一点:GetLastInputInfo

此函数对于输入空闲检测很有用。但是,GetLastInputInfo 不提供跨所有正在运行的会话的系统范围的用户输入信息。相反,GetLastInputInfo 仅为调用该函数的会话提供会话特定的用户输入信息。

甚至还有example on pinvoke.net。这是我的版本:

public static TimeSpan GetIdleTime()
{
    var lastInputInfo = new LASTINPUTINFO
    {
        cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO))
    };

    if (!GetLastInputInfo(ref lastInputInfo))
        throw new Win32Exception("GetLastInputInfo failed");

    return TimeSpan.FromMilliseconds(Environment.TickCount - lastInputInfo.dwTime);
}

相关的 P/Invoke 定义:

[DllImport("user32.dll")]
static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

[StructLayout(LayoutKind.Sequential)]
struct LASTINPUTINFO
{
    [MarshalAs(UnmanagedType.U4)]
    public UInt32 cbSize;

    [MarshalAs(UnmanagedType.U4)]
    public UInt32 dwTime;
}

【讨论】:

  • 那个 return 语句真是太棒了。 40 个字符以避免分子为零时的除法。
  • @BenVoigt 是的,事实上该函数没有返回 TimeSpan... 但我从 pinvoke.net 引用了它。我会改进的。
  • 谢谢,这看起来很接近我所追求的,但如果我理解正确的话,它似乎并没有返回有问题的事件实际是什么。如果最后一个事件是异常,我还需要一种方法来检查倒数第二个事件(即对于问题,“过去 15 秒内是否有任何非 Z 键输入?”,如果最后一个输入是 Z 并且发生在 1 秒前,我需要检查它之前的事件)。
  • @user10478 我认为它属于 nice to have 类别,但由于您确实需要它,因此此解决方案不会削减它。您必须安装系统范围的挂钩。不幸的是,我现在没有时间写一个详细说明这个问题的答案,抱歉。如果到那时没人回答,我明天试试。
  • 抱歉,这是我不清楚的说法,我不确定是否需要它(因为我的程序将输出相当于按键,但只有 4 个特定键)。不确定输出是否会干扰 GetLastInputInfo。
猜你喜欢
  • 1970-01-01
  • 2016-08-05
  • 2015-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多