Dav*_*jak 9 c# user-interaction
一些背景:我正在编写一个具有多种形式的应用程序等.用户必须登录才能使用大多数功能,这一直到目前为止工作正常.但是,现在,客户端已请求在一定量的非活动时间之后用户将被注销.问题是用户仍然可以在计算机上处于活动状态,而不是在我的应用程序中.为了清楚起见,我必须在用户处于非活动状态时将用户注销,即使他仍在与桌面交互.
首先我认为这很简单.只需记住上次操作的时间,在计时器中将其与当前时间进行持续比较,如果超过允许时间,则注销用户.但是我已经意识到找出最后一次动作时间可能并不那么简单......
当然我可以复制粘贴之类的东西
Program.LastActionTime = DateTime.Now;
Run Code Online (Sandbox Code Playgroud)
在每个OnChange,OnClick等事件中...但不仅因为应用程序的大小,这将是一项大量的工作......这也是一个非常糟糕的做法,我相信它会是忘记了至少一次,使整个事情变得不可靠(并且看起来很破碎,这个bug几乎不可能重现!)
那么,有更好的方法吗?
我过去使用过的一种方法是在您的申请表上创建一个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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后在窗体的Main()方法中,在调用Run()之前:
Application.AddMessageFilter(new UserActivityFilter());
Run Code Online (Sandbox Code Playgroud)
需要注意的是,添加复杂的邮件过滤器或添加多个单独的过滤器可能会降低应用程序的响应速度.
在 Program.CS 文件中,您可以处理 Application.Idle 事件并在那里重置计时器。看:
http://msdn.microsoft.com/en-us/library/system.windows.forms.application.idle.aspx