How can I intercept a mouse click event for Win XP or Win Vista in VB.NET

I am writing a windows service (non-forms based) that needs to intercept ANY mouse click made (anywhere) in Windows XP or Windows Vista (in C# or VB.NET).  I don't need the coordinates or anything like that, just need to know if either mouse button was clicked so that the service will intercept the click (without affecting any other program running) and play a "click" noise.
I'm not sure where to begin on this one (the Internet has tons of stuff on events WITHIN a forms program, but nothing outside).
Any ideas?
Who is Participating?
Mike TomlinsonConnect With a Mentor Middle School Assistant TeacherCommented:
For WinForms you can do this:
(note that in VB.Net 2005, or above, the hook does NOT work in the the executable itself from the bin folder)
Imports System.Runtime.InteropServices
Public Class Form1
    Private WithEvents llmh As New LowLevelMouseHook
    Private Sub llmh_LeftClick() Handles llmh.LeftClick
        Debug.Print("Left Click @ " & DateTime.Now.ToString)
    End Sub
    Private Class LowLevelMouseHook
        Private Const HC_ACTION As Integer = 0
        Private Const WH_MOUSE_LL As Integer = 14
        Private Const WM_LBUTTONDOWN As Integer = &H201
        Public Structure POINTAPI
            Public x As Int32
            Public y As Int32
        End Structure
        Public Structure MSLLHOOKSTRUCT
            Public pt As POINTAPI
            Public mouseData As Int32
            Public flags As Int32
            Public time As Int32
            Public dwExtraInfo As Int32
        End Structure
        Private Declare Function SetWindowsHookEx Lib "user32" _
            Alias "SetWindowsHookExA" ( _
            ByVal idHook As Integer, _
            ByVal lpfn As LowLevelMouseProcDelegate, _
            ByVal hmod As Integer, _
            ByVal dwThreadId As Integer) As Integer
        Private Declare Function CallNextHookEx Lib "user32" ( _
            ByVal hHook As Integer, _
            ByVal nCode As Integer, _
            ByVal wParam As Integer, _
            ByVal lParam As MSLLHOOKSTRUCT) As Integer
        Private Declare Function UnhookWindowsHookEx Lib "user32" ( _
            ByVal hHook As Integer) As Integer
        Private Delegate Function LowLevelMouseProcDelegate( _
            ByVal nCode As Integer, _
            ByVal wParam As Integer, _
            ByVal lParam As MSLLHOOKSTRUCT) As Integer
        Private Declare Function GetCursorPos Lib "user32" Alias "GetCursorPos" ( _
            ByRef lpPoint As POINTAPI) As Integer
        Private hhkLowLevelMouse As Integer
        Private mouseDelegate As LowLevelMouseProcDelegate
        Public Event LeftClick()
        Public Sub New()
        End Sub
        Public Sub Hook()
            ' remove existing hook if there is one
            If hhkLowLevelMouse <> 0 Then
            End If
            ' make a new hook
            mouseDelegate = New LowLevelMouseProcDelegate(AddressOf Me.LowLevelMouseProc)
            hhkLowLevelMouse = SetWindowsHookEx(WH_MOUSE_LL, mouseDelegate, _
                Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
        End Sub
        Public Sub UnHook()
            If hhkLowLevelMouse <> 0 Then
            End If
            hhkLowLevelMouse = 0
        End Sub
        Private Function LowLevelMouseProc( _
            ByVal nCode As Integer, _
            ByVal wParam As Integer, _
            ByVal lParam As MSLLHOOKSTRUCT) As Integer
            If (nCode = HC_ACTION) Then
                Select Case wParam
                    Case WM_LBUTTONDOWN
                        RaiseEvent LeftClick()
                End Select
            End If
            Return CallNextHookEx(hhkLowLevelMouse, nCode, wParam, lParam)
        End Function
        Protected Overrides Sub Finalize()
        End Sub
    End Class
End Class

Open in new window

Mike TomlinsonMiddle School Assistant TeacherCommented:
Pretty sure you won't be able to get the hooks to work from a SERVICE...
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

Oops my bad.

You could do it just as easily with a WinForms app with Opacity set to 0 and not shown in the taskbar.  I know the requestor said he didn't want it in a WinForms app but that may be the most plausible method since you'd have to be running on an interactive user.
bd9000Author Commented:
Thanks for the links.  I think this is way out of my league understanding how to actually implement the class.
How would I go about it in just a windows form app (when the form is out of focus?)

bd9000Author Commented:
Sorry it's taking so long to reply - I haven't had time to try this code.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.