Results 1 to 10 of 10

Thread: Problem confining pointer to Form

  1. #1

    Thread Starter
    Member
    Join Date
    Feb 2026
    Posts
    33

    Problem confining pointer to Form

    Hi Guys,

    I am trying to confine the mouse pointer to the form in a little test app.

    So far, I am able to trap all the buttons and wheel action, but when I attempt to limit the pointer movement to the active form, I am encountering an error.

    The Error I am getting is " Value does not fall within the expected range. The error occurs on line 122 of my code.
    I did have to convert some of the snippets from VB6 code so that is where I may have messed up, but I cannot figure out my mistake.

    Code:
    Imports System.Deployment.Application
    Imports System.Reflection.Emit
    Imports System.Windows.Forms.VisualStyles.VisualStyleElement
    
    Public Class Form1
        Dim lTwipsX As Long
        Dim lTwipsY As Long
        Structure RECT
            Public left As Long
            Public top As Long
            Public right As Long
            Public bottom As Long
        End Structure
        Dim RectArea As RECT
        Structure POINT
            Public x As Long
            Public y As Long
        End Structure
    
        'Private Declare Function ClipCursor Lib "user32" (lpRect As Any) As Long
        Private Declare Function ClipCursor Lib "user32" (lpRect) As Long
        Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
        Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINT) As Long
        Private Declare Function OffsetRect Lib "user32" (lpRect As RECT, ByVal x As Long, ByVal y As Long) As Long
        Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
        Private Const VK_LBUTTON = &H1
        Private Const VK_RBUTTON = &H2
        Dim RightClicked As Integer
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            lTwipsX = My.Computer.Screen.Bounds.Width / 15 ' TwipsPerPixelX
            lTwipsY = My.Computer.Screen.Bounds.Height / 15 ' TwipsPerPixelY
            For Each c As Control In Controls
                AddHandler c.MouseClick, AddressOf ClickHandler
            Next
        End Sub
    
        Private Sub Form1_MouseEnter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.MouseEnter
            TextBox1.Text = " Mouse Entered "
            'displaying "mouse entered" when the mouse pointer enters the form
        End Sub
    
        Private Sub Form1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
            If e.Button = MouseButtons.Left Then
                TextBox2.Text = " Mouse Left click at " + CStr(e.X) + " :" + CStr(e.Y)
            ElseIf e.Button = MouseButtons.Right Then
                TextBox2.Text = " Mouse Right click at " + CStr(e.X) + " :" + CStr(e.Y)
            ElseIf e.Button = MouseButtons.Middle Then
                TextBox2.Text = " Mouse Middle click at " + CStr(e.X) + " :" + CStr(e.Y)
            Else
                'displaying the coordinates when the mouse is pressed on the form
            End If
        End Sub
    
        Private Sub Form1_MouseLeave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.MouseLeave
            TextBox1.Text = " Mouse Exited "
            'displaying "mouse exited" when the mouse pointer leaves the form
        End Sub
    
        Private Sub Form1_MouseClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseClick
            If e.Button = MouseButtons.Right Then
                RightClicked += CStr(e.Clicks)
                TextBox3.Text = " Mouse Right click " + RightClicked.ToString + " times."
                'Displaying number of times the mouse right button is pressed and released.
            End If
        End Sub
    
        Private Sub Form1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
            If e.Delta > 0 Then
                TextBox2.Text = " Mouse Wheel Scrolled UP "
                Label1.Text = "Wheel UP"
            Else
                TextBox2.Text = " Mouse Wheel Scrolled DOWN "
                Label1.Text = "Wheel Down"
            End If
    
            'If MouseWheel.scrollup Then
            '        UserZoom = UserZoom + 0.05
            'Me.Refresh()
            'End If
    
        End Sub
    
        ' Source - https://stackoverflow.com/a/37639493
        ' Posted by Apachi, modified by community. See post 'Timeline' for change history
        ' Retrieved 2026-03-30, License - CC BY-SA 3.0
    
        Public Sub ClickHandler(sender As Object, e As MouseEventArgs) Handles Me.MouseClick, PictureBox1.MouseClick, Label1.MouseClick, Button1.MouseClick
            Label1.Text = String.Format("Clicked ""{0}"" with the {1} mouse button.", sender.name, e.Button.ToString.ToLower)
    
            Select Case e.Button
                Case MouseButtons.Left, Label1.Text = "Left"
                Case MouseButtons.Right, Label1.Text = "Right"
                Case MouseButtons.Middle, Label1.Text = "Middle"
                Case Else
                    Label1.Text = "Some other button"
            End Select
        End Sub
    
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            If GetAsyncKeyState(VK_LBUTTON) Then
                Label2.Text = "Left Click"
            ElseIf GetAsyncKeyState(VK_RBUTTON) Then
                Label2.Text = "Right Click"
            Else
                Label2.Text = ""
            End If
        End Sub
    
        Private Sub CmdTrap_Click(sender As Object, e As EventArgs) Handles CmdTrap.Click
    
            If CmdTrap.Text = "Trap Cursor" Then
                'MsgBox("Cursor Clipped to the Form")
    
                With RectArea
                    .left = .left / lTwipsX
                    .top = .top / lTwipsY
                    .right = .left + Me.Width / lTwipsX
                    .bottom = .top + Me.Height / lTwipsY
                End With
    
                Call ClipCursor(RectArea)
                CmdTrap.Text = "Release Cursor"
            Else
                'MsgBox("Cursor Released")
    
                With RectArea
                    .left = 0
                    .top = 0
                    .right = My.Computer.Screen.Bounds.Width / lTwipsX
                    .bottom = My.Computer.Screen.Bounds.Height / lTwipsY
                End With
                Call ClipCursor(RectArea)
                CmdTrap.Text = "Trap Cursor"
            End If
        End Sub
    End Class
    Regards,
    Antony.

  2. #2
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: Problem confining pointer to Form

    You can restrict your cursor with the Cursor.Clip property…

    https://learn.microsoft.com/en-us/do...wsdesktop-10.0

    As a clue why your API functions aren’t working, you’re using legacy declarations. VB.Net uses 32 bit variables. What was Short is now Integer, what was Long is now Integer. When a Long would’ve been used for a handle, that’s now IntPtr

    Code:
    Private Declare Function ClipCursor Lib "user32" (lpRect As RECT) As Integer
    Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As IntPtr, lpRect As RECT) As Integer
    Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As IntPtr, lpPoint As POINT) As Integer 
    Private Declare Function OffsetRect Lib "user32" (lpRect As RECT, ByVal x As Integer, ByVal y As Integer) As Integer
    Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Integer) As Integer
    Private Const VK_LBUTTON As Integer = &H1
    Private Const VK_RBUTTON As Integer = &H2
    Dim RightClicked As Boolean
    Last edited by .paul.; Apr 8th, 2026 at 03:39 PM.

  3. #3

    Thread Starter
    Member
    Join Date
    Feb 2026
    Posts
    33

    Re: Problem confining pointer to Form

    Thanks Paul.

    Your guidance helped me sort out the clip.cursor function and now it works.

    Cheers.

  4. #4
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: Problem confining pointer to Form

    Quote Originally Posted by .paul. View Post
    You can restrict your cursor with the Cursor.Clip property…

    https://learn.microsoft.com/en-us/do...wsdesktop-10.0

    As a clue why your API functions aren’t working, you’re using legacy declarations. VB.Net uses 32 bit variables. What was Short is now Integer, what was Long is now Integer. When a Long would’ve been used for a handle, that’s now IntPtr

    Code:
    Private Declare Function ClipCursor Lib "user32" (lpRect As RECT) As Integer
    Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As IntPtr, lpRect As RECT) As Integer
    Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As IntPtr, lpPoint As POINT) As Integer 
    Private Declare Function OffsetRect Lib "user32" (lpRect As RECT, ByVal x As Integer, ByVal y As Integer) As Integer
    Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Integer) As Integer
    Private Const VK_LBUTTON As Integer = &H1
    Private Const VK_RBUTTON As Integer = &H2
    Dim RightClicked As Boolean
    Ok… I can see problems there. To clarify…

    Short or Int16 is 16 bit
    Integer or Int32 is 32 bit
    Long or Int64 is 64 bit

    IntPtr represents a signed integer where the bit-width is the same as a pointer.

  5. #5

    Thread Starter
    Member
    Join Date
    Feb 2026
    Posts
    33

    Re: Problem confining pointer to Form

    I was originally encountering problems but I understood what was going on and was able to adjust to get it working.
    The only difference was in the last line, I couldn't use the Boolean response so I changed it to an integer and was able to get the test to work.

    I am now trying to get the clip rect to go back to full screen (I.E. turn clip.cursor on and off as needed.
    I can change the dimensions of rect but cannot seem to define coord 0,0, screen height, screen width in pixels or in twips as the acceptable input is only size (width, height) and it assumes that 0,0 is form top left.

    Wish it was as simple as define rect(top,left,bottom,right), then clip.cursor.enable or clip.cursor.disable but alas, it is not

    Regards,
    Antony.

  6. #6
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: Problem confining pointer to Form

    Code:
    Cursor.Clip = Me.ClientRectangle
    To reset…

    Code:
    Cursor.Clip = Nothing

  7. #7
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: Problem confining pointer to Form

    RightClicked += CStr(e.Clicks)???

    Not sure what you’re doing there? If it’s an Integer, why CStr?

  8. #8
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: Problem confining pointer to Form

    Or save the clip value to a variable before changing it, then you can easily reset it after

  9. #9

    Thread Starter
    Member
    Join Date
    Feb 2026
    Posts
    33

    Re: Problem confining pointer to Form

    Thanks Paul.

    It's embarrassing when the fix is so simple.
    I have the values in a string and can now toggle it on and off as needed.
    Threw away thirtyfive lines of useless code that I created and replaced it with three.
    This is a clear case of Nothing being so much more than a stack of code doing nothing.

    Thanks again.

  10. #10
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: Problem confining pointer to Form

    You should turn Option Strict on for all of your projects.
    To set Option Strict in this dialog box, on the Tools menu, click Options. In the Options dialog box, expand Projects and Solutions, and then click VB Defaults. The initial default setting in VB Defaults is Off.
    You’ll find it won’t let you set an Integer with a String. Also, if you have a Rectangle, use a variable of type Rectangle instead of a String…

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width