Microsoft DirectX 8.0 (Visual Basic)

ステップ 4 : マウスからのバッファリング データの取得

ScrawlB サンプルは、frmCanvas により実装される DirectXEvent8.DXCallback メソッド内部で、マウスのバッファリング データを取得する。入力イベントが発生すると必ずこのメソッドが呼び出される。

このメソッドは、Microsoft® DirectInput® がデータの格納に使用するバッファと同じサイズのバッファを宣言する。これは、以前の DirectInputDevice8.SetProperty の呼び出しにより設定されたサイズである。

Dim diDeviceData(1 To BufferSize) As DIDEVICEOBJECTDATA

また、実際に取得された項目数を受け取る変数、ループ カウンタ、およびイベントの前回のシーケンス番号を追跡する変数も必要である。

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

この時点でアプリケーションは、DirectInputDevice8.GetDeviceData を一度呼び出すことで、利用可能なデータをすべて取得する。

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

エラー トラップに注意してほしい。DirectInput が送信するイベントの 1 つは、取得の喪失である。たとえば、ユーザーが別のアプリケーションに切り替えた場合、ScrawlB はマウスを取得した状態にはない。イベントが送信され、GetDeviceData が呼び出されても、データは取得状態にあるデバイスからしか取得できないため、このメソッドは失敗する。

ここでアプリケーションは、取得した項目を補間し、DIDEVICEOBJECTDATA 型内のデータを調べ、lOfs メンバと目的のさまざまなボタンと軸を表す定数を比較する。たとえば x 軸の場合、アプリケーションは lData メンバから軸位置の変化量を取得し、ユーザー定義の感度を計算しながら、これを使ってカーソル位置を調整する。これを次のサンプル コードに示す。

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

また、アプリケーションはシーケンス番号を調べて、前回の番号と比較する。2 つの軸イベントのシーケンス番号が同一の場合、マウスは斜めに移動している。階段エフェクトの発生を防ぐには、両方の軸の移動量が計算されるまで、カーソル位置の更新や線の描画を行わない方がよい。

            If OldSequence <> diDeviceData(i).lSequence Then
                UpdateCursor 
                OldSequence = diDeviceData(i).lSequence
            Else
                OldSequence = 0
            End If

ボタンの場合、メソッドは、lData 内の適切なビットをチェックして、イベントの種類を判断する。ビットが設定されている場合、マウス ボタンは押されている。それ以外の場合、マウス ボタンは押されていない。GetDeviceData はデバイスの現在の状態を返すものではないので、ボタンが押し下げられているかどうかの専用記録を保持するのは、アプリケーションが行わなければならない。左ボタンの場合、ScrawlB はこの情報を変数 Drawing に保持する。

        Case DIMOFS_BUTTON0
            If diDeviceData(i).lData And &H80 Then
                Drawing = True
 
                ' Line 関数のレコードを保持する。
                CurrentX = g_cursorx
                CurrentY = g_cursory
 
                ' ボタンがすぐに上がった場合はポイントを描画する。
                PSet (g_cursorx, g_cursory)
            Else
                Drawing = False
            End If
.
.
    End Select
Next i