5

I want to mimic the TComBo list function which is closed when the user click 'outside' the list, but for another component (a TPanel). In Delphi XE2. Any Idea ?

philnext
  • 3,242
  • 5
  • 39
  • 62
  • 2
    possible duplicate of [Mimic outside click on a popup menu](http://stackoverflow.com/questions/3112402/mimic-outside-click-on-a-popup-menu) – Rob Kennedy Sep 19 '12 at 17:39
  • 1
    possible duplicate of [How to capture mouse clicks outside of form (like with Code Insight in Delphi)](http://stackoverflow.com/q/4524943/33732) – Rob Kennedy Sep 19 '12 at 17:40

1 Answers1

11

Assuming your panel is focussed (as I "read" from your question), then respond to the CM_CANCELMODE message which is send to all focussed windows.

type
  TPanel = class(Vcl.ExtCtrls.TPanel)
  private
    procedure CMCancelMode(var Message: TCMCancelMode); message CM_CANCELMODE;
  end;

  ...

{ TPanel }

procedure TPanel.CMCancelMode(var Message: TCMCancelMode);
begin
  inherited;
  if Message.Sender <> Self then
    Hide;
end;

When the panel itself is not focussed, e.g. a child control is, then this will not work. In that case you could track all mouse clicks (e.g. by the use of a TApplicationEvents.OnMessage handler) and compute whether the click was within the bounds of your panel:

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
  if Panel1.Visible and
      (Msg.message >= WM_LBUTTONDOWN) and (Msg.message <= WM_MBUTTONDBLCLK) and
      not PtInRect(Panel1.ClientRect, Panel1.ScreenToClient(Msg.pt)) then
    Panel1.Hide;
end;

But this still will not succeed when the click was - for example - in the list of a combobox which belongs to the panel but is partly unfolded outside of it. I would not know how to distil the panel from that click information.

NGLN
  • 43,011
  • 8
  • 105
  • 200
  • Closing == "visible := false;" – philnext Sep 19 '12 at 17:37
  • 1
    That's how to detect that a menu is going away, but that's because menus enter a special mode that the OS knows to cancel. How is the panel supposed to tell the OS that it's in "menu mode" so that the OS will know to send the message later? – Rob Kennedy Sep 19 '12 at 17:38
  • @RobKennedy `CM_CANCELMODE` is send by the VCL to whatever window has focus. I edited my answer to clarify that the panel has to be focussed somehow. Otherwise this will not work indeed. – NGLN Sep 19 '12 at 18:20
  • 1
    The panel can be focused by setting 'TabControl', but if the focus is then switched to a control parented by the panel, the panel is not sent a cancel mode anymore. – Sertac Akyuz Sep 19 '12 at 23:24
  • 1
    Perhaps one of the most useful answers I've found in a while :D – Jerry Dodge Aug 04 '16 at 21:52