应用程序中基于计时器的空闲时间跟踪

时间:2016-12-02 17:30:29

标签: .net vb.net timer

这就是我想要做的。我有一个LogIn表单,可以在用户成功登录时激活/启用计时器。我会将表单保留在后台并将计时器设置为30分钟。如果有30分钟不活动,那么我将关闭用户 - 显示到LogIn表单。什么是确定应用程序中是否存在任何活动的最佳方式 - 在这种情况下会将时间重置为DateTime.Now()。我想在每种形式中使用这些事件?

MouseClick
MouseDown
KeyPress
KeyDown

vb.net有什么可以让这更容易吗?我遇到了

GETUSERINPUT 

但是我不确定这种情况是否会起作用?由于用户可能没有输入任何新数据,但可能只是查看记录或什么?

编辑:

我在我的应用程序中创建了一个计时器,我试图找到一个不同的时间,以便我可以显示一个消息框并显示已经过了这么多时间。点击按钮我这样做......

dim MyTime as date = DateTime.Now()
Private Sub Button4_Click_1(sender As Object, e As EventArgs) Handles Button4.Click

    MyTime = DateTime.Now()
    Timer1.Interval = 1000

End Sub

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

    If DateDiff("n", DateTime.Now(), MyTime) > 1 Then

        MsgBox("TimesUP")
    End If

End Sub

我正在显示MyTime和DateTime.Now()和“n”或DateInterval.Minutes两者都不起作用。为什么??? ?? ??!

1 个答案:

答案 0 :(得分:1)

我认为在不活动的情况下锁定桌面的网络策略最简单:不需要保存任何数据(按照上一个问题)。

由于您正在模拟跟踪空闲时间的Windows作业,因此您可以使用API​​来获取空闲时间:

Partial Friend Class NativeMethods
    <StructLayout(LayoutKind.Sequential)>
    Structure LASTINPUTINFO
        <MarshalAs(UnmanagedType.U4)>
        Public cbSize As Integer
        <MarshalAs(UnmanagedType.U4)>
        Public dwTime As Integer
    End Structure 

    ' Gets the time of the last user input in ms
    <DllImport("user32.dll")>
    Private Shared Function GetLastInputInfo(ByRef plii As LASTINPUTINFO) As Boolean
    End Function

    Friend Shared Function GetLastInputTimeElapsed() As Int32
        Dim lastInputInf As New LASTINPUTINFO()
        lastInputInf.cbSize = Marshal.SizeOf(lastInputInf)
        lastInputInf.dwTime = 0

        ' get time of last input, subtract current ticks
        If GetLastInputInfo(lastInputInf) Then
            ' conver to seconds
            Return (Environment.TickCount - lastInputInf.dwTime) \ 1000
        Else
            Return 0
        End If
    End Function
 ...

然后只需检查长计时器中经过的秒数(或分钟数):

Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick

    ' Gets the time of the last user input in ms
    Dim elapsed = NativeMethods.GetLastInputTimeElapsed()

    ' 45 sec TimeOut for testing
    If elapsed > 45 Then
        Label3.Text = "You're done!"
    Else
        Label3.Text = String.Format("Idle for: {0} secs", elapsed)
    End If
End Sub

动画GIF的运行速度不足以显示,但输入是以任何鼠标移动或按键的形式检测到的。请注意,这会检测到系统输入 - 鼠标移动并且在您的应用最小化时按下的键将被计算。这是有道理的 - 如果应用程序被最小化并且本身时间,我会惊讶地看到它消失了。如果我完全是AFK,那就是另一回事。

本地计时器

对于一个简单的表单,VB Detect Idle time的答案非常简单:它会在看到鼠标移动或按键时停止并重新启动30分钟计时器。它不会检测容器控件上的移动。

使用Stopwatch也可以:

' form/class level
Private swLogout As Stopwatch

' start it with the app:
swLogout = New Stopwatch()
swLogout.Start()

您需要为每次按键和鼠标移动重新启动它。首先,将KeyPreview设置为true,然后:

Private Sub MainFrm_KeyPress(sender As Object, 
          e As KeyPressEventArgs) Handles MyBase.KeyPress
    swLogout.Restart()
End Sub

Mousemove更有问题,您需要连接所有主要的容器控件:

Private Sub MainFrm_MouseMove(sender As Object, 
            e As MouseEventArgs) Handles MyBase.MouseMove,
                  TabControl1.MouseMove, TabControl2.MouseMove,
                  ..., TabPage12.MouseMove
    swLogout.Restart()
End Sub

然后用相当短的计时器(比如3分钟)检查经过的时间:

Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
    Dim elapsed = swLogout.ElapsedMilliseconds \ 1000

    ' demo == 3 secs
    If elapsed > 3 Then
        Label3.Text = "You're done!"
        Timer2.Enabled = False
    Else
        Label3.Text = String.Format("Idle for: {0} secs", elapsed)
    End If
End Sub