GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

Post your working scripts, libraries and tools.
Spitzi
Posts: 315
Joined: 24 Feb 2022, 03:45

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

09 Aug 2023, 07:40

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
Spitzi
Posts: 315
Joined: 24 Feb 2022, 03:45

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

10 Aug 2023, 08:12

Thank you!!!!!! Very kind.
Spitzi
Posts: 315
Joined: 24 Feb 2022, 03:45

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

23 Aug 2023, 02:46

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?
just me
Posts: 9576
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

23 Aug 2023, 03:06

Hi @Spitzi, the script does'nt have any influence on if or when the tooltips are displayed.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

23 Aug 2023, 04:07

Spitzi wrote:
23 Aug 2023, 02:46
Is it possible to show the tooltip on a disabled button?
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
Spitzi
Posts: 315
Joined: 24 Feb 2022, 03:45

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

23 Aug 2023, 08:36

@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.

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)
      }
   }
}
; ======================================================================================================================
It works nicely! Thanks again.
Krd
Posts: 405
Joined: 10 Mar 2020, 02:46

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

24 Aug 2023, 03:21

Is it possible to further expand the tool tip timeout beyond 30 seconds which seems to be the limit?
just me
Posts: 9576
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

24 Aug 2023, 04:41

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?
Krd
Posts: 405
Joined: 10 Mar 2020, 02:46

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

24 Aug 2023, 08:59

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. :D
Spitzi
Posts: 315
Joined: 24 Feb 2022, 03:45

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

25 Sep 2023, 04:56

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:

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"))
but the tooltip is not shown. Any workaround?
just me
Posts: 9576
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

25 Sep 2023, 05:11

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.
Spitzi
Posts: 315
Joined: 24 Feb 2022, 03:45

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

25 Sep 2023, 16:03

@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
Spitzi
Posts: 315
Joined: 24 Feb 2022, 03:45

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

23 May 2024, 16:31

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
just me
Posts: 9576
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

24 May 2024, 02:48

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.
Spitzi
Posts: 315
Joined: 24 Feb 2022, 03:45

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

26 May 2024, 12:14

@just me So the offset to the position cannot be changed?
just me
Posts: 9576
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GuiCtrlTips - Add tooltips to your Gui.Controls (2023-05-28)

27 May 2024, 02:47

@Spitzi, not that I know of.

Return to “Scripts and Functions (v2)”

Who is online

Users browsing this forum: No registered users and 77 guests