DirectX SDK

Step 4: Retrieve Buffered Data from the Mouse

[C++]

This topic pertains only to application development in Visual Basic. See DirectInput C/C++ Tutorials.

[Visual Basic]

The ScrawlB sample retrieves buffered mouse data inside the DirectXEvent.DXCallback method implemented by frmCanvas. This method is called each time an input event is signaled.

The method declares a buffer of the same size as the buffer DirectInput is using to store the data. This is the size that was set previously by a call to DirectInputDevice.SetProperty.

Dim diDeviceData(1 To BufferSize) As DIDEVICEOBJECTDATA

Also required are a variable to receive the number of items actually retrieved, a loop counter, and a variable to track the previous sequence number of an event:

Dim NumItems As Integer
Dim i As Integer
Static OldSequence As Long

The application now retrieves all the data available, in a single call to DirectInputDevice.GetDeviceData:

On Error GoTo INPUTLOST
NumItems = objDIDev.GetDeviceData(diDeviceData, 0)
On Error GoTo 0

Note the error trap. One of the events that DirectInput will signal is loss of acquisition. If the user switches to another application, for instance, ScrawlB will no longer have the mouse in the acquired state. An event will be signaled and this method will be called, but GetDeviceData will fail, because data can only be retrieved from an acquired device.

The application now iterates through the retrieved items and examines the data in the DIDEVICEOBJECTDATA type, comparing the lOfs member with the constants for the various buttons and axes that are of interest. For the x-axis, for instance, the application extracts the change in axis position from the lData member and uses this to adjust the cursor position, taking into account the user-defined sensitivity:

For i = 1 To NumItems
    Select Case diDeviceData(i).lOfs
        Case DIMOFS_X
           g_cursorx = g_cursorx + diDeviceData(i).lData * _
               g_Sensitivity

The application also examines the sequence number and compares it with the previous one. If two axis events have the same sequence number, the mouse has been moved diagonally, and it's not desirable to update the cursor position or draw a line until both movements have been taken into account.

           If OldSequence <> diDeviceData(i).lSequence Then
             UpdateCursor  ' Move cursor and maybe draw line
             OldSequence = diDeviceData(i).lSequence
           Else
             OldSequence = 0
           End If

For the buttons, the method determines the kind of event by checking the appropriate bit in lData. If the bit is set, the mouse button was pressed; otherwise, it was released. Remember, GetDeviceData does not return the current state of the device, so it is up to the application to keep a private record of whether a button is being held down. For the left button, ScrawlB keeps this information in the Drawing Boolean variable.

         Case DIMOFS_BUTTON0
           If diDeviceData(i).lData And &H80 Then
             Drawing = True
 
             ' Keep record for Line function
             CurrentX = g_cursorx
             CurrentY = g_cursory
 
             ' Draw point in case button-up follows immediately
             PSet (g_cursorx, g_cursory)
           Else
             Drawing = False
           End If
.
.
.
    End Select
Next i