RSS
StartseiteKnowledge LibraryTop 10Impressum

Zeilen-Tooltips

Überlange Zeilen einer TextBox als Tooltip anzeigen

Häufig lässt sich nicht der vollständige Inhalt einer Textbox darstellen. Wäre es da nicht praktisch, wenn man nur noch mit der Maus auf die Textbox zeigt und ihr vollständiger Inhalt als ToolTip angezeigt wird? Dieser Artikel zeigt Ihnen, wie Sie dieses Komfort-Feature auch für mehrzeilige Textboxen implementieren..

Winfried Kaiser/-td

Selbst wenn man sich noch so viel Mühe beim Entwurf der Oberfläche seiner Anwendung gibt, kommt es immer wieder vor, dass in Textfeldern mehr Text eingefügt wird, als dargestellt werden kann. Bei einer einzeiligen Textbox kann man den vollständigen Inhalt nur durch den Cursor nach und nach sichtbar machen. Eine recht mühselige Prozedur. Bei einer mehrzeiligen Textbox lassen sich hierfür wenigstens Scrollleisten anzeigen.

In beiden Fällen wäre es aber doch um einiges komfortabler, den Inhalt der Textzeile alternativ als Tooltip anzuzeigen, so dass man nur noch mit der Maus auf die Zeile zeigen muss, um sie vollständig lesen zu können.

Dazu muss zunächst ermittelt werden, über welcher Zeile der Mauszeiger momentan verweilt. Dabei behilflich sind die API Funktionen GetCursorPos und SendMessage mit der Konstanten EM_CHARFROMPOS. Das erste Zeichen und die Zeichenlänge dieser Zeile liefert SendMessage und die Konstanten EM_LINEINDEX und EM_LINELENGTH. Mit diesen Informationen und der Mid$-Funktion, lässt sich der Inhalt der aktuellen Textbox Zeile unter dem Mauszeiger ausschneiden und ggf. für die Anzeige als Tooltip über die ToolTipText-Eigenschaft der Textbox verwerten.

Da dieser Tooltip aber nur angezeigt werden soll, wenn die Zeile nicht vollständig dargestellt werden kann, muss zuvor noch getestet werden, ob der Inhalt der Zeile in den sichtbaren Bereich der Textbox passt oder nicht. Die API-Funktion GetClientRect liefert die hierfür erforderlichen Abmessungen des Innenbereichs der Textbox. Die TextWidth-Funktion des Textbox-Parents(!) liefert die Breite der Zeile. Dies sind natürlich nur dann die richtigen Maße, wenn die Font-Einstellungen der Textbox mit denen des Formular identisch sind.

Die Folgende Routine TBAutoToolTip wird im MouseMove-Ereignis der entsprechenden TextBox aufgerufen und erwartet selbige als einzigen Parameter, um bei Bedarf die aktuelle Zeile als Tooltip darzustellen.

Private Type POINTAPI
   X As Long
   Y As Long
End Type

Private Type RECT
   Left   As Long
   Top    As Long
   Right  As Long
   Bottom As Long
End Type

Private Declare Function GetCursorPos Lib "user32" ( _
                ByRef lpPoint As POINTAPI _
                ) As Long
Private Declare Function ScreenToClient Lib "user32" ( _
        	    ByVal hwnd As Long, _
                ByRef lpPoint As POINTAPI _
                ) As Long

Private Declare Function GetClientRect Lib "user32" ( _
                ByVal hwnd As Long, _
                Byref lpRect As RECT _
                ) As Long

Private Declare Function SendMessage Lib "user32" _
                Alias "SendMessageA" ( _
                ByVal hwnd As Long, _
                ByVal wMsg As Long, _
                ByVal wParam As Long, _
                ByRef lParam As Any _
                ) As Long

Private Const EM_CHARFROMPOS = &HD7
Private Const EM_LINEINDEX = &HBB
Private Const EM_LINELENGTH = &HC1

Public Sub TBAutoToolTip(ByRef TextBox As TextBox)
   Dim lPT          As POINTAPI
   Dim lCurrentLine As Long
   Dim lLineStart   As Long
   Dim lLineLength  As Long
   Dim lLineText    As String
   Dim lRC          As RECT
   Dim lInnerWidth  As Single
      
   With TextBox
      GetCursorPos lPT
      ScreenToClient .hwnd, lPT

      lCurrentLine = SendMessage(.hwnd, EM_CHARFROMPOS, 0, _
                        ByVal CLng(CInt(lPT.Y) * &H10000 + CInt(lPT.X)))

      lCurrentLine = (lCurrentLine \ &H10000)
   
      lLineStart = SendMessage(.hwnd, EM_LINEINDEX, lCurrentLine, ByVal 0&)
      lLineLength = SendMessage(.hwnd, EM_LINELENGTH, lLineStart, ByVal 0&)
   
      lLineText = Mid$(.Text, lLineStart + 1, lLineLength)
      
      GetClientRect .hwnd, lRC
      lInnerWidth = CSng(lRC.Right - lRC.Left) * Screen.TwipsPerPixelX
   
      If .Parent.TextWidth(lLineText) < lInnerWidth Then
         lLineText = vbNullString
      End If
   
      If .ToolTipText <> lLineText Then
         .ToolTipText = lLineText
      End If
   End With
End Sub