Mausbewegungen registrieren
von Jochen Wiehrum
Grundlagen
Anfangen werden wir mit – einem leeren Modul und einem DirectX Objekt. Da wir es aber nur einmal brauchen, können wir davon ausgehen, dass es bereits initialisiert ist und „besorgen“ uns einfach nur das Objekt. Deshalb sieht die Initialisierungszeile so aus:
Public Function Init(DirectX7Object As DirectX7, _ OwnerFormHWnd As Long) As Boolean
Wie Ihr seht, muss auch die hWnd eines Fensters übergeben werden. Jetzt müssen wir erst mal in den Deklarationsbereich wechseln, um dort 2 wichtige Variablen zu deklarieren:
Private DInput As DirectInput '- Direct Input Objekt Private Maus As DirectInputDevice '- Das Gerät
Jetzt können wir endlich die Initialisierungs-Funktion schreiben:
Public Function InitMouse(DirectX7Object As DirectX7, _ OwnerFormHWnd As Long) As Boolean On Error Goto ErrOut 'Objekte erstellen: Set DInput = DirectX7Object.DirectInputCreate() 'Maus initialisieren (Standard - System - Maus) Set Maus = DInput.CreateDevice("GUID_SysMouse") Maus.SetCommonDataFormat DIFORMAT_MOUSE Maus.SetCooperativeLevel OwnerFormHWnd, _ DISCL_BACKGROUND Or _ DISCL_NONEXCLUSIVE '1. Owner '2. Exklusivmodus 'Verbindung herstellen: Maus.Acquire InitMouse = True Exit Function ErrOut: InitMouse = False End Function
Zur Erläuterung:
Falls ein Fehler entsteht, gibt die Funktion False zurück, andernfalls natürlich True. Zu erst erstellen wir ein Direct-Input Objekt. Wenn ihr Direct Input auch schon für die Tastatur oder für den Joystick benutzt, könnte ihr auch dies schon am Anfang übergeben - genau wie das DirectX-Objekt. Anschließend erstellen wir ein DirectInputDevic. Das ist das eigentliche „Mausobjekt“. Dieses wird in der nächsten Zeile initialisiert. „GUID_SysMouse“ heißt, dass die Systemmaus verwendet werden soll. Jetzt müssen wir nur noch den Cooperativelevel setzen. Damit teilen wir DirectX mit, ob Windows auch noch was von der Maus abbekommen soll. Bei einer Grafikkarte ist das nicht so empfehlenswert, aber bei Maus, Tastatur und Joystick ist es einfacher… Dann kommt die wichtigste Zeile. Sie „verbindet“ zum Gerät. Jetzt können wir ständig den Status abfragen. Doch vorher schreiben wir noch eine Funktion, die die Verbindung wieder trennt:
Public Function DestroyMouse() As Boolean On Error Goto ErrOut Set DInput = Nothing Set Maus = Nothing DestroyMouse = True Exit Function ErrOut: DestroyMouse = False End Function
Die Funktionsweise sollte sich von selbst erklären ;-)
Jetzt kommt ein etwas anspruchsvollerer Teil: Das Abfragen. Je nach Art des Programms reichen diese Zeilen:
Public Function GetMState() As DIMOUSESTATE Maus.GetDeviceStateMouse GetMState End Function
Manchmal ist es aber einfacher, das Programm ein wenig komplexer auszulegen. Dafür erleichtert es auf Dauer das Abrufen der Mausinformationen. Dafür ergänzen wir den Deklarationsabschnitt um folgende Variablen:
Public MousePosX As Integer Public MousePosY As Integer Public MousePosZ As Integer Public Button1 As Boolean Public Button2 As Boolean Public Button3 As Boolean Public Button4 As Boolean
Das macht die Informationen leichter Nutzbar, da man die Werte bis zur nächsten Abfrage bereitgestellt bekommt. Natürlich müssen die Variablen regelmäßig gefüllt werden…
DirectInput gibt immer einen „Ausschlag der Achse“ aus, d.h. ich habe die Maus zum Beispiel in der Mitte des Bildschirms, wenn ich sie aber still halte, gibt DirectInput 0 als X- und Y-Achse zurück. Also müssen wir rechnen. Bei einem Mausrad ist die Bewegung allerdings wesentlich interessanter, deshalb zählen wir hier nicht extra mit. Das klingt jetzt sehr kompliziert – ich weiß – aber wenn man den folgenden Code verstanden hat, ist auch das leicht zu begreifen.
Public Function GetMouseState() As Boolean On Error Goto ErrOut Dim Temp As DIMOUSESTATE Temp = GetMState MousePosX = MousePosX + Temp.x MousePosY = MousePosY + Temp.y If MousePosX > 800 Then MousePosX = 800 If MousePosY > 600 Then MousePosY = 600 If MousePosX < 0 Then MousePosX = 0 If MousePosY < 0 Then MousePosY = 0 MousePosZ = Temp.z Button1 = IIf(Temp.buttons(0) = 0, False, True) Button2 = IIf(Temp.buttons(1) = 0, False, True) Button3 = IIf(Temp.buttons(2) = 0, False, True) Button4 = IIf(Temp.buttons(3) = 0, False, True) GetMouseState = True Exit Function ErrOut: GetMouseState = False End Function
Dieser Code aktualisiert also unsere Variablen. Außerdem sorgt er dafür, dass die Maus nicht aus dem Bild „wandert“, in dem er sie in einem Rahmen von 800*600 Pixel hält. Sollte dies zu viel oder zu wenig sein, müssen nur die beiden oberen Zeilen geändert werden. Man kann die 4 Zeilen natürlich auch komplett entfernen, dann darf aber der Rahmen der MousePosX und MousePosY Variablen nicht gesprängt werden…
Fertig, jetzt lässt sich das Programm testen:
Beispiel
Zu erst müssen wir ein neues Projekt anlegen und unter Verweise „DirectX 7 for Visual Basic Type Library“ hinzufügen. Dann legen wir auf Form1 2 große Label an.
Jetzt schreiben wir in den Deklarationsbereich:
Dim DX7 As DirectX7 Dim bRunning As Boolean
In Form_Load müssen wir nun das DirectX Objekt anlegen, die Maus ansteuern und aktuell halten, so lange, bis das Formular wieder entladen wird. Hier der komplette Code:
Private Sub Form_Load() Set DX7 = New DirectX7 If InitMouse(DX7, Me.hWnd) = False Then MsgBox "Feher" Exit Sub End If Me.Show bRunning = True Do While bRunning GetMouseState Label1 = "X: " & MousePosX & vbCrLf & _ "Y: " & MousePosY & vbCrLf & _ "Z: " & MousePosZ Label2 = IIf(Button1, "X", "O") & " " & _ IIf(Button2, "X", "O") & " " & _ IIf(Button3, "X", "O") & " " & _ IIf(Button4, "X", "O") & " " DoEvents Loop End Sub
Nehmt euch viel Zeit, um dieses Beispiel zu begreifen und DirectInput zu lernen, es ist schwierig, aber nicht unmöglich! Viel Spaß weiterhin mit DirectX und VB
Ihre Meinung
Falls Sie Fragen zu diesem Tutorial haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.