Delphi中TTabSheet的提示信息

7
我希望能够创建一个TPageControl和一些TTabSheet,每个选项卡上的提示工具随着我的轮流悬停而可见。
在Delphi 2009中有没有办法实现这种效果?
5个回答

7

只需挂接页面控件的MouseMove事件并使用TabAtPos属性确定鼠标悬停在哪个选项卡上。然后将该选项卡的提示分配给页面控件的提示属性。

procedure TForm.PageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: integer);
var
  tabindex: integer;
begin
  tabindex := PageControl.IndexOfTabAt(X, Y);
  if (tabindex >= 0) and (PageControl.Hint <> PageControl.Pages[tabindex].Hint) then
  begin
    Application.CancelHint;
    PageControl.Hint := PageControl.Pages[tabindex].Hint;
    PageControl.ShowHint := true;
  end;
end;

当鼠标直接从一个选项卡移动到另一个选项卡时,CancelHint/ShowHint会负责更新提示窗口。

以下是改进但丑陋的版本,它在鼠标直接从选项卡移动到另一个选项卡时,暂时将HintPause更改为0,以便立即重新显示提示。 (解决方案中“丑陋”的部分是Application.ProcessMessages调用,它强制处理提示消息,然后恢复HintPause。)

procedure TForm.PagesMouseMove(Sender: TObject; Shift: TShiftState; X, Y: integer);
var
  hintPause: integer;
  tabindex: integer;
begin
  tabindex := PageControl.IndexOfTabAt(X, Y);
  if (tabindex >= 0) and (PageControl.Hint <> PageControl.Pages[tabindex].Hint) then
  begin
    hintPause := Application.HintPause;
    try
      if PageControl.Hint <> '' then
        Application.HintPause := 0;
      Application.CancelHint;
      PageControl.Hint := PageControl.Pages[tabindex].Hint;
      PageControl.ShowHint := true;
      Application.ProcessMessages; // force hint to appear
    finally Application.HintPause := hintPause; end;
  end;
end;

为了在主页面上隐藏提示,将以下方法分配给页面控件的OnMouseLeave事件。
procedure TForm.PageMouseLeave(Sender: TObject);
begin
  PageControl.Hint := '';
  PageControl.ShowHint := false;
end;

TabAtPos不存在,您的意思是IndexOfTabAt(x,Y)。 这个so几乎可以正常工作。除了当您从一个选项卡移动到另一个选项卡时,提示不会更新或重新显示。 - Roddy
抱歉,我使用的是TRzTabSheet(Raize Components),它有一个TabAtPos属性并且工作得很好。您可以使用THintWindow类在选项卡索引更改时编程地显示提示。将页面控件的Show Hint属性设置为false并创建您自己的提示窗口。 - user34411
IndexOfTabAt 存在于 Delphi Tokyo 中! - Gabriel
@Roddy- 在 Delphi Tokyo 中存在 IndexOfTabAt! - Gabriel
@Rigel - 这可能与我在我的答案中的评论有关 - Raize组件已于2015年被Embarcadero收购,用于Delphi。 - Argalatyr

6
Raize Components中,可以通过将trzpagecontrol.tabhints属性设置为true来实现。好的组件可以节省很多时间(因此也节省了金钱)。
(顺便说一句,我是一个快乐的客户)
更新(回应@Rigel的评论)来自raize.com FAQRaize Components选项卡):

Raize Components发生了什么?

回到2015年,Embarcadero从我们这里收购了Raize Components,并将产品重新命名为Konopka Signature VCL Controls(KSVC)。最初他们单独销售该产品,但在过去几个RAD Studio版本中,这些组件已经通过GetIt包管理器免费提供。只需从Delphi或C ++ Builder Tools菜单中打开GetIt Package Manager,然后搜索“Konopka”以查找安装程序。组件名称、单元和包与Raize Components中的相同,只是产品名称不同。


2
投资Raize组件是非常值得的。支持服务是世界一流的,视觉风格选项可以确实使您的应用与使用标准控件的其他应用区别开来。 - skamradt
同意。我们几乎完全使用Raize进行所有UI设计工作。出色的组件和良好的支持。 - user34411
看起来他们放弃了组件库。在他们的网站上找不到:https://raize.com/ - Gabriel
如果原始页面保留在原地,并发布一则公告,而不是被删除的话,这会更好 :) - Gabriel

2

1 - 填写.Hint属性,并将.ShowHint属性设置为True,适用于PageControl(假设每个选项卡都已将ParentShowHint设置为true;否则您需要单独设置每个页面)。

2 - 将此事件分配给PageControl的OnChange事件处理程序:

procedure TForm1.PageControl1Change(Sender: TObject);
begin
  PageControl1.Hint := PageControl1.ActivePage.Hint;
end;

在你这样做之后,提示将是活动选项卡的内容。我不确定如何根据鼠标悬停的位置更改提示 - 实际上,这是我以前从未注意到的有趣现象。


我认为问题是关于在不更改活动页面的情况下显示特定于页面的提示。 - Wolf

1

0

最初我在一个 C++ Builder 6 (!) 项目上工作(所以请原谅此转录中的任何打字错误),我从Gerard的答案[1]开始,并尽可能地减少了代码。为了更好地控制Application.CancelHint的调用,我引入了成员变量FLastHintTabIndex,它必须初始化为-1。

procedure TForm1.PageControl1MouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
var
  TabIndex: Integer;
begin
  TabIndex := PageControl1.IndexOfTabAt(X, Y);
  if FLastHintTabIndex <> TabIndex then
      Application.CancelHint;
  if TabIndex <> -1 then
      PageControl1.Hint = PageControl1.Pages[TabIndex].Hint;
  FLastHintTabIndex := TabIndex;
end;

[1] 我的回答并没有太多新内容,但我发现所有那些代码和文本太过分散注意力。


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