[Class] GuiControlTips - Tooltips for GUI controls

Post your working scripts, libraries and tools
just me
Posts: 6984
Joined: 02 Oct 2013, 08:51
Location: Germany

[Class] GuiControlTips - Tooltips for GUI controls

05 Mar 2014, 05:54

Moved from the old forum -> /board/topic/83090-class-guicontroltips-tooltips-for-gui-controls/

Update on 2014-03-06:
  • Added SetDelayTimes()
As the name implies, this class was created to provide easy methods to assign common ToolTips to GUI controls.
How to use wrote:To assign ToolTips to GUI controls you have to create a new instance of GuiControlTips per GUI with
MyToolTipObject := New GuiControlTips(HGUI)
passing the HWND of the GUI.

After this you may assign ToolTips to your GUI controls by calling
MyToolTipObject.Attach(HCTRL, "ToolTip text")
passing the HWND of the control and the ToolTip's text.
Pass True/1 for the optional third parameter if you want the ToolTip to be shown centered below the control.

To remove a ToolTip call
MyToolTipObject.Detach(HCTRL)
passing the HWND of the control.

To update the ToolTip's text call
MyToolTipObject.Update(HCTRL, "New text!")
passing the HWND of the control and the new text.

To deactivate the ToolTips call
MyToolTipObject.Suspend(True),
to activate them again afterwards call
MyToolTipObject.Suspend(False).
To adjust the ToolTips delay times call
MyToolTipObject.SetDelayTimesd(),
specifying the delay times in milliseconds.

That's all you can / have to do!

Code: Select all

; ======================================================================================================================
; Namespace:      GuiControlTips
; AHK version:    AHK 1.1.14.03
; Function:       Helper object to simply assign ToolTips for GUI controls
; Tested on:      Win 7 (x64)
; Change history: 
;                 1.1.00.00/2014-03-06/just me - Added SetDelayTimes()
;                 1.0.01.00/2012-07-29/just me
; ======================================================================================================================
; CLASS GuiControlTips
;
; The class provides four public methods to register (Attach), unregister (Detach), update (Update), and
; disable/enable (Suspend) common ToolTips for GUI controls.
;
; Usage:
; To assign ToolTips to GUI controls you have to create a new instance of GuiControlTips per GUI with
;     MyToolTipObject := New GuiControlTips(HGUI)
; passing the HWND of the GUI.
;
; After this you may assign ToolTips to your GUI controls by calling
;     MyToolTipObject.Attach(HCTRL, "ToolTip text")
; passing the HWND of the control and the ToolTip's text. Pass True/1 for the optional third parameter if you
; want the ToolTip to be shown centered below the control.
;
; To remove a ToolTip call
;     MyToolTipObject.Detach(HCTRL)
; passing the HWND of the control.
;
; To update the ToolTip's text call
;     MyToolTipObject.Update(HCTRL, "New text!")
; passing the HWND of the control and the new text.
;
; To deactivate the ToolTips call
;     MyToolTipObject.Suspend(True),
; to activate them again afterwards call
;     MyToolTipObject.Suspend(False).
;
; To adjust the ToolTips delay times call
;     MyToolTipObject.SetDelayTimesd(),
; specifying the delay times in milliseconds.
;
; That's all you can / have to do!
; ======================================================================================================================
Class GuiControlTips {
   ; ===================================================================================================================
   ; INSTANCE variables
   ; ===================================================================================================================
   HTIP := 0
   HGUI := 0
   CTRL := {}
   ; ===================================================================================================================
   ; CONSTRUCTOR           __New()
   ; ===================================================================================================================
   __New(HGUI) {
      Static CLASS_TOOLTIP      := "tooltips_class32"
      Static CW_USEDEFAULT      := 0x80000000
      Static TTM_SETMAXTIPWIDTH := 0x0418
      Static TTM_SETMARGIN      := 0x041A
      Static WS_STYLES          := 0x80000002 ; WS_POPUP | TTS_NOPREFIX
      ; Create a Tooltip control ...
      HTIP := DllCall("User32.dll\CreateWindowEx", "UInt", WS_EX_TOPMOST, "Str", CLASS_TOOLTIP, "Ptr", 0
                    , "UInt", WS_STYLES
                    , "Int", CW_USEDEFAULT, "Int", CW_USEDEFAULT, "Int", CW_USEDEFAULT, "Int", CW_USEDEFAULT
                    , "Ptr", HGUI, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr")
      If ((ErrorLevel) || !(HTIP))
         Return False
      ; ... prepare it to display multiple lines if required
      DllCall("User32.dll\SendMessage", "Ptr", HTIP, "Int", TTM_SETMAXTIPWIDTH, "Ptr", 0, "Ptr", 0)
      ; ... set the instance variables
      This.HTIP := HTIP
      This.HGUI := HGUI
      If (DllCall("Kernel32.dll\GetVersion", "UInt") & 0xFF) < 6 ; to avoid some XP issues ...
         This.Attach(HGUI, "") ; ... register the GUI with an empty tiptext
   }
   ; ===================================================================================================================
   ; DESTRUCTOR            __Delete()
   ; ===================================================================================================================
   __Delete() {
      If (This.HTIP) {
         DllCall("User32.dll\DestroyWindow", "Ptr", This.HTIP)
      }
   }
   ; ===================================================================================================================
   ; PRIVATE METHOD        SetToolInfo - Create and fill a TOOLINFO structure
   ; ===================================================================================================================
   SetToolInfo(ByRef TOOLINFO, HCTRL, TipTextAddr, CenterTip = 0) {
      Static TTF_IDISHWND  := 0x0001
      Static TTF_CENTERTIP := 0x0002
      Static TTF_SUBCLASS  := 0x0010
      Static OffsetSize  := 0
      Static OffsetFlags := 4
      Static OffsetHwnd  := 8
      Static OffsetID    := OffsetHwnd + A_PtrSize
      Static OffsetRect  := OffsetID + A_PtrSize
      Static OffsetInst  := OffsetRect + 16
      Static OffsetText  := OffsetInst + A_PtrSize
      Static StructSize  := (4 * 6) + (A_PtrSize * 6)
      Flags := TTF_IDISHWND | TTF_SUBCLASS
      If (CenterTip)
         Flags |= TTF_CENTERTIP
      VarSetCapacity(TOOLINFO, StructSize, 0)
      NumPut(StructSize, TOOLINFO, OffsetSize, "UInt")
      NumPut(Flags, TOOLINFO, OffsetFlags, "UInt")
      NumPut(This.HGUI, TOOLINFO, OffsetHwnd, "Ptr")
      NumPut(HCTRL, TOOLINFO, OffsetID, "Ptr")
      NumPut(TipTextAddr, TOOLINFO, OffsetText, "Ptr")
      Return True
   }
   ; ===================================================================================================================
   ; PUBLIC METHOD         Attach         -  Assign a ToolTip to a certain control
   ; Parameters:           HWND           -  Control's HWND
   ;                       TipText        -  ToolTip's text
   ;                       Optional:      ------------------------------------------------------------------------------
   ;                       CenterTip      -  Centers the tooltip window below the control
   ;                                         Values:  True/False
   ;                                         Default: False
   ; Return values:        On success: True
   ;                       On failure: False
   ; ===================================================================================================================
   Attach(HCTRL, TipText, CenterTip = False) {
      Static TTM_ADDTOOL  := A_IsUnicode ? 0x0432 : 0x0404 ; TTM_ADDTOOLW : TTM_ADDTOOLA
      If !(This.HTIP) {
         Return False
      }
      If This.CTRL.HasKey(HCTRL)
         Return False
      TOOLINFO := ""
      This.SetToolInfo(TOOLINFO, HCTRL, &TipText, CenterTip)
      If DllCall("User32.dll\SendMessage", "Ptr", This.HTIP, "Int", TTM_ADDTOOL, "Ptr", 0, "Ptr", &TOOLINFO) {
         This.CTRL[HCTRL] := 1
         Return True
      } Else {
        Return False
      }
   }
   ; ===================================================================================================================
   ; PUBLIC METHOD         Detach         -  Remove the ToolTip for a certain control
   ; Parameters:           HWND           -  Control's HWND
   ; Return values:        On success: True
   ;                       On failure: False
   ; ===================================================================================================================
   Detach(HCTRL) {
      Static TTM_DELTOOL  := A_IsUnicode ? 0x0433 : 0x0405 ; TTM_DELTOOLW : TTM_DELTOOLA
      If !This.CTRL.HasKey(HCTRL)
         Return False
      TOOLINFO := ""
      This.SetToolInfo(TOOLINFO, HCTRL, 0)
      DllCall("User32.dll\SendMessage", "Ptr", This.HTIP, "Int", TTM_DELTOOL, "Ptr", 0, "Ptr", &TOOLINFO)
      This.CTRL.Remove(HCTRL, "")
      Return True
   }
   ; ===================================================================================================================
   ; PUBLIC METHOD         Update         -  Update the ToolTip's text for a certain control
   ; Parameters:           HWND           -  Control's HWND
   ;                       TipText        -  New text                                                      
   ; Return values:        On success: True
   ;                       On failure: False
   ; ===================================================================================================================
   Update(HCTRL, TipText) {
      Static TTM_UPDATETIPTEXT  := A_IsUnicode ? 0x0439 : 0x040C ; TTM_UPDATETIPTEXTW : TTM_UPDATETIPTEXTA
      If !This.CTRL.HasKey(HCTRL)
         Return False
      TOOLINFO := ""
      This.SetToolInfo(TOOLINFO, HCTRL, &TipText)
      DllCall("SendMessage", "Ptr", This.HTIP, "Int", TTM_UPDATETIPTEXT, "Ptr", 0, "Ptr", &TOOLINFO)
      Return True
   }
   ; ===================================================================================================================
   ; PUBLIC METHOD         Suspend        -  Disable/enable the ToolTip control (don't show / show ToolTips)
   ; Parameters:           Mode           -  True/False (1/0)
   ;                                         Default: True/1
   ; Return values:        On success: True
   ;                       On failure: False
   ; Remarks:              ToolTips are enabled automatically on creation.
   ; ===================================================================================================================
   Suspend(Mode = True) {
      Static TTM_ACTIVATE := 0x0401
      If !(This.HTIP)
         Return False
      DllCall("SendMessage", "Ptr", This.HTIP, "Int", TTM_ACTIVATE, "Ptr", !Mode, "Ptr", 0)
      Return True
   }
   ; ===================================================================================================================
   ; PUBLIC METHOD         SetDelayTimes  -  Set the initial, pop-up, and reshow durations for a tooltip control.
   ; Parameters:           Init           -  Amount of time, in milliseconds, a pointer must remain stationary within
   ;                                         a tool's bounding rectangle before the tooltip window appears.
   ;                                         Default: -1 (system default time)
   ;                       PopUp          -  Amount of time, in milliseconds, a tooltip window remains visible if the
   ;                                         pointer is stationary within a tool's bounding rectangle.
   ;                                         Default: -1 (system default time)
   ;                       ReShow         -  Amount of time, in milliseconds, it takes for subsequent tooltip windows
   ;                                         to appear as the pointer moves from one tool to another.
   ;                                         Default: -1 (system default time)
   ; Return values:        On success: True
   ;                       On failure: False
   ; Remarks:              Times are set per ToolTip control and applied to all added tools.
   ; ===================================================================================================================
   SetDelayTimes(Init = -1, PopUp = -1, ReShow = -1) {
      Static TTM_SETDELAYTIME   := 0x0403
      Static TTDT_RESHOW   := 1
      Static TTDT_AUTOPOP  := 2
      Static TTDT_INITIAL  := 3
      DllCall("SendMessage", "Ptr", This.HTIP, "Int", TTM_SETDELAYTIME, "Ptr", TTDT_INITIAL, "Ptr", Init)
      DllCall("SendMessage", "Ptr", This.HTIP, "Int", TTM_SETDELAYTIME, "Ptr", TTDT_AUTOPOP, "Ptr", PopUp)
      DllCall("SendMessage", "Ptr", This.HTIP, "Int", TTM_SETDELAYTIME, "Ptr", TTDT_RESHOW , "Ptr", ReShow)
   }
}

Code: Select all

#NoEnv
#Include Class_GuiControlTips.ahk
TipTxt := {}
TipTxt[0] := "Button control's`r`nmultiline Tooltip!"
TipTxt[1] := "Button's alternate Tooltip, might be as long as you want and is displayed in only one single line!"
ButtonTip := 0
; Create the GUI
Gui, New, hwndHGUI
Gui, Margin, 20, 20
; Style 0x100 (SS_NOTIFY) is needed if no gLabel is given
Gui, Add, Text, w400 h20 0x200 0x100 Border hwndHText, % " Some text here ..."
Gui, Add, Edit, w400 h200 hwndHEdit, Edit
Gui, Add, DDL, w400 h200 hwndHDDL, Choose 1||Choose 2|Cjoose 3|Choose 4|Choose 5
Gui, Add, Button, hwndHButton gChange w180, Tooltip will toggle on click!
Gui, Add, Button, vSuspend gSuspend x240 yp wp, Suspend On
; Create a ToolTip control
TT := New GuiControlTips(HGUI)
; Set initial delay to 1 second (1000 ms) and the pop-up duration to 2 seconds
TT.SetDelayTimes(1000, 2000, -1)
; Attach the controls
TT.Attach(HText, "Text control's centered Tooltip!", True)
TT.Attach(HEdit, "Edit control's Tooltip!")
TT.Attach(HDDL, "DDL control's Tooltip!")
TT.Attach(HButton, TipTxt[ButtonTip])
; Now show the GUI
Gui, Show, , Control Tips
Return
; ----------------------------------------------------------------------------------------------------------------------
GuiClose:
ExitApp
; ----------------------------------------------------------------------------------------------------------------------
Change:
   ButtonTip ^= 1
   TT.Update(HButton, TipTxt[ButtonTip])
Return
; ----------------------------------------------------------------------------------------------------------------------
Suspend:
   GuiControlGet, Mode, , %A_GuiControl%
   TT.Suspend(Mode = "Suspend On" ? True : False)
   GuiControl, , %A_GuiControl%, % "Suspend " . (Mode = "Suspend On" ? "Off" : "On")
Return
Last edited by just me on 06 Mar 2014, 01:54, edited 1 time in total.
User avatar
fump2000
Posts: 313
Joined: 04 Oct 2013, 17:31

Re: [Class] GuiControlTips - Tooltips for GUI controls

05 Mar 2014, 18:36

Whatever you do, it will be good :) A very nice and functional script.

One question: can you affect the time until the tooltip appears?
just me
Posts: 6984
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: [Class] GuiControlTips - Tooltips for GUI controls

06 Mar 2014, 01:55

*Done!*
User avatar
Peace1
Posts: 41
Joined: 17 Mar 2015, 14:19
Location: 127.0.0.1

Re: [Class] GuiControlTips - Tooltips for GUI controls

06 Apr 2015, 16:36

Hi just me !

Sorry to bump this old topic,

Thank you for this great code like always ! I tried to apply your ToolTip to an ComboBox but the TT don't appear...

There is a trick for that ?

Regards.
just me
Posts: 6984
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: [Class] GuiControlTips - Tooltips for GUI controls

07 Apr 2015, 02:12

In case of a ComboBox, the tooltip will be shown if you hover over the button right of the edit control. If you want the tooltip to be shown for the edit too, you have to get the handle of the edit control (e.g. with GetComboBoxInfo) and assign an own tooltip to the control.
User avatar
Peace1
Posts: 41
Joined: 17 Mar 2015, 14:19
Location: 127.0.0.1

Re: [Class] GuiControlTips - Tooltips for GUI controls

07 Apr 2015, 04:02

just me wrote:In case of a ComboBox, the tooltip will be shown if you hover over the button right of the edit control. If you want the tooltip to be shown for the edit too, you have to get the handle of the edit control (e.g. with GetComboBoxInfo) and assign an own tooltip to the control.
Hi just me,

You was right for the ToolTip at button right of the edit control !

I followed your advice about GetComboBoxInfo and once again you were right :) All work perfectly now !

PS: Your skills are amazing dude !

Thank you a lot for the help and have a good day !

Best regards.
User avatar
kczx3
Posts: 1054
Joined: 06 Oct 2015, 21:39

Re: [Class] GuiControlTips - Tooltips for GUI controls

12 Dec 2016, 15:15

Is there a way to combine this and the ToolTipEx stuff for colors and fonts? Or would that require full sub-classing?
just me
Posts: 6984
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: [Class] GuiControlTips - Tooltips for GUI controls

13 Dec 2016, 03:16

Or would that require full sub-classing?
Since the script does not display the tooltips I see no other option.
User avatar
boiler
Posts: 4576
Joined: 21 Dec 2014, 02:44

Re: [Class] GuiControlTips - Tooltips for GUI controls

07 Jan 2020, 11:07

Deserves a bump. I like its ease of use by just identifying the control's HWND as opposed to finding a control's ClassNN which can change as you modify your GUI. This is "set it and forget it." Thanks for sharing, @just me.

Return to “Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 140 guests