Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0488: MouseOver per Mousetrackevent auslösen

 von 

Beschreibung 

Der Vorteil dieses "Mouseovers" ist, dass es automatisch immer den Status aktualisiert. So muss bei Verlassen des Objekts, nicht noch eine Prozedur folgen, die das Objekt zurücksetzt.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

CallWindowProcA (CallWindowProc), DefWindowProcA (DefWindowProc), SendMessageA (SendMessage), SetWindowLongA (SetWindowLong), TrackMouseEvent

Download:

Download des Beispielprojektes [3,57 KB]

'Dieser Quellcode stammt von http://www.activevb.de
'und kann frei verwendet werden. Für eventuelle Schäden
'wird nicht gehaftet.

'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
'Ansonsten viel Spaß und Erfolg mit diesem Source!

'-------- Anfang Projektdatei prjTrackMouseEvent.vbp --------
'--- Anfang Formular "frmTrackMouseEvent" alias frmTrackMouseEvent.frm  ---
' Steuerelement: TrackMouseEventControl "UCTrackMouseEvent1"
Option Explicit

'--- Ende Formular "frmTrackMouseEvent" alias frmTrackMouseEvent.frm  ---
'--- Anfang benutzerdefiniertes Steuerelement "UCTrackMouseEvent" alias UCTrackMouseEvent.ctl ---
Option Explicit
'*** Variables
    '*** tTrackMouseEventType
    Private tTrackMouseEventType As TRACKMOUSEEVENTTYPE
' ======================================================================================
' --------------------------------- UserControl ----------------------------------------
' ======================================================================================
Private Sub UserControl_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    '*** Ignore Errors
    On Error Resume Next
    '*** Check hWndHoverControl
    If hWndHoverControl <> UserControl.hwnd Then
        '*** SendMessage
        Call SendMessage(hWndHoverControl, WM_MOUSELEAVE, 0&, 0&)
        '*** Set hWndHoverControl
        hWndHoverControl = UserControl.hwnd
        '*** Check lpPrevWindowProc
        If lpPrevWindowProc = 0 Then
            '*** SetWindowLong
            lpPrevWindowProc = SetWindowLong(UserControl.hwnd, GWL_WNDPROC, AddressOf WindowProc)
        End If
        '*** Set tTrackMouseEventType.cbSize
        tTrackMouseEventType.cbSize = Len(tTrackMouseEventType)
        '*** Set tTrackMouseEventType.dwFlags
        tTrackMouseEventType.dwFlags = TME_LEAVE
        '*** Set tTrackMouseEventType.hwndTrack
        tTrackMouseEventType.hwndTrack = UserControl.hwnd
        '*** TrackMouseEvent
        Call TrackMouseEvent(tTrackMouseEventType)
        '*** Paint UserControl
        Call UserControl_Paint
    End If
    '*** Disable ErrorHandler
    On Error Goto 0
End Sub
Private Sub UserControl_Paint()
    '*** Ignore Errors
    On Error Resume Next
    
    '*** Die Auswertung im Paint Ereignis funktioniert nur
    '*** wenn Autoredraw=False da bei Autoredraw=True kein
    '*** Paint Ereignis ausgelöst wird
    
    '*** Abfrage ob Maus auf dem UserControl ist.
    '*** Hier kann z.B. ein Event ausgelöst werden.
    
    If UserControl.hwnd <> hWndHoverControl Then
    
        '*** Maus ist nicht auf dem UserControl
        
        
        '*** Change BackColor
        UserControl.BackColor = &HFF&
    Else
    
        '*** Maus ist auf dem UserControl
    
        '*** Change BackColor
        UserControl.BackColor = &HFF00&
    End If
    
    
    '*** Disable ErrorHandler
    On Error Goto 0
End Sub

'--- Ende benutzerdefiniertes Steuerelement "UCTrackMouseEvent" alias UCTrackMouseEvent.ctl ---
'--- Anfang Modul "modTrackMouseEvent" alias modTrackMouseEvent.bas ---
Option Explicit

' *** Constants
' *** SetWindowLong
Public Const GWL_WNDPROC = (-4)

' *** Window Messages
Public Const TME_CANCEL = &H80000000
Public Const TME_HOVER = &H1&
Public Const TME_LEAVE = &H2&
Public Const TME_NONCLIENT = &H10&
Public Const TME_QUERY = &H40000000
Public Const WM_MOUSELEAVE = &H2A3&
Public Const WM_PAINT = &HF

' *** Variables
' *** lpPrevWindowProc
Public lpPrevWindowProc As Long

' *** hWndHoverControl
Public hWndHoverControl As Long

' *** Types
' *** TrackMouseEventType
Public Type TRACKMOUSEEVENTTYPE
    cbSize As Long
    dwFlags As Long
    hwndTrack As Long
    dwHoverTime As Long
End Type

' *** Functions
' *** Window Functions
Public 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
                        
Public Declare Function DefWindowProc Lib "user32" _
                        Alias "DefWindowProcA" ( _
                        ByVal hwnd As Long, _
                        ByVal wMsg As Long, _
                        ByVal wParam As Long, _
                        ByVal lParam As Long) As Long
                        
Public Declare Function SendMessage Lib "user32" _
                        Alias "SendMessageA" ( _
                        ByVal hwnd As Long, _
                        ByVal wMsg As Long, _
                        ByVal wParam As Long, _
                        lParam As Any) As Long
                        
Public Declare Function SetWindowLong Lib "user32" _
                        Alias "SetWindowLongA" ( _
                        ByVal hwnd As Long, _
                        ByVal nIndex As Long, _
                        ByVal dwNewLong As Long) As Long
                        
Public Declare Function TrackMouseEvent Lib "user32" ( _
                        lpEventTrack As TRACKMOUSEEVENTTYPE) As Long
                        
' ======================================================================================
' --------------------------------- WindowProc -----------------------------------------
' ======================================================================================
Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, _
    ByVal lParam As Long) As Long
    
    ' *** Ignore Errors
    On Error Resume Next
    
    ' *** Select uMsg
    Select Case uMsg
    
    ' *** MouseLeave
    Case Is = WM_MOUSELEAVE
    
        ' *** Set hWndHoverControl
        hWndHoverControl = 0
        
        ' *** Set UMsg
        uMsg = WM_PAINT
        
        ' *** CallWindowProc
        WindowProc = CallWindowProc(lpPrevWindowProc, hwnd, uMsg, wParam, lParam)
        
        ' *** SetWindowLong
        If SetWindowLong(hwnd, GWL_WNDPROC, lpPrevWindowProc) <> 0 Then
        
            ' *** Set lpPrevWWindowProc
            lpPrevWindowProc = 0
        End If
        
    ' *** Other
    Case Else
    
        ' *** CallWindowProc
        WindowProc = CallWindowProc(lpPrevWindowProc, hwnd, uMsg, wParam, lParam)
    End Select
    
    ' *** Disable ErrorHandler
    On Error Goto 0
End Function
'--- Ende Modul "modTrackMouseEvent" alias modTrackMouseEvent.bas ---
'--------- Ende Projektdatei prjTrackMouseEvent.vbp ---------

Tipp-Kompatibilität:

Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel 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.

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 3 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von TiKu am 21.07.2009 um 00:51

Es ist außerdem unklug, das SubClassing bei WM_MOUSELEAVE zu beenden. Wenn man die Maus über das Control, aber nicht aus ihm heraus bewegt und dann mit Alt+F4 das Fenster schließt, wird glaube ich kein WM_MOUSELEAVE gesendet, sodass das Control zerstört wird während das Subclassing noch aktiv ist.

Kommentar von TiKu am 21.07.2009 um 00:43

Der Tipp hat beim Subclassing einen dicken Schnitzer drin. Die Parameter wParam und lParam haben für WM_PAINT eine gänzlich andere Bedeutung als für WM_MOUSELEAVE und können nicht einfach übernommen werden. Es ist ohnehin besser, ein Neuzeichnen des Fensters mittels InvalidateRect zu erzwingen statt mit WM_PAINT.
Außerdem ist es unklug, On Error Resume Next zu verwenden, wenn man Fehler nicht behandelt, sondern ignoriert. Ich kenne Leute, die haben schon Tage damit zugebracht, Fehler zu suchen, die sie nach 5 Sekunden gefunden hätten, wenn sie sie nicht versteckt hätten, indem sie nahezu jede Prozedur mit einem On Error Resume Next beginnen.

Kommentar von K.Heyer am 21.09.2007 um 13:08

Moin!

ich wollte mal als Noob fragen wie ich diese funktion in mein WinXP(64) einbetten kann.
Muss dazu sagen das meine Programierkenntnisse nahe null sind :-S.

Gruß Konstantin