Search code examples
delphitooltipttabsheet

TTabSheet hints in Delphi


I want a TPageControl and some TTabSheets, with 'per tabsheet' tooltip hints visible as I hover over each tab in turn.

Is there any way of getting this effect in Delphi 2009?


Solution

  • Just hook the Page Control's Mouse Move event and use the TabAtPos property to determine which tab the mouse is hovering over. Then assign that tab's Hint to the Page Control's hint property.

    procedure TForm.PageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: integer);
    var
      tabindex: integer;
    begin
      tabindex := PageControl.IndexOfTabAt(X, Y);
      if (tabindex >= 0) and (PageControl.Hint <> PageControl.Pages[tabindex].Hint) then
      begin
        Application.CancelHint;
        PageControl.Hint := PageControl.Pages[tabindex].Hint;
        PageControl.ShowHint := true;
      end;
    end;
    

    CancelHint/ShowHint will take care of updating the hint window when mouse moves directly from one tab to another.

    Improved but ugly version below also temporarily changes HintPause to 0 when mouse is moved directly from tab to tab so that the hint is redisplayed immediately. (The "ugly" part of the solution goes to the Application.ProcessMessages call which forces hint messages to be processed before HintPause is restored.)

    procedure TForm.PagesMouseMove(Sender: TObject; Shift: TShiftState; X, Y: integer);
    var
      hintPause: integer;
      tabindex: integer;
    begin
      tabindex := PageControl.IndexOfTabAt(X, Y);
      if (tabindex >= 0) and (PageControl.Hint <> PageControl.Pages[tabindex].Hint) then
      begin
        hintPause := Application.HintPause;
        try
          if PageControl.Hint <> '' then
            Application.HintPause := 0;
          Application.CancelHint;
          PageControl.Hint := PageControl.Pages[tabindex].Hint;
          PageControl.ShowHint := true;
          Application.ProcessMessages; // force hint to appear
        finally Application.HintPause := hintPause; end;
      end;
    end;
    

    To hide the hint on the main page body, assign the following method to the page control's OnMouseLeave event.

    procedure TForm.PageMouseLeave(Sender: TObject);
    begin
      PageControl.Hint := '';
      PageControl.ShowHint := false;
    end;