如何在THintWindow中创建TButton或其他控件?

9
我正在尝试创建一个THintWindow并在其上放置一个TButton或TFrame。这是我的代码:

TForm1 = class(TForm)
  Button1: TButton;
  Button2: TButton;
  procedure FormCreate(Sender: TObject);
  procedure Button1Click(Sender: TObject);
  procedure Button2Click(Sender: TObject);
private
  HintWindow: THintWindow;
public
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  HintWindow := THintWindow.Create(Self);
  HintWindow.Color := clInfoBk;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  P: TPoint;
  R: TRect;
  Control: TControl;
begin
  Control := Button1;
  P := Control.ClientToScreen(Point(0, Control.Height));
  R := Rect(P.X, P.Y, P.x + 100, P.Y + 100);
  with TButton.Create(HintWindow) do
  begin
    Parent := HintWindow;
    Caption := 'My Button';
  end;
  HintWindow.ActivateHint(R, 'My Hint');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  HintWindow.ReleaseHandle;
end;

提示窗口已显示,但我看不到TButton。似乎在提示窗口内没有子窗口(我使用Spy++测试了“第一个子窗口”)。 我还尝试用新的CreateParams子类化THintWindow:

procedure TMyHintWindow.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.Style := Params.Style or WS_CLIPCHILDREN;
  Params.ExStyle := Params.ExStyle or WS_EX_CONTROLPARENT;
end;

当我将TFrame创建为提示窗口的子窗口时,Spy++显示提示窗口上有一个子窗口,但是我看不到它(即使我强制将其可见)。

请问对此有什么反馈吗?


那段代码对我来说完美运行,不需要子类化。你用的是哪个版本的Delphi? - David Heffernan
1
D5。呃!是的,我在用XE2,我可以完美地看到这个按钮。 - David Heffernan
David,能否请教一下你的控件单元中“THintWindow.Create”和“THintWindow.CreateParams”的源代码?这个请求是否过分了些? - kobik
我可以在D6中重现您的行为,并且在D6中使用XE2代码会使按钮出现。我会继续搜索。 - David Heffernan
2
看起来你和我同时得出了相同的答案!我研究了XE2源代码,最明显的区别是在ActivateHint中设置ParentWindow。XE2代码总是将其设置为Application.Handle,所以我认为这只是最简单的方法。没有必要尝试将其设置为ActiveForm.Handle - David Heffernan
显示剩余3条评论
1个回答

11

不要问我为什么,但在旧版本的Delphi中,您可以通过在创建THintWindow实例后立即将ParentWindow设置为Application.Handle来使其正常工作:

HintWindow := THintWindow.Create(Self);
HintWindow.ParentWindow := Application.Handle;
这个答案的灵感来自于现代版本的Delphi VCL源代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接