locked
Trap Mouse Cursor

    Question

  • I'm writing a Pong game for fun.

    It's going well, the game is playable, but I've got a slight problem.
    The player's paddle follows the mouse cursor up and down the form. My problem here is that as soon as the cursor leaves the form, the paddle stops, sometimes prematurely.

    My solution is to trap the cursor in the game window, but I don't know how. Is there anyone who can point me in the right direction? Maybe supply some sample code...

    Thanks in advance!!!


    Logan Young, MCPD Web Developer hopeful
    Sunday, June 07, 2009 10:31 PM

Answers

  • But it should keep possible of course to leave your form, otherwize you cannot do almost anything anymore beside unplugging the power

    On the other hands should a mouse click outside the mouse area be not any problem, therefore you should have done some extremely strange, check those things is the only advice I can give you.

     
    • Marked as answer by Xingwei Hu Friday, June 12, 2009 3:36 AM
    Monday, June 08, 2009 4:28 AM
  • Ok.  The api's I was thinking of was GetClipCursor and ClipCursor - which I don't think you actually need in .NET :)  There is a property on the Cursor object - Cursor.Clip that should allow you to manipulate this.  But, they don't seem to work on Windows 7 at all - or I'm doing something wrong :)  Anyway, if I get time then I'll try them out latter on my Vista box.
    Tom Shelton
    • Marked as answer by Xingwei Hu Friday, June 12, 2009 3:30 AM
    Monday, June 08, 2009 2:22 PM
  • Based on your post, you want to handle the mouse move event on the screen, here 
    you could look this link and will be able to get current point coordinate wherever the Cursor points to. it works fine on my computer and please take it a try.
    mouse position + mousehook
    link:http://social.msdn.microsoft.com/forums/en-US/vbgeneral/thread/6ac8e418-f91a-40a2-9ac4-084288144ef3/

    Prerequisites: Create a form named Form1 and copy all code to Form1.vb.
    Public Class Form1     
        
        Private Structure MSLLHOOKSTRUCT     
            Public pt As Point     
            Public mouseData As Int32     
            Public flags As Int32     
            Public time As Int32     
            Public extra As IntPtr     
        End Structure    
        
        Private _mouseHook As IntPtr     
        Private Const WH_MOUSE_LL As Int32 = 14     
        Private Delegate Function CallBack(ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32     
        Private _mouseProc As CallBack     
        Private Declare Function SetWindowsHookExW Lib "user32.dll" (ByVal idHook As Int32, ByVal HookProc As CallBack, ByVal hInstance As IntPtr, ByVal wParam As Int32) As IntPtr     
        Private Declare Function UnhookWindowsHookEx Lib "user32.dll" (ByVal hook As IntPtr) As Boolean    
        Private Declare Function CallNextHookEx Lib "user32.dll" (ByVal idHook As Int32, ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32     
        Private Declare Function GetCurrentThreadId Lib "kernel32.dll" () As Integer    
        Private Declare Function GetModuleHandleW Lib "kernel32.dll" (ByVal fakezero As IntPtr) As IntPtr     
        
        Public Function InstallHook() As Boolean    
            If _mouseHook = IntPtr.Zero Then    
                _mouseProc = New CallBack(AddressOf MouseHookProc)     
                _mouseHook = SetWindowsHookExW(WH_MOUSE_LL, _mouseProc, GetModuleHandleW(IntPtr.Zero), 0)     
            End If    
            Return _mouseHook <> IntPtr.Zero     
        End Function    
        
        Public Sub RemoveHook()     
            If _mouseHook = IntPtr.Zero Then Return    
            UnhookWindowsHookEx(_mouseHook)     
            _mouseHook = IntPtr.Zero     
        End Sub    
        
        Private Shared Function MouseHookProc(ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32     
            Debug.Print("Message = {0}, x={1}, y={2}", wParam.ToInt32, lParam.pt.X, lParam.pt.Y)     
           ' Get the current cursor coordinate     
            Form2.Text = "Current Point: " & lParam.pt.X & " " & lParam.pt.Y         '       
            Return CallNextHookEx(WH_MOUSE_LL, nCode, wParam, lParam)     
        End Function    
        
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load     
            InstallHook()     
        End Sub    
        
        Private Sub Form1_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed     
            RemoveHook()     
        End Sub    
        
    End Class    
     

    Otherwise, you could look this article "How to develop a screen saver “and i beileve it could give you some help.
    http://www.codeproject.com/KB/cs/scrframework.aspx?display=Print

    This article explains:

    the basics of a screensaver
    loading a screensaver
    filling the whole screen
    handling multiple monitors
    handling events
    some little intricacies

    you could look the step4:

    Once you have loaded your screensaver, you have to handle events. This is because when the user uses the mouse or hits the keyboard, you probably want to do something, like ending the screensaver. To do this, you add event handlers to the KeyDown, MouseMove and MoveDown events of the screensaver form. In the event handlers, you could use the form's Close method to end the screensaver.

    There is one point to note here. When an application is executed, the current mouse parameters are passed to it by Windows. This naturally triggers a mouse event, which would close the screensaver. To handle this, add a Point variable in the class, initialize it when the application executes, and check the mouse position and mouse clicks when mouse events occur. If there happens to be any change, then call Close. The code would look something like:



    If you have any issue please feel free to tell us

    Bese wishes
    XIngwei Hu


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by Xingwei Hu Friday, June 12, 2009 3:36 AM
    Friday, June 12, 2009 3:34 AM

All replies

  • You could use a Global Mouse Hook
    Listing SPEC's is not a review !!! :-)
    Sunday, June 07, 2009 10:52 PM
  • But it should keep possible of course to leave your form, otherwize you cannot do almost anything anymore beside unplugging the power

    On the other hands should a mouse click outside the mouse area be not any problem, therefore you should have done some extremely strange, check those things is the only advice I can give you.

     
    • Marked as answer by Xingwei Hu Friday, June 12, 2009 3:36 AM
    Monday, June 08, 2009 4:28 AM
  • I'm not saying there isn't a better way to accomplish this - one idea, might be to monitor when your mouse leaves the client area to automatically pause the game...   But, if you want to pursue the capture idea, then you might look at the SetCapture/ReleaseCapture api methods.

    Tom Shelton
    Monday, June 08, 2009 5:03 AM
  • I'm not too worried about not being able to do anything outside the game window. This isn't the type of game that's going to be played for very long. More like the kind of thing you'd do during a tea break.

    Tom, can you give me a link to a "crash course" on using the SetCapture/ReleaseCapture api methods? I googled it, but I didn't find anything useful
    Logan Young, MCPD Web Developer hopeful
    Monday, June 08, 2009 12:10 PM
  • LoganY...  After playing with this, I don't think it accomplishes what you want - at least not exactly.  Sorry.

    Tom Shelton
    Monday, June 08, 2009 2:09 PM
  • Ok.  The api's I was thinking of was GetClipCursor and ClipCursor - which I don't think you actually need in .NET :)  There is a property on the Cursor object - Cursor.Clip that should allow you to manipulate this.  But, they don't seem to work on Windows 7 at all - or I'm doing something wrong :)  Anyway, if I get time then I'll try them out latter on my Vista box.
    Tom Shelton
    • Marked as answer by Xingwei Hu Friday, June 12, 2009 3:30 AM
    Monday, June 08, 2009 2:22 PM
  • Based on your post, you want to handle the mouse move event on the screen, here 
    you could look this link and will be able to get current point coordinate wherever the Cursor points to. it works fine on my computer and please take it a try.
    mouse position + mousehook
    link:http://social.msdn.microsoft.com/forums/en-US/vbgeneral/thread/6ac8e418-f91a-40a2-9ac4-084288144ef3/

    Prerequisites: Create a form named Form1 and copy all code to Form1.vb.
    Public Class Form1     
        
        Private Structure MSLLHOOKSTRUCT     
            Public pt As Point     
            Public mouseData As Int32     
            Public flags As Int32     
            Public time As Int32     
            Public extra As IntPtr     
        End Structure    
        
        Private _mouseHook As IntPtr     
        Private Const WH_MOUSE_LL As Int32 = 14     
        Private Delegate Function CallBack(ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32     
        Private _mouseProc As CallBack     
        Private Declare Function SetWindowsHookExW Lib "user32.dll" (ByVal idHook As Int32, ByVal HookProc As CallBack, ByVal hInstance As IntPtr, ByVal wParam As Int32) As IntPtr     
        Private Declare Function UnhookWindowsHookEx Lib "user32.dll" (ByVal hook As IntPtr) As Boolean    
        Private Declare Function CallNextHookEx Lib "user32.dll" (ByVal idHook As Int32, ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32     
        Private Declare Function GetCurrentThreadId Lib "kernel32.dll" () As Integer    
        Private Declare Function GetModuleHandleW Lib "kernel32.dll" (ByVal fakezero As IntPtr) As IntPtr     
        
        Public Function InstallHook() As Boolean    
            If _mouseHook = IntPtr.Zero Then    
                _mouseProc = New CallBack(AddressOf MouseHookProc)     
                _mouseHook = SetWindowsHookExW(WH_MOUSE_LL, _mouseProc, GetModuleHandleW(IntPtr.Zero), 0)     
            End If    
            Return _mouseHook <> IntPtr.Zero     
        End Function    
        
        Public Sub RemoveHook()     
            If _mouseHook = IntPtr.Zero Then Return    
            UnhookWindowsHookEx(_mouseHook)     
            _mouseHook = IntPtr.Zero     
        End Sub    
        
        Private Shared Function MouseHookProc(ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32     
            Debug.Print("Message = {0}, x={1}, y={2}", wParam.ToInt32, lParam.pt.X, lParam.pt.Y)     
           ' Get the current cursor coordinate     
            Form2.Text = "Current Point: " & lParam.pt.X & " " & lParam.pt.Y         '       
            Return CallNextHookEx(WH_MOUSE_LL, nCode, wParam, lParam)     
        End Function    
        
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load     
            InstallHook()     
        End Sub    
        
        Private Sub Form1_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed     
            RemoveHook()     
        End Sub    
        
    End Class    
     

    Otherwise, you could look this article "How to develop a screen saver “and i beileve it could give you some help.
    http://www.codeproject.com/KB/cs/scrframework.aspx?display=Print

    This article explains:

    the basics of a screensaver
    loading a screensaver
    filling the whole screen
    handling multiple monitors
    handling events
    some little intricacies

    you could look the step4:

    Once you have loaded your screensaver, you have to handle events. This is because when the user uses the mouse or hits the keyboard, you probably want to do something, like ending the screensaver. To do this, you add event handlers to the KeyDown, MouseMove and MoveDown events of the screensaver form. In the event handlers, you could use the form's Close method to end the screensaver.

    There is one point to note here. When an application is executed, the current mouse parameters are passed to it by Windows. This naturally triggers a mouse event, which would close the screensaver. To handle this, add a Point variable in the class, initialize it when the application executes, and check the mouse position and mouse clicks when mouse events occur. If there happens to be any change, then call Close. The code would look something like:



    If you have any issue please feel free to tell us

    Bese wishes
    XIngwei Hu


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by Xingwei Hu Friday, June 12, 2009 3:36 AM
    Friday, June 12, 2009 3:34 AM