Visual Basic, VB .NET, ASP, Active X, Access, SQL Server

ActiveX: Interceptando eventos MouseEnter e MouseExit sem subclassificar

 

A seguinte dica mostra que você somente precisa de três APIs para tratar a entrada do mouse na área de um controle ActiveX e a sua saída sem ter de subclassifcar o controle.

O Visual Basic dispara o evento MouseMove quando o cursor do mouse está na área de um controle, o que torna fácil saber quando o cursor entra na área do controle. Contudo, determinar quando o mouse deixa o controle é mais difícil. Você pode resolver o problema monitorando a primeira vez que o  controle dispara o evento MouseMove, que corresponde ao evento MouseEnter inexistente. Neste momento, você "captura" o mouse com a API SetCapture, de modo que o controle receberá mensagens de MouseMove mesmo se o cursor estiver fora da janela do controle.

Uma vez que você tenha capturado a entrada de mouse, você pode checar as coordenadas do cursor e verificar se ele ainda está na área do controle. Quando o mouse deixa a janela do controle, é a hora do evento MouseExit, e você deve liberar a captura do mouse com ReleaseCapture(). Eis aqui o código que realiza o truque para o botão Command1, mas você pode modificá-lo facilmente para qualquer controle que tenha a propriedade hWnd:

Private Declare Function SetCapture Lib "user32" _
    (ByVal hwnd As Long) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function GetCapture Lib "user32" () As Long

Private Sub Command1_MouseMove(Button As Integer, _
    Shift As Integer, X As Single, Y As Single)

    If (X < 0) Or (Y < 0) Or (X > Command1.Width) _
        Or (Y > Command1.Height) Then
        ' o pseudo-evento MOUSELEAVE 
        ReleaseCapture
        ' neste exemplo, reverte o título ao normal
        
        Command1.Font.Bold = False
    ElseIf GetCapture() <> Command1.hwnd Then
        ' o pseudo-evento MOUSEENTER
        SetCapture Command1.hwnd
        ' neste exemplo, muda o título para negrito
        Command1.Font.Bold = True
    End If
End Sub

Eis aqui um outro exemplo que seleciona o texto de um textbox quando o cursor do mouse está sobre ele:

Private Sub Text1_MouseMove(Button As Integer, Shift As Integer, _
    X As Single, Y As Single)

    If (X Or Y) < 0 Or (X > Text1.Width) Or (Y > Text1.Height) Then
        ReleaseCapture
        Text1.SelLength = 0
    ElseIf GetCapture() <> Text1.hWnd Then
        SetCapture Text1.hWnd
        Text1.SelStart = 0
        Text1.SelLength = Len(Text1)
        Text1.SetFocus
    End If
End Sub