Перехват события подсказки в delphi

Я пытаюсь временно изменить текст подсказки во время выполнения внутри компонента, не изменяя само свойство 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;

Я нашел этот код где-то в Интернете, но, к сожалению, он не работает.


person ertx    schedule 11.10.2012    source источник


Ответы (2)


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. Неважно, это чище, как у меня в этом ответе.

person David Heffernan    schedule 11.10.2012
comment
Вы также можете сделать то же самое, используя вместо этого событие TApplication.OnShowHint. - person Remy Lebeau; 12.10.2012
comment
@Remy Плюсы и минусы в обоих направлениях. Если вы пишете компонент, то сообщение лучше всего. Если вы хотите применить политику для всего приложения, лучше использовать OnShowHint. - person David Heffernan; 12.10.2012

Вы можете использовать событие 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;  
person Arioch 'The    schedule 11.10.2012
comment
О, @TLama, кажется несовместимым делать эти замены вместе: boolean -> Boolean и String - string. Однако объявление DoShowHint взято непосредственно из примеров Delphi DocWiki. Я бы доверял их выбору String. - person Arioch 'The; 11.10.2012