Version 2.0!
Features
Tutorials
Files
Glossary
Projects
Contact
Links
Message Board
Extras
LuckyCam
Old News
Sign Guestbook
View Guestbook
VB Horoscope
VB Photo Album
.
ATTENTION READERS! Lucky's VB Gaming Site is no longer active. For updated game programming information and tutorials, please visit The Game Programming Wiki!

Mouse Handling

Here kitty-kitty! It's time to catch a mouse. Actually, we're not going to catch it, we're going to acquire it. If you've been looking for a more robust and precise alternative to standard VB mouse handling, you've come to the right place my feline friend!

But enough Lucky babble, lets talk DirectX. There are a few things you'll have to come to terms with if you'd like to use DirectInput to handle your mousey:

  • The standard mouse cursor will disappear
  • You'll have to draw your own cursor
  • You won't be given absolute X and Y coordinates
  • There will be no events, you must actively poll the device
  • Mommy isn't here to hold your hand anymore

    Still with me? Check out these initialization steps:

    Dim mobjdx As New DirectX7
    Dim mobjdi As DirectInput
    Dim mobjdiMouse As DirectInputDevice
    
        Set mobjdi = mobjdx.DirectInputCreate()
                
        Set mobjdiMouse = mobjdi.CreateDevice("GUID_SysMouse")
        
        mobjdiMouse.SetCommonDataFormat DIFORMAT_MOUSE
        mobjdiMouse.SetCooperativeLevel frmMouse.hWnd, DISCL_FOREGROUND Or DISCL_EXCLUSIVE
        mobjdiMouse.Acquire
    

    Here we have initialized the DirectInput object, and then used it to create a device. The DirectInput.CreateDevice method accepts one argument, the "GUID" of the device we'd like to create. To access the system's standard mouse, simply pass "GUID_SysMouse". Next, we set the data format we'll be using for the device. This tells DirectInput how to interpret the data that it receives. Obviously, we want to interpret the data as DIFORMAT_MOUSE. Finally, we set the cooperative level (much like DirectDraw), and call the DirectInputDevice.Acquire method to initialize data acquisition for the device.

    It is important to note: If the Form object passed as the first parameter of the SetCooperativeLevel method is not yet visible, the Acquire method will fail! Be sure to call Form.Show when needed. Also, if we lose exclusivity (if some other program takes the mouse away from us), we will have to reacquire the mouse or face the consequences (errors)!

    Once acquired, we can poll the device for input whenever we feel like:

    Dim mdiMState As DIMOUSESTATE
    
        mobjdiMouse.GetDeviceStateMouse mdiMState
    

    DIMOUSESTATE is like a UDT for mouse data. It can contain info on the X, Y, and Z (!!!) motion of the mouse, in addition to info on the various button states. Calling the DirectInputDevice.GetDeviceStateMouse method fills the variable with the most recent data received from the mouse. You may want to place some error handling code around this call, it will fail and raise an error if we've lost exclusivity.

    The info returned, as I said before, is NOT absolute. Checking the value of mdiMState.x will NOT give you the current X-coordinate of the mouse. What it will give you is the mouse X-displacement since the last time you checked the mouse state. This means that you have to keep track of the mouse's position yourself:

    Const MOUSE_SPEED = 2
    Dim mintMouseX As Integer
    
        mintMouseX = mintMouseX + mdiMState.x * MOUSE_SPEED
    

    This code will add the observed X-displacement of the mouse to the current cursor X-coordinate. Also, it multiplies the displacement by some constant, allowing us to increase the sensitivity of motion. Do the same thing for the Y-displacement, and you've got yourself some absolute coordinates! You should probably include some code that checks for the edges of the screen (or form) to ensure that the cursor doesn't escape and run amok.

    Dim mblnLMouseButton As Boolean
    Dim mblnRMouseButton As Boolean
    
        If mdiMState.buttons(0) <> 0 Then mblnLMouseButton = True
        If mdiMState.buttons(0) = 0 Then mblnLMouseButton = False
        
        If mdiMState.buttons(1) <> 0 Then mblnRMouseButton = True
        If mdiMState.buttons(1) = 0 Then mblnRMouseButton = False
    

    Buttons! Can't forget those! DirectInput gives support for up to 8 buttons (or something crazy like that), but we'll just use the standard left and right mouse buttons here. The buttons member of the DIMOUSESTATE type is an array, the first index represents the state of the left mouse button, the second index represents the state of the right mouse button. We need only check these values as compared to zero to determine if they are currently being held or not. Then, assigning values to some booleans makes it easy for us to check this info whenever we like.

    That's all there is to it. You now have some variables that describe the X and Y coordinates, and some booleans that describe the button states. Use this information as you see fit!

        mobjdiMouse.Unacquire
            
        Set mobjdiMouse = Nothing
        Set mobjdi = Nothing
    

    Termination is always fun. Don't forget to Unacquire the mouse when you're done.

    Click here to download some sample source code.