拦截delphi上的提示事件

时间:2012-10-11 11:22:27

标签: delphi delphi-xe2 windows-messages hint

我试图在组件内部的运行时暂时更改提示文本, 无需更改Hint属性本身。

我试过捕捉CM_SHOWHINT,但这个事件似乎只是来了 形式,但不是组件本身。

插入CustomHint也不起作用,因为它需要文本 来自Hint属性。

我的组件是TCustomPanel

的后代

这是我正在尝试做的事情:

procedure TImageBtn.WndProc(var Message: TMessage);
begin
  if (Message.Msg = CM_HINTSHOW) then
    PHintInfo(Message.LParam)^.HintStr := 'CustomHint';
end;

我在互联网的某个地方找到了这个代码,不幸的是它不起作用。

2 个答案:

答案 0 :(得分:11)

CM_HINTSHOW确实正是你所需要的。这是一个简单的例子:

type
  TButton = class(Vcl.StdCtrls.TButton)
  protected
    procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW;
  end;

  TMyForm = class(TForm)
    Button1: TButton;
  end;

....

procedure TButton.CMHintShow(var Message: TCMHintShow);
begin
  inherited;
  if Message.HintInfo.HintControl=Self then
    Message.HintInfo.HintStr := 'my custom hint';
end;

问题中的代码未能调用inherited,这可能是失败的原因。或者类声明可能省略override上的WndProc指令。无论如何,在这个答案中我的方式更清晰。

答案 1 :(得分:6)

您可以使用OnShowHint事件

它有HintInfo参数:http://docwiki.embarcadero.com/Libraries/XE3/en/Vcl.Forms.THintInfo

该参数允许您查询提示控件,提示文本和所有上下文 - 并在需要时覆盖它们。

如果要过滤哪些组件可以改变提示,例如,可以声明某种类型的ITemporaryHint界面

type 
  ITemporaryHint = interface 
  ['{1234xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}']
    function NeedCustomHint: Boolean;
    function HintText: string;
  end;

然后,您可以稍后检查任何组件,无论它们是否实现该接口

procedure TForm1.DoShowHint(var HintStr: string; var CanShow: Boolean;
  var HintInfo: THintInfo);
var
  ih: ITemporaryHint;
begin
  if Supports(HintInfo.HintControl, {GUID for ITemporaryHint}, ih) then
    if ih.NeedCustomHint then
      HintInfo.HintStr := ih.HintText;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.ShowHint := True;
  Application.OnShowHint := DoShowHint;
end;