GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
Hi @just me
Do you plan to publish the code on GitHub or something, for use under an official library (e.g. MIT-License)? It would help me out, because my script uses your class in a lot of places, and I would like to make all my used libraries transparent to the user.
Greets Spitzi
Do you plan to publish the code on GitHub or something, for use under an official library (e.g. MIT-License)? It would help me out, because my script uses your class in a lot of places, and I would like to make all my used libraries transparent to the user.
Greets Spitzi
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
Thank you!!!!!! Very kind.
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
Hi @just me. I noticed that when a button is disabled, the tooltip is not shown. Is it possible to show the tooltip on a disabled button?
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
Hi @Spitzi, the script does'nt have any influence on if or when the tooltips are displayed.
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
Tried a workaround... seemingly works:
Code: Select all
#Requires AutoHotkey v2.0
#SingleInstance
MyGui := Gui()
Push1 := MyGui.AddButton("", "Disable / Enable Button 2")
Push2 := MyGui.AddButton("wp","Button 2")
Text1 := MyGui.AddText("xp yp wp hp BackGroundTrans +0x100")
Push1.OnEvent("Click", (*) => Push2.Enabled := !Push2.Enabled)
Push2.OnEvent("Click", (*) => MsgBox())
GuiCtrlSetTip(Push1, "Disable the other button")
GuiCtrlSetTip(Push2, "Show MsgBox")
GuiCtrlSetTip(Text1, "Show MsgBox (Disabled)")
MyGui.Show("w200 h200")
; Paste the function GuiCtrlSetTip() below
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
@just me and @SKAN: thanks for your reply.
I like your workaround, SKAN, thank you. I adapted it for for use with just me's class as follows.
It works nicely! Thanks again.
I like your workaround, SKAN, thank you. I adapted it for for use with just me's class as follows.
Code: Select all
#Requires AutoHotkey v2.0
#SingleInstance
MyGui := Gui()
MyGui.Tooltips := GuiCtrlTips(MyGui)
Push1 := MyGui.AddButton("", "Disable / Enable Button 2")
Push2 := MyGui.AddButton("wp","Button 2")
Text1 := MyGui.AddText("xp yp wp hp BackGroundTrans +0x100")
Push1.OnEvent("Click", (*) => Push2.Enabled := !Push2.Enabled)
Push2.OnEvent("Click", (*) => MsgBox())
MyGui.ToolTips.SetTip(Push1, "Disable the other button")
MyGui.ToolTips.SetTip(Push2, "Show MsgBox")
MyGui.ToolTips.SetTip(Text1, "Show MsgBox (Disabled)")
MyGui.Show("w200 h200")
; 28 May 2022 - from https://www.autohotkey.com/boards/viewtopic.php?f=83&t=116218
#Requires AutoHotkey v2.0
; ======================================================================================================================
; Release date: 2023-05-28
; ======================================================================================================================
; Add tooltips to your Gui controls.
; Tooltips are managed per Gui, so you first have to create a new instance of the class for the Gui, e.g.:
; MyGui := Gui()
; MyGui.Tips := GuiCtrlTips(MyGui)
; Then you can create your controls and add tooltips, e.g.:
; MyBtn := MyGui.AddButton(...)
; MyGui.Tips.SetTip(MyBtn, "My Tooltip!")
; You can activate, deactivate, or change the delay times for all tooltips at any time by calling the corresponding
; methods.
; To remove a tooltip from a single control pass an empty text, e.g.:
; MyGui.Tips.SetTip(MyBtn, "")
; Text and Picture controls require the SS_NOTIFY (+0x0100) style or a 'Click' event function.
; ----------------------------------------------------------------------------------------------------------------------
; Tooltip control: https://learn.microsoft.com/en-us/windows/win32/controls/tooltip-control-reference
; ======================================================================================================================
Class GuiCtrlTips {
Static TOOLINFO {
Get {
Static SizeOfTI := 24 + (A_PtrSize * 6)
Local TI := Buffer(SizeOfTI, 0)
NumPut("UInt", SizeOfTI, TI)
Return TI
}
}
; -------------------------------------------------------------------------------------------------------------------
Static ToolTipFont {
Get {
Static SizeOfLFW := 92 ; LOGFONTW structure
Static SizeOfNCM := 44 + (SizeOfLFW * 5) ; NONCLIENTMETRICSW structure
Static OffStatusFont := 40 + (SizeOfLFW * 3) ; lfStatusFont
Static LOGFONTW := 0
If !IsObject(LOGFONTW) { ; first call
Local NCM := Buffer(SizeOfNCM, 0)
NumPut("UInt", SizeOfNCM, NCM)
DllCall("SystemParametersInfoW", "UInt", 0x0029, "UInt", 0, "Ptr", NCM.Ptr, "UInt", 0) ; SPI_GETNONCLIENTMETRICS
LOGFONTW := Buffer(SizeOfLFW, 0)
DllCall("RtlMoveMemory", "Ptr", LOGFONTW.Ptr, "Ptr", NCM.Ptr + OffStatusFont, "Ptr", SizeOfLFW)
}
Local LF := Buffer(SizeOfLFW, 0)
DllCall("RtlMoveMemory", "Ptr", LF.Ptr, "Ptr", LOGFONTW.Ptr, "Ptr", SizeOfLFW)
Return LF
}
}
; -------------------------------------------------------------------------------------------------------------------
; https://learn.microsoft.com/en-us/windows/win32/controls/ttm-addtool
; https://learn.microsoft.com/en-us/windows/win32/controls/ttm-setmaxtipwidth
; https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tttoolinfow
__New(GuiObj, UseAhkStyle := True, UseComboEdit := True) {
Local Flags, HGUI, HTIP, TI
If !(GuiObj Is Gui)
Throw TypeError(A_ThisFunc . ": Expected a Gui object!", -1 "GuiObj")
HGUI := GuiObj.Hwnd
; Create the TOOLINFO structure
Flags := 0x11 ; TTF_SUBCLASS | TTF_IDISHWND
TI := GuiCtrlTips.TOOLINFO
NumPut("UInt", Flags, "UPtr", HGUI, "UPtr", HGUI, TI, 4) ; uFlags, hwnd, uID
; Create a tooltip control for this Gui
If !(HTIP := DllCall("CreateWindowEx", "UInt", 0, "Str", "tooltips_class32", "Ptr", 0, "UInt", 0x80000003
, "Int", 0x80000000, "Int", 0x80000000, "Int", 0x80000000, "Int", 0x80000000
, "Ptr", HGUI, "Ptr", 0, "Ptr", 0, "Ptr", 0, "UPtr"))
Throw Error(A_ThisFunc . ": Could not create a tooltip control", -1)
If (UseAhkStyle)
DllCall("Uxtheme.dll\SetWindowTheme", "Ptr", HTIP, "Ptr", 0, "Str", " ")
SendMessage(0x0418, 0, A_ScreenWidth, HTIP) ; TTM_SETMAXTIPWIDTH
; SendMessage(0x0432, 0, TI.Ptr, HTIP) ; TTM_ADDTOOLW <--- doesn't seem required any more
This.DefineProp("HTIP", {Get: (*) => HTIP})
This.DefineProp("HGUI", {Get: (*) => HGUI})
This.DefineProp("UAS", {Get: (*) => !!UseAhkStyle})
This.DefineProp("UCE", {Get: (*) => !!UseComboEdit})
This.Ctrls := Map()
}
; -------------------------------------------------------------------------------------------------------------------
__Delete() {
If This.HasProp("HTIP")
DllCall("DestroyWindow", "Ptr", This.HTIP)
}
; -------------------------------------------------------------------------------------------------------------------
; https://learn.microsoft.com/en-us/windows/win32/controls/ttm-activate
Activate() {
SendMessage(0x0401, True, 0, This.HTIP) ; TTM_ACTIVATE
Return True
}
; -------------------------------------------------------------------------------------------------------------------
; https://learn.microsoft.com/en-us/windows/win32/controls/ttm-activate
Deactivate() {
SendMessage(0x0401, False, 0, This.HTIP) ; TTM_ACTIVATE
Return True
}
; -------------------------------------------------------------------------------------------------------------------
; https://learn.microsoft.com/en-us/windows/win32/controls/ttm-settipbkcolor
SetBkColor(Color) {
If IsInteger(Color) {
Color := ((Color & 0x0000FF) << 16) | (Color & 0x00FF00) | ((Color & 0xFF0000) >> 16)
SendMessage(0x0413, Color, 0, This.HTIP)
}
}
; -------------------------------------------------------------------------------------------------------------------
; https://learn.microsoft.com/en-us/windows/win32/controls/ttm-setdelaytime
; Flag - one of the string keys defined in Flags
; MilliSecs - time in millisecons, pass -1 to reset to the default
SetDelayTime(Flag, MilliSecs) {
Static Flags := {AUTOMATIC: 0, AUTOPOP: 2, INITIAL: 3, RESHOW: 1}
If !Flags.HasProp(Flag) || !IsInteger(MilliSecs)
Return False
If (MilliSecs < -1)
MilliSecs := -1
SendMessage(0x0403, Flags.%Flag%, MilliSecs, This.HTIP)
Return True
}
; -------------------------------------------------------------------------------------------------------------------
; Any value passed in Bold and Italic will set the related font option
SetFont(FontSize?, FontName?, Bold?, Italic?) {
Static LOGPIXELSY := 0, PrevFont := 0
If (LOGPIXELSY = 0) { ; first call
Local HDC := DllCall("GetDC", "Ptr", 0, "UPtr")
LOGPIXELSY := DllCall("GetDeviceCaps", "Ptr", HDC, "Int", 90, "Int") ; LOGPIXELSY
DllCall("ReleaseDC", "Ptr", 0, "Ptr", HDC)
}
Local LOGFONT := GuiCtrlTips.ToolTipFont
If IsSet(FontSize) && IsNumber(FontSize)
NumPut("Int", -Round(FontSize * LOGPIXELSY / 72), LOGFONT)
If IsSet(Bold)
NumPut("Int", 700, LOGFONT, 16)
If IsSet(Italic)
NumPut("UChar", 1, LOGFONT, 20)
If IsSet(FontName)
StrPut(FontName, LOGFONT.Ptr + 28, 32)
Local HFONT := DllCall("CreateFontIndirectW", "Ptr", LOGFONT.Ptr, "UPtr")
SendMessage(0x0030, HFONT, 1, This.HTIP)
If PrevFont
DllCall("DeleteObject", "Ptr", PrevFont)
PrevFont := HFONT
}
; -------------------------------------------------------------------------------------------------------------------
; https://learn.microsoft.com/en-us/windows/win32/controls/ttm-setmargin
SetMargins(L := 0, T := 0, R := 0, B := 0) {
RC := Buffer(16, 0)
NumPut("Int", L, "Int", T, "Int", R, "Int", B, RC)
SendMessage(0x041A, 0, RC.Ptr, This.HTIP)
}
; -------------------------------------------------------------------------------------------------------------------
; https://learn.microsoft.com/en-us/windows/win32/controls/ttm-addtool
; https://learn.microsoft.com/en-us/windows/win32/controls/ttm-deltool
; https://learn.microsoft.com/en-us/windows/win32/controls/ttm-updatetiptext
SetTip(GuiCtrl, TipText, CenterTip := False) {
Local Flags, HCTL, TI
; Check the passed GuiCtrl
If !(GuiCtrl Is Gui.Control) || (GuiCtrl.Gui.Hwnd != This.HGUI)
Return False
If (GuiCtrl.Type = "ComboBox") && This.UCE ; use the Edit control of the Combobox
HCTL := DllCall("FindWindowExW", "Ptr", GuiCtrl.Hwnd, "Ptr", 0, "Ptr", 0, "Ptr", 0, "UPtr")
Else
HCTL := GuiCtrl.Hwnd
; Create the TOOLINFO structure
Flags := 0x11 | (CenterTip ? 0x02 : 0x00) ; TTF_SUBCLASS | TTF_IDISHWND [| TTF_CENTERTIP]
TI := GuiCtrlTips.TOOLINFO
NumPut("UInt", Flags, "UPtr", This.HGUI, "UPtr", HCTL, TI, 4) ; cbSize, uFlags, hwnd, uID
If (TipText = "") {
If This.Ctrls.Has(HCTL) {
SendMessage(0x0433, 0, TI.Ptr, This.HTIP) ; TTM_DELTOOLW
This.Ctrls.Delete(HCTL)
}
Return True
}
If !This.Ctrls.Has(HCTL) {
SendMessage(0x0432, 0, TI.Ptr, This.HTIP) ; TTM_ADDTOOLW
This.Ctrls[HCTL] := True
}
; Set / Update the tool's text.
NumPut("UPtr", StrPtr(TipText), TI, 24 + (A_PtrSize * 3)) ; lpszText
SendMessage(0x0439, 0, TI.Ptr, This.HTIP) ; TTM_UPDATETIPTEXTW
Return True
}
; -------------------------------------------------------------------------------------------------------------------
; https://learn.microsoft.com/en-us/windows/win32/controls/ttm-settiptextcolor
SetTxColor(Color) {
If IsInteger(Color) {
Color := ((Color & 0x0000FF) << 16) | (Color & 0x00FF00) | ((Color & 0xFF0000) >> 16)
SendMessage(0x0414, Color, 0, This.HTIP)
}
}
}
; ======================================================================================================================
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
Is it possible to further expand the tool tip timeout beyond 30 seconds which seems to be the limit?
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
I don't think so, because the times are stored as a WORD (16-bit) value -> TTM_SETDELAYTIME
BTW, why do you want to display a tooltip for more than 32 seconds?
BTW, why do you want to display a tooltip for more than 32 seconds?
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
Thanks for the replay.
Because I utilize your fantastic script in my main GUI, which comprises of numerous functions, some of these functions can be directly used from the main GUI.
Your script serves to provide instructions to the end user about what actions to take and what not to.
This approach saves me from needing to create an additional GUI solely for describing these functions.
Some descriptions might be longer, and occasionally, 32 seconds is not sufficient to fully comprehend them all.
But the trick is to think and work faster, which is even better.
Because I utilize your fantastic script in my main GUI, which comprises of numerous functions, some of these functions can be directly used from the main GUI.
Your script serves to provide instructions to the end user about what actions to take and what not to.
This approach saves me from needing to create an additional GUI solely for describing these functions.
Some descriptions might be longer, and occasionally, 32 seconds is not sufficient to fully comprehend them all.
But the trick is to think and work faster, which is even better.
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
Hi @just me.
Still using your GuiCtrlTips frequently, if not daily! Is it possible, to use the tooltips on a activeX control? I tried this:
but the tooltip is not shown. Any workaround?
Still using your GuiCtrlTips frequently, if not daily! Is it possible, to use the tooltips on a activeX control? I tried this:
Code: Select all
aXObj := aChatGui.add("ActiveX", "xs w" guiWidth " h50 vwbParticipants +0x0100", "Shell.Explorer") ; a webbrowser activeX for the participants, +0x0100 = SS_Notify
aChatGui.Tooltips.SetTip(aXObj, loc("Test"))
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
If aChatGui.Tooltips.SetTip() returns True it's the matter of the control to show the tip. If it doesn't, it does'nt. The only workaround I know is to watch the mouse cursor.
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
@just me, thank you.
It obviously doesn't...
My workaround was to use the tooltip function of the html-File that is loaded into the activeX/explorer.
Greets Spitzi
It obviously doesn't...
My workaround was to use the tooltip function of the html-File that is loaded into the activeX/explorer.
Greets Spitzi
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
Hi @just me.
Is it possible to change the offset where the tooltip appears? I would like it to appear 100pixels to the right of the mouse cursor. Is that possible?
Greets Simon
Is it possible to change the offset where the tooltip appears? I would like it to appear 100pixels to the right of the mouse cursor. Is that possible?
Greets Simon
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
Hi @Spitzi,
the class does not care about the tooltip's position.It's determined by the ToolTip("Text", X, Y, ...) function.
Edit: Sorry, wrong class!
It's automatically determined by the tooltip control.
the class does not care about the tooltip's position.
Edit: Sorry, wrong class!
It's automatically determined by the tooltip control.
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
@just me So the offset to the position cannot be changed?
Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)
@Spitzi, not that I know of.