winforms 如何在Windows窗体应用程序中触发自动注销?

k10s72fa  于 2022-11-16  发布在  Windows
关注(0)|答案(4)|浏览(145)

我有一个Windows应用程序项目,用户可以用他们的用户名和密码登录。我想让它在用户登录时,我会得到登录时间,如果用户30分钟不使用应用程序,应用程序会再次将用户发送到登录屏幕。我如何实现这一点?

5f0d552i

5f0d552i1#

编辑:Adam是完全正确的,我误解了这个问题,所以我删除了原来的答案。

若要监视用户活动,可以创建一个基于Form的自定义类,应用程序窗体将从该类继承。在该类中,可以订阅MouseMove和KeyDown事件(将KeyPreview属性设置为true),只要用户处于活动状态,就会引发这两个事件中的任何一个。然后,您可以创建System.Threading.Timer,将到期时间设置为30分钟,并在检测到用户活动时使用Change()方法将其推迟。
下面是一个示例实现:ObservedForm编写得相当一般,这样您可以更容易地看到模式。

public class ObservedForm : Form
{
     public event EventHandler UserActivity;

     public ObservedForm()
     {
         KeyPreview = true;

         FormClosed += ObservedForm_FormClosed;
         MouseMove += ObservedForm_MouseMove;
         KeyDown += ObservedForm_KeyDown;
     }

     protected virtual void OnUserActivity(EventArgs e)
     {
         var ua = UserActivity;
         if(ua != null)
         {
              ua(this, e);
         }
     }

     private void ObservedForm_MouseMove(object sender, MouseEventArgs e)
     {
          OnUserActivity();
     }

     private void ObservedForm_KeyDown(object sender, KeyEventArgs e)
     {
          OnUserActivity();
     }

     private void ObservedForm_FormClosed(object sender, FormClosedEventArgs e)
     {
         FormClosed -= ObservedForm_FormClosed;
         MouseMove -= ObservedForm_MouseMove;
         KeyDown -= ObservedForm_KeyDown;
     }
}

现在,您可以订阅UserActivity事件,并执行所需的逻辑,例如:

private System.Threading.Timer timer = new Timer(_TimerTick, null, 1000 * 30 * 60, Timeout.Infinite);
private void _OnUserActivity(object sender, EventArgs e)
{
     if(timer != null)
     {
         // postpone auto-logout by 30 minutes
         timer.Change(1000 * 30 * 60, Timeout.Infinite);
     }
}

private void _TimerTick(object state)
{
    // the user has been inactive for 30 minutes; log him out
}

希望这对你有帮助。

编辑#2:为了清楚起见,重新表述了说明的某些部分,并将FormClosing事件的用法更改为FormClosed。

olhwl3o2

olhwl3o22#

这是解决这个问题的最简单的方法,效果很好。

using System;
using System.Windows.Forms;
namespace WindowsApplication1 {
    public partial class Form1 : Form, IMessageFilter {
        private Timer mTimer;
        private int mDialogCount;
        public Form1() {
            InitializeComponent();
            mTimer = new Timer();
            mTimer.Interval = 2000;
            mTimer.Tick += LogoutUser;
            mTimer.Enabled = true;
            Application.AddMessageFilter(this);
        }

        public bool PreFilterMessage(ref Message m) {
            // Monitor message for keyboard and mouse messages
            bool active = m.Msg == 0x100 || m.Msg == 0x101;  // WM_KEYDOWN/UP
            active = active || m.Msg == 0xA0 || m.Msg == 0x200;  // WM_(NC)MOUSEMOVE
            active = active || m.Msg == 0x10;  // WM_CLOSE, in case dialog closes
            if (active) {
                if (!mTimer.Enabled) label1.Text = "Wakeup";
                mTimer.Enabled = false;
                mTimer.Start();
            }
            return false;
        }

        private void LogoutUser(object sender, EventArgs e) {
            // No activity, logout user
            if (mDialogCount > 0) return;
            mTimer.Enabled = false;
            label1.Text = "Time'z up";
        }

        private void button1_Click(object sender, EventArgs e) {
            mDialogCount += 1;
            Form frm = new Form2();
            frm.ShowDialog();
            mDialogCount -= 1;
            mTimer.Start();
        }
    }
}
syqv5f0l

syqv5f0l3#

你必须为你所有的表单创建一个基类,它将拦截任何用户活动并存储最后一次活动的时间。每次用户点击某个东西时,你都必须检查最后一次活动的日期,并决定它是否是太久以前的。
目前我不知道如何拦截,但我很肯定这是可能的(也许使用windows消息?)

kdfy810k

kdfy810k4#

**1.st:**用户登录,将时间戳存储在某处(例如,此unix时间戳“1294230230”表示大约为2011年1月5日12:24)

int sess_creation_time = now(); * 假设'now()'函数返回当前unix时间戳

**2.nd:**当用户尝试执行任何操作时,捕获此尝试的时间戳。

int temp_time = now();
现在,只需将这些值与所需的自动注销限制进行比较。

// compare here
// a, temp_time - sess_creation_time => the difference, time of inactivity
// 60*30 -> 60 seconds * 30 -> 30 minutes
if( (temp_time - sess_creation_time) > (60*30) )
{
  // time of inactivity is higher than allowed, logout here
  logout();
}
else
{
  // session is still valid, do not forget to update its creation time
  sess_creation_time = now();
}

**不要忘记,这不是用C/C++或C#编写的,但逻辑保持不变;- )

Hope,这对你有点帮助**

相关问题