TVirtualStringTree - 如何为VT列使用我自己的提示窗口类?

时间:2017-06-24 09:20:08

标签: delphi virtualtreeview tvirtualstringtree

我想为我的整个应用程序使用自定义Hint窗口类。 我使用Application.OnShowHint,分析THintInfo,然后在TMyHintWindow中返回我自己的HintInfo.HintWindowClass。这适用于所有控件,但我只有TVirtualStringTree 提示才有奇怪的问题。

VT使用它自己的提示窗口和HintInfo.HintData自己的结构。我研究代码,并知道它使用VTHintData。到现在为止还挺好。问题是,当我返回自己的提示窗口类(派生自THintWindow)时,它仅显示提示窗口一瞬间消失!

树节点返回的提示没有问题。他们使用相同的方法/结构(VTHintData)。

这是一个非常简单的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's 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.

形式:

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

我已经调试了好几个小时。我觉得没什么特别的。 为什么会这样?谁/什么立即关闭提示窗口? 感谢。

我正在使用VT版本5.3.0

TBaseVirtualTree.CMHintShowPause()中声明:

  

这里需要一个小的解决方法来创建应用程序类   使用正确的提示窗口类。一旦应用程序获得   ShowHint设置为true(当我们想要显示提示时就是这种情况   树)然后将创建一个内部提示窗口,而不是   我们自己的类(因为我们没有设置应用程序范围的提示窗口   类,但只有一个树)。 不幸的是,此默认提示   窗口类将阻止显示非客户区域的提示   每当某些消息时,通过调用CancelHint (例如标题)   到达。如果我们的提示类不是,则通过将提示show pause设置为0   最近使用我们确保提示计时器(在Forms.pas中)是   未使用,我们的班级立即创建。

我不确定如何处理这个问题。我想我会放弃使用我的赢得提示类作为标题列的整个想法。

0 个答案:

没有答案