I want to make an application in vb.net which will allow user to use mouse in a different way. i.e Dwell Clicking.

Suppose user moves mouse pointer at particular location and if the user doesnt move the mouse pointer from that location for 2 seconds then single click will be initiated.

Can any one help me out! How should I start?
All I know is I will need a form, 2 buttons i.e for selecting single click and double click, and a timer!

Recommended Answers

All 24 Replies

What is Dwell Clicking ?

@debasisdas ..The user moves mouse pointer at particular location(dwelling) and if the user doesnt move the mouse pointer from that location for particular time then clicks will be initiated.

1. On a timer keep tacking of the X,Y coordinates of the mouse.
2. Check the same after desired time gap and compare with the old location, if it has changed call the click event.
3. On each mouse move reset the timer.

@debasisdas.. First I would like to Thank you for your time.
I understood your first step, and successfully implemented it. But, I m stuck in second step i.e checking the new coordinates with old ones for desired time gap? How do I set timer and which data structure should I use? Should I use array, or variables will do? If possible can you post the sample code of second step? - Thank you.

No need of using array ,using variables should work for you.

Can you post the sample code of second step? - Thank you.

what is the problem with step2 ?

suppose
on start of the timer
x=1500
y=2000

after 2 seconds
x1=2500
y1=3000


if x <> x1 and y <>y1 then
' your next logic here

Why not just use the MouseHover event?

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'Do click code here
    End Sub

    Private Sub Button1_MouseHover(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.MouseHover
        Button1_Click(Nothing, Nothing)
    End Sub

MSDN - Control.MouseHover Event

Actually that does not give you much control over the dwell time.
Try using a ToolTip control like this.

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ToolTip1.AutomaticDelay = 1500
        ToolTip1.SetToolTip(Button1, "Button1")
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'Do click code here
        MessageBox.Show("Clicked")
    End Sub

    Private Sub ToolTip1_Popup(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PopupEventArgs) Handles ToolTip1.Popup

        If e.AssociatedControl Is Button1 Then
            e.Cancel = True
            Button1_Click(Nothing, Nothing)
        End If

    End Sub

I dont want cursor to be able to initiate clicks on form only!

It should initiate clicks anywhere like on desktop, taskbar...etc

I dont want cursor to be able to initiate clicks on form only!

It should initiate clicks anywhere like on desktop, taskbar...etc

Ohh, you mean change the whole OS mouse experience so that you can Dwell click a Desktop shortcut.

That will require very deep knowledge of the OS and is not available via .Net directly.
You will need to do some research on Windows OS messaging and how Windows handles mouse operations. Then call on some Windows APIs.

Sorry, this is a bit beyond my knowledge.
Maybe someone else could help.
Good luck.

@debasisdas & @nick.crane - Thank you for helping me!

I have successfully created dwell click application. But, I m facing some problem.
I have used a timer whose interval is set to 2 sec, so this program is initiating clicks every 2 sec. I want it to click only when my mouse does not move for 2 sec or so.

means if I move mouse continuously it should not initiate click.

Please help me out with timer syntax - Thank you!

Public Class Form1
    Dim x As Integer  ' X variable to store x coordinate of cursor
    Dim y As Integer  ' X Variable to store y coordinate of cursor
    Dim x1 As Integer  ' X1 Variable to store x1 new coordinate of cursor
    Dim y2 As Integer   'y2 Variable to store y2 new coordinate of cursor
    Private Declare Sub mouse_event Lib "user32.dll" (ByVal dwFlags As Integer, ByVal dx As Integer, ByVal dy As Integer, ByVal cButtons As Integer, ByVal dwExtraInfo As Integer)

    Private Sub Mouse_Click(ByVal button As Integer, ByVal state As String)
        Select Case button
            Case 1
                If state = "down" Then
                    mouse_event(2, 100, 100, 0, 0)
                Else
                    mouse_event(4, 100, 100, 0, 0)
                End If
            Case 2
                If state = "down" Then
                    mouse_event(8, 100, 100, 0, 0)
                Else
                    mouse_event(16, 100, 100, 0, 0)
                End If
            Case 3
                If state = "down" Then
                    mouse_event(32, 100, 100, 0, 0)
                Else
                    mouse_event(64, 100, 100, 0, 0)
                End If
        End Select

    End Sub

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        
        x = MousePosition.X
        y = MousePosition.Y
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
        x1 = MousePosition.X
        y2 = MousePosition.Y

        If x <> x1 And y <> y2 Then
            Mouse_Click(1, "down")
            Mouse_Click(1, "up")

        End If

        x = x1
        y = y2

    End Sub

Reply..!

You have no code to capture the mouse movement!
Your application will capture mouse events while it has focus.
However, when the user clicks outside your app you will not receive any mouse event notifications.
This is a feature of the OS and you must do more research to find out how to capture the mouse at a lower level. Not sure how you do this. Good luck in finding out.

Also, according to MSDN mouse_event Function the mouse_event is superseded with the SendInput Function .

I dont have problem with mouse clicks!
I just want to control timer! i.e if mouse doesnt move for specific time initiate click. If I continously move my mouse it should not perform clicks!
C'mon guys help me out!

In your code that captures the mouse move event you should reset the timer.
Then when the mouse stops moving your timer is allowed to timeout.
When the timer times out the mouse has been stationary for timeout period.
Try this in the mouse move event handler.

Timer2.Enabled = False;
Timer2.Enabled = True;
Member Avatar for Unhnd_Exception

This will start and stop a timer with mouse movement.
The Form's timer checks every half second if there was movement.

Option Strict On

Public Class Form1

    Private LastMoveTime As DateTime
    Private WithEvents MouseDetector As MouseDetector

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        MouseDetector = New MouseDetector

        Timer1.Interval = 500
        Timer1.Start()
    End Sub

    Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        'If the last time of movement and right now is >= 2 seconds then mouse     hovered.
        If DateAndTime.DateDiff(DateInterval.Second, LastMoveTime, DateAndTime.Now) >= 2 Then
            Timer1.Enabled = False
            MsgBox("Cursor Hovered for 2 Seconds")
        End If
    End Sub

    Private Sub MouseDetector_GlobalMouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MouseDetector.GlobalMouseMove
        'MouseMove raised from anywhere on the desktop
        'Set the time of movement
        LastMoveTime = DateAndTime.Now
        If Not Timer1.Enabled Then Timer1.Enabled = True
    End Sub

End Class

The MouseDetector Class

The mouse detectory class creates a global mouse hook and raises the Global mouse move event on mouse move.

You will need to add a class called mousedetector and paste the following code into it. You will also need to go to Project/Properties/Debug and uncheck enable the visual studio hosting process.

Imports System.Runtime.InteropServices
Imports System.Reflection
Imports System.Windows.Forms

Public Class MouseDetector

    Public Event GlobalMouseLeftButtonClick(ByVal sender As Object, ByVal e As MouseEventArgs)
    Public Event GlobalMouseRightButtonClick(ByVal sender As Object, ByVal e As MouseEventArgs)
    Public Event GlobalMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)

    Private Delegate Function MouseHookCallback(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer

    Private MouseHookCallbackDelegate As MouseHookCallback
    Private MouseHookID As Integer

    Public Sub New()

        If MouseHookID = 0 Then

            MouseHookCallbackDelegate = AddressOf MouseHookProc
            MouseHookID = SetWindowsHookEx(CInt(14), MouseHookCallbackDelegate, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly.GetModules()(0)), 0)

            If MouseHookID = 0 Then
                'error
            End If

        End If

    End Sub

    Public Sub Dispose()
        If Not MouseHookID = -1 Then
            UnhookWindowsHookEx(MouseHookID)
            MouseHookCallbackDelegate = Nothing
        End If
        MouseHookID = -1
    End Sub

    Private Enum MouseMessages
        WM_LeftButtonDown = 513
        WM_LeftButtonUp = 514
        WM_LeftDblClick = 515
        WM_RightButtonDown = 516
        WM_RightButtonUp = 517
        WM_RightDblClick = 518
        WM_MouseMove = 512
    End Enum

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure Point
        Public x As Integer
        Public y As Integer
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure MouseHookStruct
        Public pt As Point
        Public hwnd As Integer
        Public wHitTestCode As Integer
        Public dwExtraInfo As Integer
    End Structure

    <DllImport("user32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
    Private Shared Function CallNextHookEx( _
         ByVal idHook As Integer, _
         ByVal nCode As Integer, _
         ByVal wParam As IntPtr, _
          ByVal lParam As IntPtr) As Integer

    End Function

    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall, SetLastError:=True)> _
     Private Shared Function SetWindowsHookEx _
          (ByVal idHook As Integer, ByVal HookProc As MouseHookCallback, _
           ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall, SetLastError:=True)> _
    Private Shared Function UnhookWindowsHookEx(ByVal idHook As Integer) As Integer
    End Function

    Private Function MouseHookProc(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer

        If nCode < 0 Then
            Return CallNextHookEx(MouseHookID, nCode, wParam, lParam)
        End If

        Dim MouseData As MouseHookStruct = Marshal.PtrToStructure(lParam, GetType(MouseHookStruct))

        Select Case wParam

            Case MouseMessages.WM_MouseMove
                RaiseEvent GlobalMouseMove(Nothing, New MouseEventArgs(MouseButtons.None, 1, MouseData.pt.x, MouseData.pt.y, 0))

            Case MouseMessages.WM_LeftButtonUp
                RaiseEvent GlobalMouseLeftButtonClick(Nothing, New MouseEventArgs(MouseButtons.Left, 1, MouseData.pt.x, MouseData.pt.y, 0))

            Case MouseMessages.WM_RightButtonUp
                RaiseEvent GlobalMouseRightButtonClick(Nothing, New MouseEventArgs(MouseButtons.Right, 1, MouseData.pt.x, MouseData.pt.y, 0))
        End Select

        Return CallNextHookEx(MouseHookID, nCode, wParam, lParam)

    End Function

End Class
Member Avatar for Unhnd_Exception

Heres another example since you just completley ignored the last.

Public Class Form1

    Private LastPoint As Point
    Private LastTimeMoved As Date

    Sub New()

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

        ' Add any initialization after the InitializeComponent() call.
        LastTimeMoved = Now
        Timer1.Interval = 100
        Timer1.Start()
    End Sub

    Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        If LastPoint = Cursor.Position Then
            If DateDiff(DateInterval.Second, LastTimeMoved, Now) >= 2 Then
                LastPoint = New Point(Integer.MinValue, Integer.MinValue)
                MsgBox("Cursor Hovered over " & Cursor.Position.ToString & " for 2 seconds")
            End If
        Else
            LastPoint = Cursor.Position
            LastTimeMoved = Now
        End If
    End Sub
End Class

@Unhnd_exception....Thankyou very much!
Your code works perfectly fine! But there is a problem. If I dont move the cursor for more than 2 sec or so, it keeps on clicking! I just want one click to be initiated.

Public Class Form1
    
    Private LastPoint As Point
    Private LastTimeMoved As Date
    Private Declare Sub mouse_event Lib "user32.dll" (ByVal dwFlags As Integer, ByVal dx As Integer, ByVal dy As Integer, ByVal cButtons As Integer, ByVal dwExtraInfo As Integer)

    Sub New()

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

        ' Add any initialization after the InitializeComponent() call.
        LastTimeMoved = Now
        Timer1.Interval = 200
        Timer1().Start()
    End Sub


    Private Sub Mouse_Click(ByVal button As Integer, ByVal state As String)
        Select Case button
            Case 1
                If state = "down" Then
                    mouse_event(2, 100, 100, 0, 0)
                Else
                    mouse_event(4, 100, 100, 0, 0)
                End If
            Case 2
                If state = "down" Then
                    mouse_event(8, 100, 100, 0, 0)
                Else
                    mouse_event(16, 100, 100, 0, 0)
                End If
            Case 3
                If state = "down" Then
                    mouse_event(32, 100, 100, 0, 0)
                Else
                    mouse_event(64, 100, 100, 0, 0)
                End If
        End Select

    End Sub



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

        If LastPoint = Cursor.Position Then
            If DateDiff(DateInterval.Second, LastTimeMoved, Now) >= 1 Then
                LastPoint = New Point(Integer.MinValue, Integer.MinValue)
                Mouse_Click(1, "down")
                Mouse_Click(1, "up")
                Beep()

            End If
        Else
            LastPoint = Cursor.Position
            LastTimeMoved = Now
        End If

    End Sub

You need to latch the click event with a boolean.
You also do not need to reset LastPoint unless the cursor has moved.
Try this

Private ClickDone As Boolean
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        If LastPoint = Cursor.Position Then
            If DateDiff(DateInterval.Second, LastTimeMoved, Now) >= 1 And Not ClickDone Then
                ClickDone = True
                Mouse_Click(1, "down")
                Mouse_Click(1, "up")
                Beep()

            End If
        Else
            ClickDone = False
            LastPoint = Cursor.Position
            LastTimeMoved = Now
        End If

    End Sub
Member Avatar for Unhnd_Exception

Heres another since I already did it.

Private LastPointWhenClicked As Point

Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    If LastPoint = Cursor.Position AndAlso LastPointWhenClicked <> Cursor.Position Then
        If DateDiff(DateInterval.Second, LastTimeMoved, Now) >= 2 Then

            LastPoint = New Point(Integer.MinValue, Integer.MinValue)
            LastPointWhenClicked = Cursor.Position
               
        End If

    Else

        LastPoint = Cursor.Position
        LastTimeMoved = Now

    End If

End Sub
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.