【问题标题】:Automatic logout Windows Form自动注销 Windows 窗体
【发布时间】:2015-04-09 17:31:11
【问题描述】:

我有一个在 VB.NET 2010 中创建的 Windows 窗体应用程序,现在我需要实现自动注销。 我正在考虑使用一个计时器,它会在每个事件中重置它或保存用户执行的每个操作的时间戳,问题是我如何检测每个事件。

应用程序有几个在运行时创建的控件和一些子 Windows 窗体。

或者也许有人对如何实现该目标有更好的想法。(在一段时间不活动后从应用程序中注销用户。


编辑: Anthony 的代码从 C# 转换为 VB

Class MessageFilter
    Implements IMessageFilter
    Public Function PreFilterMessage(ByRef m As Message) As Boolean
        Const WM_KEYDOWN As Integer = &H100
        Const WM_MOUSELEAVE As Integer = &H2A3

        Select Case m.Msg
            Case WM_KEYDOWN, WM_MOUSELEAVE
                ' Do something to indicate the user is still active.
                Exit Select
        End Select

        ' Returning true means that this message should stop here,
        ' we aren't actually filtering messages, so we need to return false.
        Return False
    End Function
End Class

我在 WinForm 类和一个单独的类中尝试了这段代码,结果相同。 “类 'MessageFilter' 必须为接口 'System.Windows.Forms.IMessageFilter' 实现 'Function PreFilterMessage(ByRef m As Message) As Boolean'。”

已解决: 转换中的错误出现在必须如下的函数签名中。

Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) As Boolean Implements System.Windows.Forms.IMessageFilter.PreFilterMessage

编辑 2: 要删除过滤器,我以这种方式声明过滤器

Public Class Form1 
  Friend MyMsgFilter As New MessageFilter()
End Class

然后,当我需要添加消息过滤器时

Application.AddMessageFilter(MyMsgFilter)

以及何时需要删除它

Application.RemoveMessageFilter(MyMsgFilter)

非常感谢安东尼。

【问题讨论】:

    标签: vb.net winforms events logout


    【解决方案1】:

    您可以通过创建消息过滤器并响应某些类型的频繁消息来做到这一点。示例代码是 C#,但翻译成 VB.NET 应该不难。

    class MessageFilter : IMessageFilter
    {
        public bool PreFilterMessage(ref Message m)
        {
            const int WM_KEYDOWN = 0x0100;
            const int WM_MOUSELEAVE = 0x02A3;
    
            switch (m.Msg)
            {
                case WM_KEYDOWN:
                case WM_MOUSELEAVE:
                    // Do something to indicate the user is still active.
                    break;
            }
    
            // Returning true means that this message should stop here,
            // we aren't actually filtering messages, so we need to return false.
            return false;
        }
    }
    

    在您应用程序的某处,用户登录后,您可以使用Application.AddMessageFilter 方法注册消息过滤器。

    Application.AddMessageFilter(new MessageFilter());
    

    该示例仅侦听KeyDownMouseLeave 事件,它们都应该足够频繁地发生,但不要太频繁以至于消息过滤器会减慢整个应用程序的速度。在 WinForms 应用程序中会触发大量消息,并且为每条发送的消息都做一些事情并不是一个好主意。

    【讨论】:

    • 我转换了代码,我得到一个错误“类'MessageFilter'必须为接口'System.Windows.Forms.IMessageFilter'实现'Function PreFilterMessage(ByRef m As Message) As Boolean' 。”另一个疑问是你从哪里得到消息代码(十六进制数字)?我想通过 CLICK 更改 MOUSELEAVE。
    • 该错误使您看起来好像没有正确地将其转换为 VB.NET。没有看到你的代码很难说。通过在线搜索可以轻松找到 Windows 消息代码。 Here is a complete list of them,可以搜索WM_LBUTTONDOWN等具体消息。没有 Click 消息这样的东西,因为它实际上只是对 MouseDown 和 MouseUp 的响应。
    • 当用户注销时我必须处理MessageFilter,因为如果不是每次登录都会得到一个新的MessageFilter,那么我必须怎么做呢?我知道我必须使用 Application.RemoveMessageFilter() 但我必须在括号之间写什么?如何引用MessageFilter?
    【解决方案2】:

    如何检测每个事件?

    您并不真正需要每个 事件。一些战略事件,如MouseMove 和一些精心挑选的KeyDown 处理程序应该涵盖它。我在这些事件中所做的只是更新一个全局时间戳变量,仅此而已。然后我还有一个计时器,它会每隔一段时间触发一次,并检查自时间戳以来的时间。

    【讨论】:

    • 我已经尝试过了,但只有当鼠标移到表单上并且我的应用程序有很多控件使用很多表单表面(如 DataGrids 和/或 TabControls)时才会触发,所以如果用户将鼠标悬停在该控件的某个人上,即使用户仍在使用该程序,该方法也会注销用户。并且应用程序必须进行大量控制才能将该代码添加到每个代码中。
    • @E_Blue 查看Application.AddMessageFilter,它可以让您基本上挂钩所有消息。我仍然建议仅在某些类型的事件上更新时间(或重新启动计时器),因为消息过滤器会经常被调用,并且执行任何可能密集的操作都会减慢您的应用程序。
    • 谢谢。这将捕获所有消息,甚至来自运行时创建的控件的消息?来自 Timers 等控件的消息呢?我有几个计时器来不时更新 DataGrids。有一些属性可以将这些消息与用户活动区分开来?
    • 我发布了一个答案以更好地演示,但是消息过滤器将能够监听系统中的所有消息。从技术上讲,并非所有事件都从消息中产生,但其中很多都是。
    • 我在原问题中添加代码,IDE在第二行备注IMessageFilter。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    • 2022-12-11
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多