【问题标题】:Stop TCustomHint from centering itself around my point阻止 TCustomHint 以我的观点为中心
【发布时间】:2013-09-23 13:51:13
【问题描述】:

我正在尝试使用TCustomHint 向我的用户显示一条可以很好地淡入淡出的消息,以免过于分散注意力。但是,当我用一个点在我的对象上调用ShowHint 时,提示框似乎以我给出的点为中心。我想要的是让我的盒子出现这样它的左上角坐标就是给定的点。

这是我正在使用的代码,因此请显示提示:

procedure ShowNotification(ATitle: UnicodeString; AMsg: UnicodeString);
var
  Box: TCustomHint;
  P: TPoint;
begin
    Box := TCustomHint.Create(MyForm);
    Box.Title := ATitle;
    Box.Description := AMsg;
    Box.Delay := 0;
    Box.HideAfter := 5000;
    Box.Style := bhsStandard;

    P.X := 0;
    P.Y := 0;

    Box.ShowHint(P);
end;

我知道我的点的 X/Y 坐标与表格无关,这不是问题所在。

我已经追踪了当我调用 ShowHint 时会发生什么,看来如果我能以某种方式控制 TCustomHint.ShowHint(Rect: TRect) 内部底层 TCustomHintWindow 的最终宽度,那么我可能会做生意。

所以我的问题是:有没有一种明显的方法可以阻止 TCustomHint 以我的观点为中心?或者我是否必须经历继承、覆盖绘图方法等的过程?我希望我只是缺少一些简单的东西。

【问题讨论】:

    标签: delphi delphi-xe3


    【解决方案1】:

    没有特别简单的方法可以做你想做的事。 TCustomHint 类旨在服务于一个非常特定的目的。它旨在供TControl.CustomHint 属性使用。您可以通过查看TCustomHint.ShowHint 的代码来了解它是如何调用的。相关摘录如下:

    if Control.CustomHint = Self then
    begin
      ....
      GetCursorPos(Pos);
    end
    else
      Pos := Control.ClientToScreen(Point(Control.Width div 2, Control.Height));
    ShowHint(Pos);
    

    因此,控件要么以当前光标位置为中心水平居中显示,要么以相关控件的中间为中心水平居中。

    我认为这里的底线是TCustomHint 并非旨在以您使用它的方式使用。

    无论如何,有一种相当可怕的方法可以让你的代码做你想做的事。您可以创建一个从不显示的临时TCustomHintWindow,并使用它来计算您要显示的提示窗口的宽度。然后使用它将您传递的点转移到真正的提示窗口。为了让它飞起来,你需要破解TCustomHintWindow的私有成员。

    type
      TCustomHintWindowCracker = class helper for TCustomHintWindow
      private
        procedure SetTitleDescription(const Title, Description: string);
      end;
    
    procedure TCustomHintWindowCracker.SetTitleDescription(const Title, Description: string);
    begin
      Self.FTitle := Title;
      Self.FDescription := Description;
    end;
    
    procedure ShowNotification(ATitle: UnicodeString; AMsg: UnicodeString);
    var
      Box: TCustomHint;
      SizingWindow: TCustomHintWindow;
      P: TPoint;
    begin
      Box := TCustomHint.Create(Form5);
      Box.Title := ATitle;
      Box.Description := AMsg;
      Box.Delay := 0;
      Box.HideAfter := 5000;
      Box.Style := bhsStandard;
    
      P := Point(0, 0);
      SizingWindow := TCustomHintWindow.Create(nil);
      try
        SizingWindow.HintParent := Box;
        SizingWindow.HandleNeeded;
        SizingWindow.SetTitleDescription(ATitle, AMsg);
        SizingWindow.AutoSize;
        inc(P.X, SizingWindow.Width div 2);
      finally
        SizingWindow.Free;
      end;
      Box.ShowHint(P);
    end;
    

    这符合你的要求,但老实说,这让我感到相当反感。

    【讨论】:

    • 感谢您的回复。我将不得不考虑这样做是否更好,或者我是否应该将 TCustomHint 用作“灵感”并从头开始构建我自己的课程。更倾向于后者。
    猜你喜欢
    • 2015-06-04
    • 1970-01-01
    • 2021-08-21
    • 2022-12-31
    • 2011-03-26
    • 1970-01-01
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多