Problem
Wenn Sie bei der Arbeit in Formularen aus Versehen das Mausrad betätigen, führt Access unkontrollierbare Datensatzwechsel aus. Das kann zum Beispiel dazu führen, dass neue oder geänderte Datensätze unvollständig gespeichert werden, Eingaben/ Änderungen in falschen Datensätzen erfolgen oder Datensätze „angesteuert“ werden können, die dem Anwender eigentlich verborgen bleiben sollten.
Leider lässt sich die Abfrage des Mausrades in Access weder ausschalten noch mit den vorhandenen Funktionen oder über Ereignisprozeduren unterdrücken, sodass viele Entwickler und Datenbank- Administratoren die Mausrad-Funktion in letzter Konsequenz entnervt über die Systemsteuerung ausschalten.
Lösung
Eine alternative Möglichkeit, hier Abhilfe zu schaffen, besteht darin, die für ein Access-Formular ausgelösten Ereignisse auf Systemebene zu filtern und das Ereignis „Mausrad“ nur für das betreffende Formular zu eliminieren. In anderen Fenstern kann das Mausrad wie gewohnt genutzt werden. Dazu ist eine Funktion notwendig, die quasi zwischen das Formular und das Betriebssystem geschaltet wird. Dieser Funktion werden zunächst alle von Windows an das Formular gesendeten Ereignisse übergeben; sie prüft sie und reagiert entsprechend, indem sie das Ereignis „Mausrad“ nicht an das Formular weitergibt, während alle anderen Ereignisse den Filter unverändert passieren.
Vom Grundsatz her kann eine solche Filterfunktion in VBA geschrieben und über eine API-Funktion initialisiert werden. Da sie aber kontinuierlich von Windows, beispielsweise bei Mausbewegungen oder Tastendrücken, aufgerufen wird, muss sie sich immer an der gleichen Speicheradresse befinden. Das ist im VBA-Speichermodell erst ab VBA 6.0/Access 2000 einigermaßen zuverlässig der Fall. In früheren VBA-Versionen können Funktionen im Speicher zum Beispiel durch Aufräumaktionen im Zeichenkettenbereich („Garbage Collection“) wandern, sodass unter Umständen mit einem Absturz von Access zu rechnen ist. Außerdem steht eine Funktion „AddressOf“ zur Ermittlung der Adresse einer Variablen, Prozedur oder Funktion erst ab VBA 6.0 zur Verfügung. Aber auch mit VBA 6.0 bzw. Access 2000/2002/2003 ist der Einsatz einer Filterfunktion für Ereignisse nicht ganz unproblematisch.
Wenn die VBA-Entwicklungsumgebung geöffnet wird, läuft eine rein in VBA realisierte Lösung nicht mehr verlässlich und kann schlimmstenfalls auch zum Absturz von Access führen. Um sicherzustellen, dass die Filterfunktion sich immer an einer festen Adresse befindet und korrekt aufgerufen werden kann, empfiehlt sich die Auslagerung als Klasse in eine externe DLL, die dann über das Menü EXTRAS-VERWEISE referenziert wird. Diese DLL wird unabhängig von Access in einen geschützten Speicherbereich geladen und verbleibt unberührt von den Aktionen in Access immer an einer festen Speicheradresse. Microsoft beschreibt eine solche Lösung im Knowledge-Base-Artikel „Q278379“. Da aber die wenigstens Access-Anwender in der Lage sind, eine solche DLL zu erstellen, haben wir sie für Sie vorbereitet. Um diese DLL bzw. die darauf basierende Lösung zur Unterdrückung des Mausrades in Ihren Datenbanken zu nutzen, gehen Sie wie folgt vor:
1. Starten Sie Access und öffnen Sie die Datenbank mit den Formularen, in denen das Mausrad unterdrückt werden soll.
2. Öffnen Sie das betreffende Formular im Entwurfsmodus und wählen Sie das Menü ANSICHT-CODE an, um den VBA-Editor zu starten.
3. Wählen Sie das Menü EXTRAS-VERWEISE an, klicken Sie auf die Schaltfläche DURCHSUCHEN, stellen Sie als „Dateityp“ den Eintrag „Ausführbare Dateien (*.EXE, .DLL)“ beziehungsweise „Klassenbibliotheken (*.OLB, *.TLB, *.DLL)“ ein, lokalisieren Sie die Datei „MouseWheel.dll“ im Windows- Systemverzeichnis und übernehmen Sie sie per Doppelklick.
4. In der Liste „Verfügbare Referenzen“ finden Sie nun einen aktivierten Eintrag „Access-Berater MouseWheel DLL“. Übernehmen Sie die Einbindung mit einem Klick auf die Schaltfläche OK.
5. Geben Sie im allgemeinen Teil des Formularmoduls die folgende Deklaration und die folgende Prozedur ein (oder kopieren Sie die Zeilen aus dem Formular „Kunden/MouseWheel“ der Beispieldatenbank):
Private WithEvents
clsMouseWheel
As MouseWheel.CMouseWheel
Private Sub
clsMouseWheel_MouseWheel
(Cancel As Integer)
Beep
Cancel = True
End Sub
6. Verlassen Sie nun zunächst die VBAEntwicklungsumgebung und wählen Sie das Menü ANSICHT-EIGENSCHAFTEN an, um das Eigenschaftenfenster für das Formular anzeigen zu lassen.
7. Stellen Sie die Eigenschaft „Bei Laden“ auf den Eintrag „[Ereignisprozedur]“, klicken Sie auf die Schaltfläche mit den drei Punkten und geben Sie die folgenden Anweisungen im VBA-Editor ein:
Private Sub Form_Load()
Set clsMouseWheel
= New MouseWheel.CMouseWheel
Set clsMouseWheel.Form = Me
clsMouseWheel.SubClassHook-
Form
End Sub
Wenn Sie in „Form_Load“ bereits eigene Anweisungen untergebracht haben, setzen Sie die drei oben gezeigten Zeilen an den Anfang der Ereignisprozedur.
8. Stellen Sie die Eigenschaft „Bei Schließen“ auf den Eintrag „[Ereignisprozedur]“ ein, klicken Sie auf die Schaltfläche mit den drei Punkten und geben Sie die folgenden Anweisungen im VBA-Editor ein:
Private Sub Form_Close()
clsMouseWheel.SubClassUnHook-
Form
Set clsMouseWheel.Form
= Nothing
Set clsMouseWheel = Nothing
End Sub
Wenn Sie in „Form_Close“ bereits eigene Anweisungen untergebracht haben, setzen Sie die drei oben gezeigten Zeilen an das Ende der Ereignisprozedur. Wenn Sie nun das Formular über ANSICHT- FORMULARMODUS anzeigen lassen und das Mausrad betätigen, hören Sie lediglich einen akustischen Hinweis, es werden aber keine Datensatzwechsel mehr ausgeführt. In der DLL befindet sich die Funktion „Window- Proc“, die für die Filterung zuständig ist. Zwei weitere Funktionen „SubClassHookForm“ und „SubClassUnHook- Form“ aktivieren die Filterfunktion beim Laden des Formulars bzw. heben diesen Zustand wieder auf. Ist die Funktion aktiviert, schickt das Betriebssystem alle Ereignisse für das Formular zunächst an die Funktion „WindowProc“ in der DLL. Diese prüft auf das Ereignis „WM_Mouse- Wheel“. Tritt es auf, wird die benutzerdefinierte Ereignisprozedur „clsMouse- Wheel.MouseWheel“ im Formular aufgerufen. Über den Parameter „Cancel“ beziehungsweise die Zuweisung „= True“ veranlassen wir dort nach einem akustischen Hinweis, dass das Ereignis unterdrückt wird. Alternativ können Sie hier eine Meldung wie „Mausrad wird nicht unterstützt…“ anzeigen lassen oder „Beep“ weglassen, um das Ereignis stillschweigend unter den Tisch fallen zu lassen.