Reputation: 976
I can write some code inside TPopupMenu's OnPopUp event. But I also need another event for OnPopDown. Is there any way to do it using Delphi 10.3.3?
Upvotes: 1
Views: 918
Reputation: 449
In newer version (e.g. 11.2 Alexandria) TPopupMenu
has an build in OnClose
event
Upvotes: 1
Reputation: 109158
There are various options you can try.
In the simpler case when you have a particular control whose context menu you need to track, you can handle its WM_CONTEXTMENU
message manually:
protected
procedure WMContextMenu(var Message: TWMContextMenu);
message WM_CONTEXTMENU;
where (for example)
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;
The test ClientRect.Contains(ScreenToClient(Message.Pos))
is necessary so that you don't "overwrite" the scrollbar's own context menu. Also, you need to consider the case when the context menu is opened using the keyboard (e.g. menu key or Shift+F10).
If this is not enough for you, you could create your own TPopupMenu
child class and override its Popup
method, which is virtual. Add a DoPopdown
method and call it at the end (following the design of the DoPopup
method).
To quickly test this approach, you can use an interposer class:
type
TPopupMenu = class(Vcl.Menus.TPopupMenu)
procedure Popup(X, Y: Integer); override;
end;
implemented as
{ TPopupMenu }
procedure TPopupMenu.Popup(X, Y: Integer);
begin
inherited;
Windows.Beep(400, 500); // post-popup code
end;
But of course it is nicer to create a true descendant class (TPopupMenuEx
, perhaps?) that you register in the IDE. Add an FOnPopdown: TNotifyEvent
private field, a DoPopdown
protected function, and an OnPopdown
published property. This precisely mimics the OnPopup
mechanism.
Needless to say, this approach also works with a TTrayIcon
's menu.
Upvotes: 6