【问题标题】:How to detect Hint sender-control in OnHint event-handler?如何在 OnHint 事件处理程序中检测提示发送者控制?
【发布时间】:2020-04-10 23:04:06
【问题描述】:

在 Delphi 10.3.3 Windows VCL 应用程序中,在 TApplicationEvents 组件的 OnHint 事件处理程序中,我在状态栏中显示当前提示:

procedure TForm1.ApplicationEvents1Hint(Sender: TObject);
begin
  statMain.SimpleText := Application.Hint;
end;

但是,我想添加一些包含特定运行时数据的特定文本,具体取决于哪个控件发送提示。

很遗憾,Sender 参数没有提供该信息。

那么如何检测是哪个控件发送了提示?

【问题讨论】:

  • 巧妙!最简单的往往是最好的解决方案!
  • @RemyLebeau:我知道OnShowHint 及其HintInfo.HintControl。我没有提到它的原因是因为它似乎只有在控件将ShowHint 设置为True 时才会触发(我从来没有,因为我希望我的提示出现在状态栏中,而不是黄色弹出窗口),并且它以通常的弹出提示延迟触发(我想要立即提示)。 OnHint 事件没有这些“缺点”。因此,我寻找替代解决方案。我现在意识到我仍然可以使用OnShowHint 抑制提示弹出窗口,并使用Application.HintPause 消除延迟。
  • 也许,在 OnHint 之外使用 OnShowHint 会使事情变得不必要地复杂?

标签: delphi delphi-10.3-rio hints


【解决方案1】:

OnHint 事件不提供对有关正在显示提示的控件的任何信息的访问。

但是,OnShowHint 事件确实如此,您可以在该事件中完全自定义提示:

procedure TForm1.ApplicationEvents1ShowHint(var HintStr: string;
  var CanShow: boolean; var HintInfo: THintInfo);
begin
  if HintInfo.HintControl = DesiredControl then
  begin
    // customize HintStr, and/or HintInfo fields, as needed...
  end;
end;

procedure TForm1.ApplicationEvents1Hint(Sender: TObject);
begin
  statMain.SimpleText := Application.Hint;
end;

HintInfo 提供有关您可以自定义的提示的各种信息:

提示控件
正在进行提示处理的控件的名称。

提示窗口类
提示窗口控件的类。默认值为 THintWindow,但您可以指定从 THintWindow 派生的任何类。如果您想用自定义提示窗口替换 THintWindow,请使用此字段。

提示位置
提示窗口左上角在屏幕坐标中的默认位置。通过更改此值来更改窗口的显示位置。

提示最大宽度
自动换行开始前提示窗口的最大宽度。默认情况下,该值为屏幕的宽度(全局 Screen 变量的 Width 属性)。

提示颜色
提示窗口的背景颜色。

光标矩形
要显示提示窗口,用户鼠标指针必须位于的矩形。 CursorRect 的默认值是控件的客户矩形。更改此值,以便可以将单个控件划分为多个提示区域。当用户将鼠标指针移到矩形外时,提示窗口消失。

光标位置
鼠标指针在控件中的位置。

重新显示超时
提示系统在再次询问提示状态之前应该等待多长时间。默认情况下,该字段为零,表示提示状态不会改变。将其设置为非零值将导致提示在请求的毫秒数过去后采取行动,就好像用户将鼠标移出提示矩形并重新移入一样。这可用于推迟提示处理一段时间时间,或允许定期更新提示。

隐藏超时
显示提示的毫秒数。默认情况下,它设置为 Application 变量的 HintHidePause 属性的值。

HintStr
要在提示窗口中显示的字符串。这允许 OnHint 事件处理程序在显示之前修改提示的内容。默认情况下,它包含 GetShortHint 函数在传递 Application 变量的 Hint 属性值时返回的值。

提示数据
要传递给提示窗口控件的附加数据。将此字段与 HintWindowClass 结合使用。

另外,仅供参考,您不需要使用TApplication(Event).OnHint 事件来在TStatusBar 中显示TApplication.Hint 文本。如果将 StatusBar 的 AutoHint 属性设置为 true,则 StatusBar 可以自动显示 TApplication.Hint 更新。您只需要确保没有分配OnHint 处理程序,否则AutoHint 将不起作用(不过OnShowHint 很好)。

【讨论】:

  • "AutoHint":我试过了。但出于某种奇怪的原因,AutoHint 在我的具体情况下不起作用。因此,要修改提示,我需要使用您的解决方案。
  • @user1580348 TStatusBar.AutoHint 在分配 TApplication(Events).OnHint 处理程序时不起作用。当TApplication.Hint 更新时,如果分配了TApplication(Events).OnHint 事件,则会触发,否则THintAction 会广播到所有控件,这是TStatusBarAutoHint 为True 时侦听的内容。所以,如果你想使用AutoHint,那么不要使用OnHint(不过OnShowHint 很好)。
  • 这很奇怪:有时,OnShowHint 事件发生在OnHint 事件之后!为什么会这样?
  • 更奇怪的是:如果我将CodeSite.Send 调试消息放入OnHintOnShowHint 事件处理程序中,那么OnShowHint 事件处理程序中的调试消息不会被发送,仅发送OnHint 事件处理程序中的调试消息!
  • @RemyLebeau:据我所知,文档是正确的。默认为True。作为一个类的成员,该字段最初是False,并且在TApplication.Create 中也不必要地设置为False(10.3.2 中的Vcl.Forms:9617)。但是TApplication.CreateVcl.Controls.InitControls(来自单元的initialization 部分)在Delphi 10.3.2 中的Vcl.Controls.pas:16545 行调用。 Application := TApplication.Create(nil) 之后的下一行是 Application.ShowHint := True。事实上,在主窗体的OnCreate 中,例如,Application.ShowHintTrue
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-18
  • 1970-01-01
  • 1970-01-01
  • 2014-02-14
  • 1970-01-01
  • 2013-05-30
相关资源
最近更新 更多