Rubrik: | VB-Versionen: VB5, VB6 | 01.03.04 |
WheelMouse-Funktionalität für beliebige Controls Dieser Tipp verrät, wie man beliebige Controls (z.B. MSFlexGrid, ListView, ListBox, TextBox etc.) mit WheelMouse-Unterstützung ausstattet. | ||
Autor: Dieter Otter | Bewertung: | Views: 2.139 |
http://www.tools4vb.de/ | System: Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt |
Das Mausrädchen der sogenannten WheelMouse ist ein sehr häufiger Diskussionspunkt in unseren Foren. Beispielsweise wurde erst kürzlich wieder gefragt, warum das Scrollrad im Microsoft FlexGrid-Control nicht (immer) funktioniert. Manchmal liegt es am falschen Maustreiber - ein anderes Mal kommt das Statement: unter Win... funktionierte es noch, doch seit ich Windows XP installiert habe, funktioniert es nicht mehr.
Um auf "Nummer Sicher" zu gehen, kann man das FlexGrid mit einer immer funktionierenden Wheel-Scroll-Funktion ausstatten. Hierzu muss man das Control "subclassen", d.h. man "fängt" die Window-Messages ab und prüft, ob sich darunter zufällig die Nachricht WM_MOUSEWHEEL befindet. Ist dies der Fall, so wurde das Scrollrädchen gedreht - entweder nach vorne oder nach hinten. Die Drehrichtung selbst lässt sich über den wParam-Parameter abfragen. Nun braucht man das Control nur noch zu benachrichtigen, in welche Richtung es seinen Inhalt scrollen soll
Ein kleines Beispiel:
Erstellen Sie ein neues Projekt und platzieren auf die Form das MSFlexGrid-Control. Im Form_Load Ereignis füllen wir das Grid mit 1000 Zeilen:
Option Explicit Private Sub Form_Load() Dim i As Long ' FlexGrid mit 1000 Zeilen füllen With MSFlexGrid1 .Rows = 1000 For i = 1 To .Rows - 1 .TextMatrix(i, 1) = "Eintrag " & CStr(i) Next i End With End Sub
Jetzt brauchen wir noch ein Modul für das Subclassing. Fügen Sie nachfolgenden Code in das Modul ein:
Option Explicit ' benötigte API-Funktionen Private Declare Function SetWindowLong Lib "user32" _ Alias "SetWindowLongA" ( _ ByVal hWnd As Long, _ ByVal nIndex As Long, _ ByVal dwNewLong As Long) As Long Private Declare Function CallWindowProc Lib "user32" _ Alias "CallWindowProcA" ( _ ByVal lpPrevWndFunc As Long, _ ByVal hWnd As Long, _ ByVal Msg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long ' Konstante für das Subclassing Private Const GWL_WNDPROC = (-4) Private Const WM_MOUSEWHEEL = &H20A ' Original-Addresse der Windowsprozedur merken Private oldWndProc As Long
' Subclassing starten Public Sub StartSubclass(ByVal hWnd As Long) oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WndProc) End Sub
' Windows-Messages abfragen Public Function WndProc(ByVal hWnd As Long, _ ByVal uMsg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long ' WM_MOUSEWHEEL-Message abfragen! If uMsg = WM_MOUSEWHEEL Then ' Mausrad wurde gedreht! If wParam < 0 Then ' nach hinten: ScrollDown SendKeys "%{Down}" Else ' nach vorne: ScrollUp SendKeys "%{Up}" End If Exit Function End If WndProc = CallWindowProc(oldWndProc, hWnd, uMsg, wParam, ByVal lParam) End Function
' Subclassing beenden Public Sub StopSubclass(ByVal hWnd As Long) SetWindowLong hWnd, GWL_WNDPROC, oldWndProc End Sub
Jetzt fügen Sie noch folgenden Code in den Codeteil der Form ein:
Private Sub MSFlexGrid1_GotFocus() ' Subclassing aktivieren StartSubclass MSFlexGrid1.hWnd End Sub
Private Sub MSFlexGrid1_KeyDown(KeyCode As Integer, Shift As Integer) ' WheelMouse? With MSFlexGrid1 If (KeyCode = vbKeyUp Or KeyCode = vbKeyDown) And (Shift = 4) Then Select Case KeyCode Case vbKeyUp ' nach oben scrollen KeyCode = 0 If .TopRow > 1 Then .TopRow = .TopRow - 1 Case vbKeyDown ' nach unten scrollen KeyCode = 0 If .TopRow < .Rows - 1 Then .TopRow = .TopRow + 1 End Select End If End With End Sub
Private Sub MSFlexGrid1_LostFocus() ' Subclassing beenden StopSubclass MSFlexGrid1.hWnd End Sub
Der Trick hierbei ist folgender:
Erhält das FlexGrid den Fokus wird das Subclassing gestartet. In der Funktion WndProc wird dann die Nachricht WM_MOUSEWHEEL abgefragt und je nach Drehrichtung des Scrollrades die Tastatenkombination ALT+Up bzw. ALT+Down an das FlexGrid gesendet. Im KeyDown-Ereignis des FlexGrids braucht man jetzt nur diese beiden Tastenkombinationen abfragen. Verliert das Grid den Fokus, wird das Subclassing wieder ausgeschaltet.
Auf diese Weise kann man nahezu jedes Control mit WheelMouse-Funktionalität ausstatten.