Option Explicit
Public Enum ttIconType
TTNoIcon = 0
TTIconInfo = 1
TTIconWarning = 2
TTIconError = 3
End Enum
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type TOOLINFO
cbSize As Long
uFlags As Long
#If Win64 Then
hwnd As LongLong
uId As LongLong
cRect As RECT
hinst As LongLong
#Else
hwnd As Long
uId As Long
cRect As RECT
hinst As Long
#End If
lpszText As String
End Type
Private Type InitCommonControlsEx
Size As Long
ICC As Long
End Type
#If VBA7 Then
Private Declare PtrSafe Sub InitCommonControls Lib "comctl32.dll" ()
Private Declare PtrSafe Function InitCommonControlsEx Lib "comctl32.dll" (iccex As InitCommonControlsEx) As Long
Private Declare PtrSafe Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As LongPtr, ByVal hMenu As Long, ByVal hInstance As LongPtr, lpParam As Any) As LongPtr
Private Declare PtrSafe Function DestroyWindow Lib "user32" (ByVal hwnd As LongPtr) As Long
Private Declare PtrSafe Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, ByRef lParam As Any) As LongPtr
Private Declare PtrSafe Function SendMessageLong Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
Private Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As LongPtr
Private Declare PtrSafe Function TranslateColor Lib "oleAut32.dll" Alias "OleTranslateColor" (ByVal Clr As OLE_COLOR, ByVal palet As LongPtr, col As Long) As Long
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
#Else
Private Declare Sub InitCommonControls Lib "comctl32.dll" ()
Private Declare Function InitCommonControlsEx Lib "comctl32.dll" (iccex As InitCommonControlsEx) As Long
Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long
Private Declare Function DestroyWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Declare Function SendMessageLong Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function TranslateColor Lib "oleAut32.dll" Alias "OleTranslateColor" (ByVal Clr As OLE_COLOR, ByVal palet As Long, col As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#End If
#If Win64 Then
Public Sub CreateToolTip(ByVal ParentHwnd As LongLong, _
ByVal TipText As String, _
Optional ByVal uIcon As ttIconType = TTNoIcon, _
Optional ByVal sTitle As String, _
Optional ByVal lForeColor As Long = -1, _
Optional ByVal lBackColor As Long = -1, _
Optional ByVal bCentered As Boolean, _
Optional ByVal bBalloon As Boolean, _
Optional ByVal lWrapTextLength As Long = 50, _
Optional ByVal lDelayTime As Long = 200, _
Optional ByVal lVisibleTime As Long = 5000)
#Else
Public Sub CreateToolTip(ByVal ParentHwnd As Long, _
ByVal TipText As String, _
Optional ByVal uIcon As ttIconType = TTNoIcon, _
Optional ByVal sTitle As String, _
Optional ByVal lForeColor As Long = -1, _
Optional ByVal lBackColor As Long = -1, _
Optional ByVal bCentered As Boolean, _
Optional ByVal bBalloon As Boolean, _
Optional ByVal lWrapTextLength As Long = 50, _
Optional ByVal lDelayTime As Long = 200, _
Optional ByVal lVisibleTime As Long = 5000)
#End If
' If lWrapTextLength = 0 then there will be no wrap.
' Also, lWrapTextLength = 40 is a minimum value.
' The max for lVisibleTime is 32767.
Const TOOLTIPS_CLASSA = "tooltips_class32"
Const ICC_WIN95_CLASSES = &HFF
Const CW_USEDEFAULT = &H80000000
Const WM_USER = &H400
Const TTM_ACTIVATE = WM_USER + 1
Const TTM_ADDTOOLA = WM_USER + 4
Const TTM_SETDELAYTIME = WM_USER + 3
Const TTM_UPDATETIPTEXTA = WM_USER + 12
Const TTM_SETTIPBKCOLOR = WM_USER + 19
Const TTM_SETTIPTEXTCOLOR = WM_USER + 20
Const TTM_SETMAXTIPWIDTH = WM_USER + 24
Const TTM_SETTITLE = WM_USER + 32
Const TTS_NOPREFIX = &H2
Const TTS_BALLOON = &H40
Const TTS_ALWAYSTIP = &H1
Const TTF_CENTERTIP = &H2
Const TTF_IDISHWND = &H1
Const TTF_SUBCLASS = &H10
Const TTF_TRANSPARENT = &H100
Const TTDT_AUTOPOP = 2
Const TTDT_INITIAL = 3
#If Win64 Then
Dim hwndTT As LongLong
#Else
Dim hwndTT As Long
#End If
Static bCommonControlsInitialized As Boolean
Dim lWinStyle As Long, lRealColor As Long
Dim ti As TOOLINFO
Dim tIccex As InitCommonControlsEx
If Not bCommonControlsInitialized Then
With tIccex
.Size = LenB(tIccex)
.ICC = ICC_WIN95_CLASSES
End With
If InitCommonControlsEx(tIccex) = False Then
Call InitCommonControls
End If
bCommonControlsInitialized = True
End If
' Destroy any previous tooltip.
Call DestroyWindow(FindWindow(TOOLTIPS_CLASSA, "MyToolTip"))
' Format the text.
FormatTooltipText TipText, lWrapTextLength
' Initial style settings.
lWinStyle = TTS_ALWAYSTIP Or TTS_NOPREFIX
If bBalloon Then lWinStyle = lWinStyle Or TTS_BALLOON ' Create baloon style if desired.
' Set the style.
hwndTT = CreateWindowEx(0&, TOOLTIPS_CLASSA, "MyToolTip", lWinStyle, CW_USEDEFAULT, CW_USEDEFAULT, _
CW_USEDEFAULT, CW_USEDEFAULT, 0&, 0&, GetModuleHandle(vbNullString), 0&)
' Setup our tooltip info structure.
With ti
.uFlags = TTF_SUBCLASS Or TTF_IDISHWND
If bCentered Then .uFlags = .uFlags Or TTF_CENTERTIP
' Set the hwnd prop to our parent control's hwnd.
.hwnd = ParentHwnd
.uId = ParentHwnd
.hinst = GetModuleHandle(vbNullString)
.lpszText = TipText
.cbSize = LenB(ti)
End With
' Debug.Print SendMessage(hwndTT, TTM_SETMAXTIPWIDTH, 0&, 100)
SendMessage hwndTT, TTM_ADDTOOLA, 0&, ti
SendMessage hwndTT, TTM_UPDATETIPTEXTA, 0&, ti
' Colors.
If lForeColor <> -1 Then SendMessage hwndTT, TTM_SETTIPTEXTCOLOR, lForeColor, 0&
If lBackColor <> -1 Then
Call TranslateColor(lBackColor, 0, lRealColor)
SendMessage hwndTT, TTM_SETTIPBKCOLOR, lRealColor, 0&
End If
' Title or icon.
If uIcon <> TTNoIcon Or sTitle <> vbNullString Then SendMessage hwndTT, TTM_SETTITLE, CLng(uIcon), ByVal sTitle
SendMessageLong hwndTT, TTM_SETDELAYTIME, TTDT_AUTOPOP, lVisibleTime
SendMessageLong hwndTT, TTM_SETDELAYTIME, TTDT_INITIAL, lDelayTime
End Sub
Public Sub DestroyToolTip()
' It's not a bad idea to put this in the Form_Unload event just to make sure.
Const TOOLTIPS_CLASSA = "tooltips_class32"
Call DestroyWindow(FindWindow(TOOLTIPS_CLASSA, "MyToolTip"))
End Sub
Private Sub FormatTooltipText(TipText As String, lLen As Long)
Dim s As String
Dim i As Long
'
' Make sure we need to do anything.
If lLen = 0 Then Exit Sub
If lLen < 40 Then lLen = 40
If Len(TipText) <= lLen Then Exit Sub
'
Do
i = InStrRev(TipText, " ", lLen + 1)
If i = 0 Then
s = s & Left$(TipText, lLen) & vbCrLf ' Build "s" and trim from TipText.
TipText = Mid$(TipText, lLen + 1)
Else
s = s & Left$(TipText, i - 1) & vbCrLf ' Build "s" and trim from TipText.
TipText = Mid$(TipText, i + 1)
End If
If Len(TipText) <= lLen Then
TipText = s & TipText ' Place "s" back into TipText and get out.
Exit Sub
End If
Loop
End Sub