How to select Delphi frame instead of its components for an onclick event?

Viewed 343

I have created a VCL Form containing multiple copies of a TFrame, each containing multiple TLabel components.

The labels take up most of the area inside the frame, providing little exposed client area for selecting the frame specifically. The program must take action when the user selects a frame component and display specific text in the various label captions. The problem is that if the user clicks on one of the label components instead of an open area in the frame, the OnClick event is not triggered.

How do I generate the frame's OnClick event if the user clicks anywhere within the frame?

3 Answers

VCL tests a graphic (non windowed) control's response to mouse events before it decides if it is a valid target. You can use a specialized label then that modifies this response. Easiest would be to use an interposer class in your frame unit (if all the labels are expected to behave the same).

type
  TLabel = class(Vcl.StdCtrls.TLabel)
  protected
    procedure CMHitTest(var Message: TCMHitTest); message CM_HITTEST;
  end;

  TMyFrame = class(TFrame)
  ...
  end;

...

procedure TLabel.CMHitTest(var Message: TCMHitTest);
begin
  Message.Result := HTNOWHERE;
end;

Simply assign the very same OnClick event handler also to each of the labels inside. Multiple controls can share the same event handler, so long as they have the same signature.

If you don't mind Label's text to be greyed then you can simply set Enabled property of your Labels to False. This will prevent your labels to capture any keyboard or mouse events and thus all of these will got to the underlying frame.

Related