【问题标题】:How to show hint using Application.ActivateHint on Delphi?如何在 Delphi 上使用 Application.ActivateHint 显示提示?
【发布时间】:2013-02-08 11:21:38
【问题描述】:

我有以下代码试图显示提示:

procedure TMyGrid.OnGridMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
var
  aPoint: TPoint;
begin
  inherited;
  //Application.Hint := 'Hint Text';
  //Application.ShowHint := True;
  Grid.Hint := 'Hint Text';
  Grid.ShowHint := True;
  aPoint.X := X;
  aPoint.Y := Y;
  Application.ActivateHint(aPoint);
end;

但是没有出现任何提示。怎么了?

【问题讨论】:

    标签: delphi hint


    【解决方案1】:

    ActivateHint 想要您的点在屏幕坐标中,而不是在客户端坐标中。

    来自文档:

    ActivateHint 将控件或菜单​​项定位在 CursorPos 指定的位置,其中 CursorPos 表示屏幕坐标,以像素为单位。找到控件后,ActivateHint 会在提示窗口中显示控件的 Hint。

    所以,你必须像这样改变你的方法:

    procedure TMyGrid.OnGridMouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Integer);
    var
      aPoint: TPoint;
    begin
      inherited;
      //Application.Hint := 'Hint Text';
      Grid.Hint := 'Hint Text';
      Grid.ShowHint := True;
      aPoint.X := X;
      aPoint.Y := Y;
      aPoint := ClientToScreen(aPoint);
      Application.ActivateHint(aPoint);
    end;
    

    【讨论】:

    • 谢谢!但是为什么提示没有显示在窗口外(坐标不正确)?
    • 在我的情况下它工作正常。你希望它出现在哪里?它出现在哪里?
    • 我认为,正确的代码:Grid.ClientToScreen。在我的情况下没有出现 - 例如,X:200, Y:15。
    • 嗯,您知道什么是 TMyGrid 以及 X、Y 相对于什么控件。我假设这是一个表单,并且方法在表单上,​​所以 Self.ClientToScreen 是正确的,但你是知道的人!
    【解决方案2】:

    与其试图强制TApplication 在您的网格控件的OnMouseMove 事件中显示新提示,正确的方法是让您的网格处理CM_HINTSHOW 消息以自定义当前提示,只要它正常显示.

    CM_HINTSHOW 消息在其LPARAM 值中为您提供了指向THintInfo 记录的指针。 THintInfo 有一个 CursorPos 成员,它告诉您当前鼠标在控件的客户区内的位置,还有一个 CursorRect 成员,它允许您在控件的客户区内定义一个矩形,当前提示应该对其有效(@ 987654332@ 有其他成员用于进一步自定义提示,例如文本、颜色、窗口类、显示/隐藏超时等)。当鼠标移出该矩形但仍在控件的客户区域内时,将再次生成CM_HINTSHOW 消息以获取新信息以更新当前提示。

    如果您需要在每次鼠标移动时更新提示,您可以定义一个只包含当前CursorPos 的自定义CursorRect,例如:

    type
      TMyGrid = class(...)
      private
        procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW;
      end;
    
    procedure TMyGrid.CMHintShow(var Message: TCMHintShow);
    begin
      with Message.HintInfo^ do
      begin
        HintStr := Format('Hint Text (%d,%d)', [CursorPos.X, CursorPos.Y]);
        CursorRect := Rect(CursorPos.X, CursorPos.Y, CursorPos.X, CursorPos.Y);
      end;
    end;
    

    【讨论】:

    • 这也正是我所需要的。我担心是否只是更改 OnMouseMove 中的提示文本和/或首先调用 Application.CancelHint,以及这会对超时产生什么影响。现在我知道这是错误的方法。
    • 顺便说一句,当您不想/不能子类化控件时,这也适用于Application.OnShowHint
    • @IanGoldby:你总是可以子类化一个控件,即使你不得不使用它的WindowProc 属性来做到这一点。但是,是的,你说的是真的。 THintInfo 首先通过CM_HINTSHOW 发送到组件。如果组件没有拒绝它(通过返回一个非零值),那么 THintInfo 将发送到 TApplication.OnShowHint 事件处理程序(如果已分配)。如果事件处理程序没有拒绝它(通过将CanShow 参数设置为false,或清除THintInfo.HintStr 字段),则THintInfo 用于激活/更新提示窗口。
    猜你喜欢
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-30
    • 1970-01-01
    • 2010-10-11
    • 2011-06-12
    • 1970-01-01
    相关资源
    最近更新 更多