Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercepting hint event on delphi

I am trying to change hint text temporarily at a run-time inside of a component, without changing the Hint property itself.

I've tried catching CM_SHOWHINT, but this event seems to only come to form, but not the component itself.

Inserting CustomHint doesnt really work either, because it takes the text from the Hint property.

my component is descendant from TCustomPanel

Here's what i'm trying to do:

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

I've found this code somewhere in the internet, unfortunately it doesn't work tho.

like image 369
ertx Avatar asked Dec 03 '22 01:12

ertx


2 Answers

CM_HINTSHOW is indeed just what you need. Here's a simple example:

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;

The code in the question is failing to call inherited which is probably why it fails. Or perhaps the the class declaration omits the override directive on WndProc. No matter, it's cleaner the way I have it in this answer.

like image 146
David Heffernan Avatar answered Dec 22 '22 10:12

David Heffernan


You can use OnShowHint event

  • http://docwiki.embarcadero.com/Libraries/XE3/en/Vcl.Forms.TApplication.OnShowHint
  • http://docwiki.embarcadero.com/Libraries/XE3/en/Vcl.AppEvnts.TCustomApplicationEvents.OnShowHint

It has HintInfo parameter: http://docwiki.embarcadero.com/Libraries/XE3/en/Vcl.Forms.THintInfo

That parameter lets you query the hint control, hint text and all that context - and override them it if needed.

If you want to filter which components to change hint for you may, for example, declare some kind of ITemporaryHint interface like

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

Then you can check later generically any of your components, whether they implement that interface

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;  
like image 33
Arioch 'The Avatar answered Dec 22 '22 09:12

Arioch 'The