Code: Select all
/*
Creates personalized tooltips. Allows modification of text, title, icon and font.
Remarks:
This class only works for Windows Vista and newer.
See the example at the end of the class.
*/
Class _ToolTip ; WIN_V+
{
; ===================================================================================================================
; INSTANCE VARIABLES
; ===================================================================================================================
hWnd := 0 ; ID of ToolTip window
TOOLINFO := "" ; TOOLINFO Struct
pTOOLINFO := 0 ; Pointer to TOOLINFO struct
X := 0 ; X coordinate. This variable is updated on use of the Show function when X isn't specified.
Y := 0 ; Y coordinate. This variable is updated on use of the Show function when Y isn't specified.
W := 0 ; ToolTip width. This variable is updated on use of the Show function when X isn't specified.
H := 0 ; ToolTip height. This variable is updated on use of the Show function when Y isn't specified.
; ===================================================================================================================
; CONSTRUCTOR
; ===================================================================================================================
/*
Parameters:
Title: Title to display for this ToolTip. If this parameter is an empty string, is not displayed.
Text : Text or message to display for this ToolTip. If you assign an empty string to it, it cannot be displayed.
Icon : A value identifying the icon to be displayed. This parameter can be an icon ID. If this value is 0, the icon is not displayed.
1 / 4 = Small/large Info icon.
2 / 5 = Small/large Warning icon.
3 / 6 = Small/large Error icon.
*/
__New(Title := "", Text := "", Icon := 0)
{
; https://msdn.microsoft.com/en-us/library/windows/desktop/ms632680(v=vs.85).aspx
This.hWnd := DllCall("User32.dll\CreateWindowExW", "UInt", 0x00000008 ;dwExStyle --> WS_EX_TOPMOST
, "Str" , "tooltips_class32" ;dwExStyle --> (https://msdn.microsoft.com/en-us/library/windows/desktop/bb760250(v=vs.85).aspx)
, "Ptr" , 0 ;lpWindowName --> NULL
, "UInt", 0x80000003 ;dwStyle --> WS_POPUP
, "Int" , 0x80000000 ;x --> CW_USEDEFAULT
, "Int" , 0x80000000 ;y --> CW_USEDEFAULT
, "Int" , 0x80000000 ;nWidth --> CW_USEDEFAULT
, "Int" , 0x80000000 ;nHeight --> CW_USEDEFAULT
, "Ptr" , 0 ;hWndParent --> NULL (ignored)
, "Ptr" , 0 ;hMenu --> NULL
, "Ptr" , 0 ;hInstance --> NULL
, "Ptr" , 0 ;lpParam --> NULL
, "Ptr") ;ReturnType
Text .= "" ; nos aseguramos que Text sea una cadena
ObjSetCapacity(this, "TOOLINFO", 6*4 + 6*A_PtrSize) ; we reserve memory for the TOOLINFO Struct
this.pTOOLINFO := ObjGetAddress(this, "TOOLINFO") ; we retrieve the TOOLINFO memory address
NumPut(6*4 + 6*A_PtrSize , this.pTOOLINFO , "UInt") ;cbSize --> size of TOOLINFO
NumPut(0x0080 | 0x0001 | 0x0020, this.pTOOLINFO + 4 , "UInt") ;uFlags --> options
NumPut(This.hWnd , this.pTOOLINFO + 2*4 , "Ptr") ;hwnd --> ToolTip window ID
NumPut(This.hWnd , this.pTOOLINFO + 2*4 + A_PtrSize , "Ptr") ;uId --> ToolTip window owner's ID
NumPut(&Text , this.pTOOLINFO + 24 + 3*A_PtrSize) ;lpszText --> memory address of a string specifying the text to be displayed.
; https://msdn.microsoft.com/en-us/library/windows/desktop/bb760338(v=vs.85).aspx
DllCall("User32.dll\SendMessageW", "Ptr" , This.hWnd ;Window handle
, "UInt", 0x0432 ;TTM_ADDTOOLW
, "Ptr" , 0 ;wParam (Must be zero)
, "UPtr", this.pTOOLINFO) ;lParam (Pointer to a TOOLINFO structure)
; https://msdn.microsoft.com/en-us/library/windows/desktop/bb760408(v=vs.85).aspx
DllCall("User32.dll\SendMessageW", "Ptr" , This.hWnd ;Window handle
, "UInt", 0x0418 ;TTM_SETMAXTIPWIDTH
, "Ptr" , 0 ;wParam (Must be zero)
, "Int" , 0) ;lParam (Maximum tooltip window width, or 0 to allow any width)
This.SetTitle(Title, Icon) ; we set the title
}
; ===================================================================================================================
; DESTRUCTOR
; ===================================================================================================================
__Delete()
{
Local hFont
If (hFont := DllCall("User32.dll\SendMessageW", "Ptr", This.hWnd, "UInt", 0x0031, "Ptr", 0, "Ptr", 0, "Ptr")) ; we check to see if the user changed the default font for the tooltip.
DllCall("Gdi32.dll\DeleteObject", "Ptr", hFont) ; if this is true, we should destroy it.
DllCall("User32.dll\DestroyWindow", "Ptr", This.hWnd) ; we destroy the tooltip window.
} ;https://msdn.microsoft.com/en-us/library/windows/desktop/ms632682(v=vs.85).aspx
; ===================================================================================================================
; PUBLIC METHODS
; ===================================================================================================================
/*
Shows, hides, changes the text and/or position of this Tooltip.
Parameters:
Text : The new text to be dislayed. If this is an empty string the Tooltip is hidden. Text is not modified if there is no change.
X / Y: The new coordinates. If an empty string is used, the cursor coordinates are utilized, and are self-adjusting so that the ToolTip will always be visible on the screen.
*/
Show(Text, X := "", Y := "")
{
Local Pos, X2, Y2, VW
If (Text == "") ; if the user specifies no text, we hide the ToolTip
This.Hide()
Else
{
If (!(This.Text == Text)) ; we only change the text if the new text is different; this prevents bothersome blinking if the text is long.
This.Text := Text
If (X == "" || Y == "") ; if a coordinate is not specified, we use the cursor coordinates, adapting them so that the ToolTip will display correctly on the screen.
{
Pos := This.GetPos() ; we get the ToolTip's position dimensions.
CoordMode("Mouse", "Screen") ; we make sure that MouseGetPos is retrieving coordinates relative to the desktop (full-screen) and not to some other window.
MouseGetPos(X2, Y2) ; we get the cursor's present coordinates.
If (X == "")
{
X := X2 + 10
This.X := X := X + (This.W:=Pos.W) > (VW:=SysGet(78)) ? X - (X + Pos.W - VW) : X
}
If (Y == "")
{
Y := Y2 + 10
This.Y := Y := Y + (This.H:=Pos.H) > SysGet(79) ? Y - Pos.H - 10 : Y
}
}
This.Move(X, Y) ; we reposition the ToolTip per the new coordinates.
If (!This.Visible) ; we show the ToolTip if it isn't visible
This.Visible := TRUE
}
}
/*
Hides this ToolTip
*/
Hide()
{
DllCall("User32.dll\SendMessageW", "Ptr", This.hWnd, "UInt", 0x0411, "Int", FALSE, "UPtr", this.pTOOLINFO)
} ; https://msdn.microsoft.com/en-us/library/windows/desktop/bb760421(v=vs.85).aspx
/*
Gets this ToolTip's coordinates and dimensions.
Return:
Returns an object with the keys X, Y, W and H.
*/
GetPos()
{
Local X, Y
WinGetPos(X, Y,,, "ahk_id" . This.hWnd) ; we get the ToolTip's coordinates.
Local Size := DllCall("User32.dll\SendMessageW", "Ptr", This.hWnd, "UInt", 0x041E, "Ptr", 0, "UPtr", this.pTOOLINFO, "UInt") ; we get the ToolTip's dimensions.
Return {X: X, Y: Y, W: Size & 0xFFFF, H: Size >> 16}
} ; https://msdn.microsoft.com/en-us/library/windows/desktop/bb760387(v=vs.85).aspx
/*
Move this ToolTip to the specified coordinates.
Parameters:
X / Y: New X and Y coordinates.
*/
Move(X, Y)
{
DllCall("User32.dll\SendMessageW", "Ptr", This.hWnd, "UInt", 0x0412, "Ptr", 0, "UInt", (X & 0xFFFF) | (Y << 16))
} ; https://msdn.microsoft.com/en-us/library/windows/desktop/bb760422(v=vs.85).aspx
/*
Forces a Redraw of this ToolTip.
*/
Update()
{
DllCall("User32.dll\SendMessageW", "Ptr", This.hWnd, "UInt", 0x0412, "Ptr", 0, "UInt", 0)
} ; https://msdn.microsoft.com/en-us/library/windows/desktop/bb760425(v=vs.85).aspx
/*
Changes the title and icon displayed for this ToolTip.
Parameters:
NewTitle: The new title. If this is an empty string the title is removed.
Icon : A value identifying the icon to be displayed. This parameter can be an icon ID. If this value is 0, the icon is not displayed.
1 / 4 = Small/large Info icon.
2 / 5 = Small/large Warning icon.
3 / 6 = Small/large Error icon.
*/
SetTitle(NewTitle, Icon := 0)
{
NewTitle .= "" ; we make sure that NewTitle is a string
DllCall("User32.dll\SendMessageW", "Ptr", This.hWnd, "UInt", 0x0421, "Ptr", Icon, "UPtr", NewTitle == "" ? 0 : &NewTitle)
} ; https://msdn.microsoft.com/en-us/library/windows/desktop/bb760414(v=vs.85).aspx
/*
Changes the text font for this ToolTip.
Parameters:
Options: Font options. You should specify a string with one or more of the following keywords:
sN = Text size. Default is 9.
qN = Font quality. Default is 5 (ClearType).
wN = Text weight. 400 is normal, 600 is semi-bold, 700 is bold. Default is 400.
Italic / Underline / Strike / Bold = Font style. Italic / Underline / Strikethrough / Bold
FontName: Font Name. If this is an empty string, the present font is removed and replaced with the original font.
Note:
If the font weight is specified (wN), "Bold" has no effect, since "Bold" makes wN be 700 (i.e. bold).
*/
SetFont(Options := "", FontName := "Segoe UI")
{
Local hFont
If (hFont := DllCall("User32.dll\SendMessageW", "Ptr", This.hWnd, "UInt", 0x0031, "Ptr", 0, "Ptr", 0, "Ptr")) ; we remove the previously assigned font, if any.
DllCall("Gdi32.dll\DeleteObject", "Ptr", hFont)
If (FontName == "") ; if FontName is an empty string, we restore the original font.
Return DllCall("User32.dll\SendMessageW", "Ptr", This.hWnd, "UInt", 0x0030, "Ptr", 0, "Int", TRUE) ; WM_SETFONT = 0x0030
Local hDC := DllCall("Gdi32.dll\CreateDCW", "Str", "DISPLAY", "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr")
, R := DllCall("Gdi32.dll\GetDeviceCaps", "Ptr", hDC, "Int", 90)
DllCall("Gdi32.dll\DeleteDC", "Ptr", hDC)
Local t
, Size := RegExMatch(Options, "i)s([\-\d\.]+)(p*)", t) ? t[1] : 10
, Height := Round((Abs(Size) * R) / 72) * -1
, Quality := RegExMatch(Options, "i)q([\-\d\.]+)(p*)", t) ? t[1] : 5
, Weight := RegExMatch(Options, "i)w([\-\d\.]+)(p*)", t) ? t[1] : (InStr(Options, "Bold") ? 700 : 400)
, Italic := !!InStr(Options, "Italic")
, Underline := !!InStr(Options, "Underline")
, Strike := !!InStr(Options, "Strike")
DllCall("User32.dll\SendMessageW", "Ptr", This.hWnd, "UInt", 0x0030
, "Ptr" , DllCall("Gdi32.dll\CreateFontW", "Int", Height, "Int", 0, "Int", 0, "Int", 0, "Int", Weight, "UInt", Italic, "UInt", Underline, "UInt", Strike, "UInt", 1, "UInt", 4, "UInt", 0, "UInt", Quality, "UInt", 0, "UPtr", &FontName, "Ptr")
, "Int" , TRUE)
} ;https://msdn.microsoft.com/en-us/library/windows/desktop/ms632642(v=vs.85).aspx
; ===================================================================================================================
; PROPERTIES
; ===================================================================================================================
/*
Gets or sets the text shown for this ToolTip.
*/
Text[]
{
Get
{
Local Buffer
VarSetCapacity(Buffer, 5024 * 2) ; we reserve storage of 5024*2 bytes
NumPut(&Buffer, this.pTOOLINFO + 24 + 3*A_PtrSize) ; we NumPut the memory address of the ToolTip Struct's buffer, which will be used for SendMessage::0x0438
DllCall("User32.dll\SendMessageW", "Ptr", This.hWnd, "UInt", 0x0438, "Ptr", 5024, "UPtr", this.pTOOLINFO) ; this message gets the ToolTip text and writes it to the buffer.
Return StrGet(&Buffer, "UTF-16") ; devolvemos la cadena
}
Set
{
Value .= "" ; we make sure that Value is a string with this 'Set'
NumPut(&Value, this.pTOOLINFO + 24 + 3*A_PtrSize) ; we NumPut the memory address of Value to the ToolTip Struct's buffer, which will be used for SendMessage::0x0439
DllCall("User32.dll\SendMessageW", "Ptr", This.hWnd, "UInt", 0x0439, "Int", 0, "UPtr", this.pTOOLINFO) ; we update the ToolTip text, copying the content of Value.
}
}
/*
Determines or establishes whether this ToolTip is visible (Get/Set).
*/
Visible[]
{
Get
{
Return DllCall("User32.dll\IsWindowVisible", "Ptr", This.hWnd)
}
Set
{
DllCall("User32.dll\SendMessageW", "Ptr", This.hWnd, "UInt", 0x0411, "Int", !!Value, "UPtr", this.pTOOLINFO)
}
}
}
; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; ::: EXAMPLE
; :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
/*
TT := New _ToolTip() ; we create the ToolTip window TT
TT.SetTitle("ToolTip 1", 1) ; we set the title and icon
TT.SetFont("s12 Italic Underline", "Courier New") ; we set the font, font type and size
TT2 := New _ToolTip("ToolTip 2",, 2) ; we create a second ToolTip window TT2
Loop ; infinite loop - press ESCAPE key to stop the script.
{
TT.Show("My ToolTip Text") ; shows the ToolTip window TT
TT2.Show("ToolTip 1: x" . TT.X . " y" . TT.Y . " w" . TT.W . " h" . TT.H, 10, 10) ; shows the ToolTip window TT2
Sleep(50) ; we wait 50 ms
}
Return
~Esc::ExitApp ; ESCAPE to exit the script.
*/