Is there a HitTest property or something in VCL for Delphi?

166 Views Asked by At

In FireMonkey (FMX), every TControl component has a HitTest property that allows me to enable or disable mouse events on the component.

Is there something like this in VCL? I tried searching and looking for it, but I can't find a HitTest property anywhere.

If there isn't HitTest for VCL, how can the same be achieved? Can someone provide a code example on how to do it in VCL perhaps?

I am using Embarcadero Delphi 12.

1

There are 1 best solutions below

10
Remy Lebeau On

There is no such property in VCL.

All FMX controls are entirely custom made with very little management by the OS, so mouse handling is managed by FMX itself, thus exposing a HitTest property is trivial for FMX to do.

But in VCL, only TGraphicControl descendants are implemented like that. TWinControl descendants, on the other hand, are wrappers for Win32 HWND windows and so mouse handling is largely managed by the OS instead.

For windowed VCL controls, you will have to manually subclass each control as needed to handle the Win32 WM_NCHITTEST message directly. The VCL doesn't normally handle that message (except in a few select cases).

For example:

private
  PrevWndProc: TWndMethod;
  procedure MyWndProc(var Message: TMessage);

procedure TMyForm.FormCreate(Sender: TObject);
begin
  PrevWndProc := SomeControl.WindowProc;
  SomeControl.WindowProc := MyWndProc;
end;

procedure TMyForm.MyWndProc(var Message: TMessage);
begin
  PrevWndProc(Message);
  if Message.Msg = WM_NCHITTEST then
  begin
    ...
    if MessageShouldBeIgnored then
      Message.Result := HTNOWHERE;
  end;
end;

For a graphic control, you would have to subclass its windowed Parent control instead.

However, be careful with how you modify the default behavior of WM_NCHITTEST:

WM_NCHITTEST is for hit-testing, and hit-testing can happen for reasons other than the mouse being over your window