Search code examples
windowsdelphitooltipvcl

How can I update the tooltip text of a Windows trackbar control?


The TTrackBar component in Delphi is a wrapper around the standard Windows trackbar control. When the PositionToolTip property is not None a tooltip is displayed while dragging the thumb of the trackbar control.

By default, that tooltip displays a plain integer number between Min and Max of the control. Is there a way to manually update that position tooltip text so that the number value can be formatted like e.g., "80 %" in case of a volume control?

When looking at the Windows trackbar control documentation there seems to be a TBM_GETTOOLTIPS message which allows to retrieve a handle for the tooltip. Not sure how to update the tooltip text using that handle, though.


Solution

  • I believe the best approach is to use the TTN_NEEDTEXT notification and fill the NMTTDISPINFO structure:

    unit Unit1;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, CommCtrl;
    
    type
      TTrackBar = class(Vcl.ComCtrls.TTrackBar)
        procedure WndProc(var Message: TMessage); override;
      end;
    
      TForm1 = class(TForm)
        TrackBar1: TTrackBar;
      private
      public
      end;
    
    implementation
    
    {$R *.dfm}
    
    procedure TTrackBar.WndProc(var Message: TMessage);
    begin
      inherited;
      case Message.Msg of
        WM_NOTIFY:
          if PNMHdr(Message.LParam).code = TTN_NEEDTEXT then
          begin
            var S := Round(100 * Position / Max).ToString + '%';
            FillChar(
              PNMTTDispInfo(Message.LParam).szText,
              Length(PNMTTDispInfo(Message.LParam).szText) * SizeOf(Char),
              0);
            if S.Length <= Length(PNMTTDispInfo(Message.LParam).szText) then
              CopyMemory(
                @PNMTTDispInfo(Message.LParam).szText,
                Pointer(S),
                S.Length * SizeOf(Char)
              );
          end;
      end;
    end;
    
    end.
    

    Screenshot of the tooltip

    (Most often, you don't use a space before a percent sign in English. In many other languages, however, there should be a space. For instance, in Swedish, you always have a non-breaking space before the percent sign. So 50% in English, but 50 % in Swedish.)