Microsoft DirectX 8.1 (Visual Basic)

Step 4: Retrieving Buffered Data from the Mouse

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

The method declares an array of the same size as the buffer Microsoft® DirectInput® is using to store the data. This is the size that was set previously by a call to DirectInputDevice8.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 DirectInputDevice8.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 GetDeviceData will be called, but the method will fail because data can be retrieved only from a device that is in an acquired state.

The application next iterates through the retrieved items and examines the data in the DIDEVICEOBJECTDATA type, comparing the lOfs member against 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, as in the following code sample.

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. To avoid a staircase effect, it is 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 
                OldSequence = diDeviceData(i).lSequence
            Else
                OldSequence = 0
            End If

For the buttons, the method determines the event type 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 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