Я хочу имитировать функцию списка TComBo, которая закрывается, когда пользователь щелкает «вне» списка, но для другого компонента (TPanel). В Делфи XE2. Любая идея ?
Как «закрыть по внешнему клику» для TPanel (например, TCombo) в Delphi
comment
возможный дубликат Имитировать внешний щелчок по всплывающему меню
- person Rob Kennedy   schedule 19.09.2012
comment
возможный дубликат Как фиксировать щелчки мыши вне формы (например, с помощью Code Insight в Delphi)
- person Rob Kennedy   schedule 19.09.2012
Ответы (1)
Предполагая, что ваша панель сфокусирована (как я «читал» из вашего вопроса), затем ответьте на сообщение CM_CANCELMODE
, которое отправляется во все сфокусированные окна.
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;
Когда сама панель не сфокусирована, т.е. есть дочерний контроль, то это не сработает. В этом случае вы можете отслеживать все щелчки мыши (например, с помощью обработчика TApplicationEvents.OnMessage
) и вычислять, находился ли щелчок в пределах вашей панели:
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;
Но это все равно не получится, когда клик был, например, в списке выпадающего списка, который принадлежит панели, но частично развернут за ее пределы. Я бы не знал, как выделить панель из этой информации о щелчке.
person
NGLN
schedule
19.09.2012
Закрытие == видимое := ложное;
- person philnext; 19.09.2012
Вот как определить, что меню исчезает, но это потому, что меню входят в специальный режим, который ОС знает, чтобы отменить. Как панель должна сообщить ОС, что она находится в режиме меню, чтобы ОС знала, что сообщение нужно отправить позже?
- person Rob Kennedy; 19.09.2012
@RobKennedy
CM_CANCELMODE
отправляется VCL в любое окно, имеющее фокус. Я отредактировал свой ответ, чтобы уточнить, что панель должна быть как-то сфокусирована. Иначе это действительно не сработает.
- person NGLN; 19.09.2012
Панель можно сфокусировать, установив «TabControl», но если затем фокус переключится на элемент управления, родительский для панели, панель больше не будет отправлять режим отмены.
- person Sertac Akyuz; 20.09.2012
Возможно, один из самых полезных ответов, которые я нашел за последнее время: D
- person Jerry Dodge; 05.08.2016