I want to use a custom Hint window class for my entire application. I use Application.OnShowHint , parse THintInfo and return my own TMyHintWindow to HintInfo.HintWindowClass . This works well for all controls, but I only have a weird problem with the TVirtualStringTree Columns hint.
VT uses its own prompt window and its own structure for HintInfo.HintData . I am studying the code and know that it uses VTHintData . So far, so good. the problem is that when I return my own tooltip window class (derived from THintWindow ), it only displays the tooltip for a split second and disappears!
No problem with the hints returned for tree nodes. they use the same method / structure ( VTHintData ).
Here is a very simple MCVE:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, VirtualTrees, StdCtrls; type TForm1 = class(TForm) VirtualStringTree1: TVirtualStringTree; Memo1: TMemo; procedure FormCreate(Sender: TObject); private public procedure ApplicationShowHint(var HintStr: string; var CanShow: Boolean; var HintInfo: THintInfo); end; var Form1: TForm1; implementation {$R *.dfm} type TMyHintWindow = class(THintWindow) public { nothing special here for now } end; procedure TForm1.FormCreate(Sender: TObject); begin VirtualStringTree1.Hint := 'VT main hint'; VirtualStringTree1.ShowHint := True; Memo1.Hint := 'Memo hint'; Memo1.ShowHint := True; Application.OnShowHint := ApplicationShowHint; end; procedure TForm1.ApplicationShowHint(var HintStr: string; var CanShow: Boolean; var HintInfo: THintInfo); var VTHintData: TVTHintData; begin { VT uses it own hint window class } if HintInfo.HintWindowClass = TVirtualTreeHintWindow then begin { VT passes columns and nodes hints information in HintInfo.HintData } if HintInfo.HintData <> nil then begin VTHintData := PVTHintData(HintInfo.HintData)^; if VTHintData.Node <> nil then { node hint } begin { handle this case with DoGetNodeHint/DoGetNodeToolTip ... it works fine } end else begin { column hint } HintStr := VTHintData.DefaultHint; { got it! } end; end; end; Memo1.Lines.Add(HintStr); { prove I got the right hint } HintInfo.HintColor := clAqua; { use my own hint window class the hint from the VT columns is shown for a split second and hides! } HintInfo.HintWindowClass := TMyHintWindow; end; end.
the form:
object Form1: TForm1 Left = 399 Top = 256 Width = 720 Height = 211 Caption = 'Form1' Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] OldCreateOrder = False OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 object VirtualStringTree1: TVirtualStringTree Left = 8 Top = 8 Width = 409 Height = 153 Header.AutoSizeIndex = 0 Header.Font.Charset = DEFAULT_CHARSET Header.Font.Color = clWindowText Header.Font.Height = -11 Header.Font.Name = 'MS Sans Serif' Header.Font.Style = [] Header.Options = [hoColumnResize, hoDrag, hoShowHint, hoShowSortGlyphs, hoVisible] HintAnimation = hatNone HintMode = hmTooltip TabOrder = 0 Columns = < item Position = 0 Width = 150 WideText = 'column 0' WideHint = 'VT column 0 hint' end item Position = 1 Width = 150 WideText = 'column 1' WideHint = 'VT column 1 hint' end> end object Memo1: TMemo Left = 424 Top = 8 Width = 273 Height = 153 ScrollBars = ssVertical TabOrder = 1 end end
I debugged this for hours. I don’t see anything special. Why is this happening? who / what closes the prompt window immediately? Thanks.
I am using VT version 5.3.0
In TBaseVirtualTree.CMHintShowPause() says:
Here, a small workaround is needed to make the application class using the correct class of the prompt window. As soon as the application gets ShowHint set to true (this is the case when we want to show tooltips in the tree), then an internal tooltip will be created, which will not be our own class (because we do not set the application’s large-scale tooltip window, but only one for wood). Unfortunately, this hint by default of the window class will prevent hints from appearing for the non-client area (for example, for the header) , causing CancelHint when certain messages arrive. By setting the pause of confirmation impressions to 0 if our class of prompts was not recently, we check that the timer of prompts (in Forms.pas) is not used, and our class is created immediately.
I am not sure how to handle this. I think that I will abandon the idea of using my won hint class for header columns.