2

我正在尝试向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,似乎如果我能以某种方式控制底层TCustomHintWindow内部的最终宽度,TCustomHint.ShowHint(Rect: TRect)那么我可能会做生意。

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

4

1 回答 1

3

没有特别简单的方法可以做你想做的事。该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;

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

于 2013-09-23T15:05:57.417 回答