Winapi:可靠地检测用户活动

时间:2015-03-17 23:30:09

标签: winapi user-input

我写了一个(非常小的)程序,当某个蓝牙连接丢失时执行。它应该等待几秒钟以便用户不活动,当没有活动时系统应该锁定。

我不需要跨会话检测,但它在会话中应该是全局的(即,不仅是当前进程的输入)。

如果有一个简单但可靠的解决方案,我会很高兴。特别是,我想避免全局挂钩。

我的第一次尝试是在开始时使用:

LASTINPUTINFO lii;
lii.dwSize = sizeof(LASTINPUTINFO);
GetLastInputInfo(&lii);
g_iLastActivity = lii.dwTime;

然后,我设置了一个计时器,在WM_TIMER上我做了

LASTINPUTINFO lii;
lii.dwSize = sizeof(LASTINPUTINFO);
GetLastInputInfo(&lii);
if(lii.dwTime > g_iLastActivity)
  LockWorkStation();

不幸的是,这似乎并不可靠。虽然我根本没有触及任何东西,但第二次呼叫通常会提供更大的价值。

我的下一次尝试是原始输入。创建主窗口时,我会这样做:

RAWINPUTDEVICE Rid[2];
Rid[0].usUsagePage = 0x01; 
Rid[0].usUsage = 0x02; 
Rid[0].dwFlags = RIDEV_NOLEGACY;
Rid[0].hwndTarget = hWnd;
Rid[1].usUsagePage = 0x01; 
Rid[1].usUsage = 0x06; 
Rid[1].dwFlags = RIDEV_NOLEGACY;
Rid[1].hwndTarget = hWnd;
if(RegisterRawInputDevices(Rid, 2, sizeof(Rid[0])) == FALSE)
    return -1;

再次,我为我的超时设置了一个计时器,在WM_INPUT中我有:

case WM_INPUT:
  KillTimer(hWnd, IDTIMER);
  // terminate my app
  break;

在WM_TIMER中:

WM_TIMER:
  if(wParam != IDTIMER) break;
  LockWorkStation();
  KillTimer(hWnd, IDTIMER);
  // terminate my app
  break;

不幸的是,这也不可靠。 此外,在某些情况下,我会立即收到WM_INPUT,尽管没有用户输入。 在其他情况下,我没有收到WM_INPUT。当我的应用程序没有焦点时(即它不能全局工作),似乎会发生这种情况。

我找到了一些文章(例如Detecting User Activity),但最终他们都指向GetLastInputInfo,这对我来说似乎不可靠。

这些方法有误吗?如果是,为什么?如果不是,最简单的方法是什么?

0 个答案:

没有答案