Assuming that your panel is focused (as I "read" from your question), then respond to the CM_CANCELMODE message, which is sent to all focused 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 does not focus, for example. child control then this will not work. In this case, you can track all mouse clicks (for example, using the TApplicationEvents.OnMessage handler) and calculate whether the click was within 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 if the click was, for example, in a list with a list that belongs to the panel but is partially expanded outside it. I donβt know how to separate the panel from the information about this click.
source share