Я могу написать некоторый код внутри события OnPopUp TPopupMenu. Но мне также нужно другое событие для OnPopDown. Есть ли способ сделать это с помощью Delphi 10.3.3?
Как обнаружить событие OnClose (OnPopDown) TPopupMenu в приложениях Delphi
Ответы (1)
Есть разные варианты, которые вы можете попробовать.
Подход 1
В более простом случае, когда у вас есть конкретный элемент управления, контекстное меню которого нужно отслеживать, вы можете обработать его сообщение WM_CONTEXTMENU
вручную:
protected
procedure WMContextMenu(var Message: TWMContextMenu);
message WM_CONTEXTMENU;
где (например)
procedure TForm1.WMContextMenu(var Message: TWMContextMenu);
begin
if
Assigned(PopupMenu)
and
(ClientRect.Contains(ScreenToClient(Message.Pos)) or (Message.Pos = Point(-1, -1)))
then
begin
Windows.Beep(200, 500); // pre-popup code
if (Message.XPos = -1) and (Message.YPos = -1) then // Menu key or Shift+F10
with ClientToScreen(Point(0, 0)) do
PopupMenu.Popup(X, Y)
else
PopupMenu.Popup(Message.XPos, Message.YPos);
Windows.Beep(400, 500); // post-popup code
end
else
inherited;
end;
Тест ClientRect.Contains(ScreenToClient(Message.Pos))
необходим, чтобы вы не перезаписали собственное контекстное меню полосы прокрутки. Также нужно учитывать случай, когда контекстное меню открывается с помощью клавиатуры (например, клавиши меню или Shift+F10).
Подход 2
Если вам этого недостаточно, вы можете создать свой собственный TPopupMenu
дочерний класс и переопределить его метод Popup
, который является виртуальным. Добавьте метод DoPopdown
и вызовите его в конце (в соответствии с дизайном метода DoPopup
).
Чтобы быстро протестировать этот подход, вы можете использовать класс интерпозера:
type
TPopupMenu = class(Vcl.Menus.TPopupMenu)
procedure Popup(X, Y: Integer); override;
end;
реализовано как
{ TPopupMenu }
procedure TPopupMenu.Popup(X, Y: Integer);
begin
inherited;
Windows.Beep(400, 500); // post-popup code
end;
Но, конечно, лучше создать настоящий класс-потомок (возможно, TPopupMenuEx
?), который вы регистрируете в IDE. Добавьте FOnPopdown: TNotifyEvent
закрытое поле, DoPopdown
защищенную функцию и OnPopdown
опубликованное свойство. Это точно имитирует механизм OnPopup
.
Излишне говорить, что этот подход также работает с меню TTrayIcon
.
PopupMenu
формы значение PopupMenu1
или у вас есть элемент управления TRichEdit
с именем RichEdit1
, PopupMenu
которого вы установили для PopupMenu1
. Или, может быть, у вас есть код, который вызывает PopupMenu1.Popup
вручную. Что он?
- person Andreas Rejbrand; 18.07.2020
TForm1
в разделе interface
. Второй фрагмент должен находиться в разделе implementation
. Это будет работать. Обещаю. Если щелкнуть форму правой кнопкой мыши, вы услышите низкочастотный звуковой сигнал перед отображением всплывающего меню и высокочастотный звуковой сигнал, когда оно будет закрыто. Вы должны заменить эти звуковые сигналы кодом, который вы хотите выполнить до и после отображения меню.
- person Andreas Rejbrand; 18.07.2020
Sender
?
- person Andreas Rejbrand; 19.07.2020
TPopupListEx
) действительно работает. Я использовал его раньше. - person Remy Lebeau   schedule 21.07.2020