Jump to content
alogrep

THintWindow; exposing the WMLButtonDown event

Recommended Posts

Hi

I got this neat piece of code froma OpenAI GPT searc


 
type
  TMyHintWindow = class(THintWindow)
  protected
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
  end;

procedure TMyHintWindow.WMLButtonDown(var Message: TWMLButtonDown);
begin
  // Close the hint window when clicked
  ReleaseHandle;
end;

I put the first part in the interface section, the second in the implementation.

But the the WMLButtonDown   (clic left button, right?) never gets triggered.

What is missing to make it work?

Also, in case I make it work, I lso have set the timerr to hide it after 2 seconds. In the timere I use wh (The TMyHintWindow control)

if wh <> Nil then begin   

  wh.releasehandle.

  wh.free;

  wh:=Nil;

end.

How can I make the same inside  the WMLButtonDown event?

Thanks very much.

 

  wh

 

Share this post


Link to post

The correct link is https://docwiki.embarcadero.com/Libraries/en/Vcl.Forms.HintWindowClass

 

Also, you don't need to assign the HintWindowClass before Application.Run() is called (though you certainly can). Just be sure to assign it before any hints are displayed at runtime. For instance, in the MainForm's OnCreate event would suffice.

 

Also, if you don't want to override the hint behavior globally, you can customize the hint on a per-invocation basis by using the TApplication[Events].OnShowHint event. It gives you access to a THintInfo describing the hint that is about to be displayed, which has a HintWindowClass field (amongst many others). 

Edited by Remy Lebeau

Share this post


Link to post

Thanks both. But it still does not work. This is the code.

I crated a unit

unit myhint;

interface
   uses classes, messages,graphics,controls, comctrls;
type
  TMyHintWindow = class(THintWindow)
  protected
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
  public
    constructor Create(AOwner: TComponent); override;
  end;
implementation
constructor TMyHintWindow.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Color := clinfobk;
end;


procedure TMyHintWindow.WMLButtonDown(var Message: TWMLButtonDown);
begin
  // Close the hint window when clicked
  ReleaseHandle;
end;

end.

unit myhint;

interface
   uses classes, messages,graphics,controls, comctrls;
type
  TMyHintWindow = class(THintWindow)
  protected
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
  public
    constructor Create(AOwner: TComponent); override;
  end;
implementation
constructor TMyHintWindow.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Color := clinfobk;
end;


procedure TMyHintWindow.WMLButtonDown(var Message: TWMLButtonDown);
begin
  // Close the hint window when clicked
  ReleaseHandle;
end;

end.

in the dr:

 

    Application.Initialize;
    HintWindowClass:=TMyHintWindow;

Then in the form  i include myhint.pas. In the FormCreate I crete the control

     wh:=TMyhintWindow.crete(nil)

The wh constructor is executed (the beakpoint is triggered).

But when I clkic on the hintt, the 

 

procedure TMyHintWindow.WMLButtonDown(var Message: TWMLButtonDown);
begin
  // Close the hint window when clicked
  ReleaseHandle;
end;

 

is not triggered.

Share this post


Link to post

You don't need to create an instance of your hint class. By setting the HintWindowClass variable, the VCL will instantiate your class when needed.

 

In any case, the reason your code doesn't work is because by default THintWindow responds to WM_NCHITTEST to return HTTRANSPARENT, thus all mouse activity gets directed to the window that is underneath the hint.  You can intercept WM_NCHITTEST yourself to return HTCLIENT instead, so thus your WM_LBUTTONDOWN handler will be triggered when clicking on the hint window.

 

However, then you run into a new problem, because as soon as the mouse enters the hint window, it effectively leaves the control underneath the hint, and thus the control hides the hint immediately before you can click on it.  You can work around that by having TMyHintWindow override the virtual ShouldHideHint() method to return False.  Then, you will have opportunity to click on the hint window.

 

However, then you run into a new problem, because as soon as your click closes the hint, the mouse will effectively re-enter the control that was underneath the hint, and the control will reshow the hint again.

 

Isn't this fun? :classic_wacko: What exactly are you trying to accomplish by messing with the hint window's default behavior?

Edited by Remy Lebeau

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×