9

一些背景知识:我正在编写一个包含多个表单等的应用程序。用户必须登录才能使用大部分功能,直到现在它都运行良好。但是,现在,客户要求用户在一定的非活动时间后退出。问题是用户仍然可以在计算机上处​​于活动状态,只是不在我的应用程序中。需要明确的是,当用户在我的应用程序中处于非活动状态时,我必须将其注销,即使他仍在与桌面交互。

首先,我认为这将相当简单。只需记住最后一次操作的时间,在计时器中不断将其与当前时间进行比较,如果经过的时间大于允许的时间,则注销用户。但是我意识到找出最后的行动时间可能不是那么简单......

当然我可以复制粘贴类似

Program.LastActionTime = DateTime.Now;

在每个 OnChange、OnClick 等事件中......但是,由于应用程序的大小,这不仅会是大量工作......这也是一个非常糟糕的做法,我相信它会是至少忘记一次,使整个事情变得不可靠(而且看起来很糟糕,这个错误几乎不可能重现!)

那么,有没有更好的方法呢?

4

6 回答 6

6

我过去使用的一种方法是在您的应用程序表单上创建一个MessageFilter并检查指示用户活动的某些类型的事件:

 public class UserActivityFilter : IMessageFilter
 {
        // Define WinAPI window message values (see pinvoke.net)
        private int WM_LBUTTONDOWN = 0x0201;
        private int WM_MBUTTONDOWN = 0x0207;
        private int WM_RBUTTONDOWN = 0x0204;
        private int WM_MOUSEWHEEL = 0x020A;
        private int WM_MOUSEMOVE = 0x0200;
        private int WM_KEYDOWN = 0x0100;

        public bool PreFilterMessage(ref Message m)
        {
            if (m.Msg == WM_LBUTTONDOWN || m.Msg == WM_MBUTTONDOWN || m.Msg == WM_RBUTTONDOWN || m.Msg == WM_MOUSEWHEEL || m.Msg == WM_MOUSEMOVE || m.Msg == WM_KEYDOWN)
            {
                //User activity has occurred
                // Reset a flag / timer etc.
            }
            return false;
        }
  }

然后在表单的 Main() 方法中,在调用 Run() 之前:

Application.AddMessageFilter(new UserActivityFilter());

需要注意的是,添加复杂的消息过滤器或添加多个单独的过滤器会减慢应用程序的响应速度。

于 2009-09-14T13:20:20.930 回答
2

在您的 Program.CS 文件中,您可以处理 Application.Idle 事件并在那里重置您的计时器。看:

http://msdn.microsoft.com/en-us/library/system.windows.forms.application.idle.aspx

于 2009-09-14T13:21:43.423 回答
1

您可以覆盖WndProc,更新Program.LastActionTime每个相关Keyboard/Mouse事件消息。

于 2009-09-14T13:21:16.983 回答
0

在 MouseMove 和 KeyPressed 事件上挂钩事件处理程序,然后检查该事件内的焦点?

于 2009-09-14T13:03:09.023 回答
0

一般来说,最好从应用程序逻辑而不是原始用户输入中获取此信息,但我假设您没有可以提供此信息的灵活基础架构(可能使用命令模式)。

所以我建议只在您的主表单中注册处理程序 - 如果您收到点击或关键事件(为此启用Form.KeyPreview),您的用户处于活动状态,您可以重置不活动时间。

于 2009-09-14T13:07:14.863 回答
0

您可以创建一个所有窗口窗体都继承自的基类。在基类中,您检查并重置每个 KeyPress 或 Click 的超时。

于 2009-09-14T13:07:32.627 回答