Hi

Is it possible to capture a mouse click anywhere on a form (both on the form itself and on any control) without putting code in each control?

I want to reset a timer/timeout when the user hits a key (which I have working no problem w/ a combo of

1. Keypreview turned on

Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.KeyPreview = True

    End Sub

2. Capturing KeyDown event

Private Sub Login_Key(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
        MsgBox("key")
    End Sub

I can capture the mouse click on the form by using the mousedown event, but then I would also have to put code inside each control on the form to capture the mouse clicks there.

Private Sub SMKiosk_Login_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseClick
        MsgBox("mouse click")
    End Sub

Any ideas on how to do this?

Thanks,
Scott

Dani AI

Generated

A clean, app‑wide way to catch every mouse click (and keyboard activity) without wiring handlers on every control is to install an IMessageFilter and register it with Application.AddMessageFilter — the filter sees Windows messages before they reach individual controls, so you can reset your timeout from one place instead of adding timers/handlers on every form. This avoids polling and per-control wiring and is exactly what you need to detect clicks anywhere in the process. (learn.microsoft.com)

The core idea (VB.NET) is to implement IMessageFilter.PreFilterMessage and look for mouse/key messages, then reset your timeout there:

Public Class GlobalInputFilter
    Implements IMessageFilter

    Private Const WM_LBUTTONDOWN As Integer = &H201
    Private Const WM_RBUTTONDOWN As Integer = &H204
    Private Const WM_MBUTTONDOWN As Integer = &H207
    Private Const WM_KEYDOWN As Integer = &H100

    Public Function PreFilterMessage(ByRef m As Message) As Boolean Implements IMessageFilter.PreFilterMessage
        Select Case m.Msg
            Case WM_LBUTTONDOWN, WM_RBUTTONDOWN, WM_MBUTTONDOWN
                ResetTimeout()
            Case WM_KEYDOWN
                ResetTimeout()
        End Select
        Return False
    End Function

    Private Sub ResetTimeout()
        ' Call your existing timeout reset logic here (keep it fast/thread-safe)
    End Sub
End Class

' Register (for example at application startup)
Application.AddMessageFilter(New GlobalInputFilter())

The mouse messages you check map to the standard Win32 messages (WM_LBUTTONDOWN = 0x0201, etc.). Keep the filter fast; returning True will swallow the message. (learn.microsoft.com)

Notes on keyboard behavior: KeyPress is raised only for character keys (it won’t fire for navigation keys), so relying on KeyPress explains why Tab/Enter looked missing. Use KeyDown with Form.KeyPreview = True to catch most keys at form level, or override ProcessCmdKey / handle WM_KEYDOWN in your filter if you need to reliably catch dialog/navigation keys (Enter, Tab, accelerators). (learn.microsoft.com)

This approach ties back to what started and avoids the per‑control work that ’s referenced thread pushed toward. Keep filter work minimal and thread-safe, and remove the filter if you need to unwind it at shutdown.

Recommended Answers

All 4 Replies

Have a look at this discussion: http://www.vbforums.com/showthread.php?t=358556

Thanks for the reply. I did see that while I was searching but I though a timer (basically a continuous loop, right?) would use up a bunch of resources where an event (if it existed) wouldn't really use up any.

If that's the only way to do it fine, but if an event-type solution is out there I would prefer that.

This would also force me to put a timer on every page, no? Or is there a way to have it in one place (on main form perhaps)?

Thanks,
Scott

Thanks Oxiegen. I tried this method for capturing the mouse clicks and it seems to work great.

One problem related to the keyboard capture. Keypress and keydown events do not seem to capture keys like tab or enter. Anybody know why?

Here is my code:

Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        MsgBox("keydown")
    End Sub

    Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
        MsgBox("keypress")
    End Sub

In your Form1_KeyDown you can use the e variable and perform some checks on which keys were pressed.

Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
   If e.KeyCode = Keys.Enter Then
      '' Works with both the standard Enter key and the keypad Enter.
      MsgBox("It's the Enter key")
   ElseIf e.KeyCode = Keys.Tab Then
      MsgBox("It's the Tab key")
   End If
End Sub

And if

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.