Delphi TMenuItem OnClick not working if menu has sub items - delphi

It appears Onclick events are not processed for menu items that have sub-items.
I realize I could create a leaf item which users could use instead, but I would like to have my menu folders respond to OnClick (in my case to "launch" all sub-items)
Is there any way around this limitation?

Menu items that have sub-items do indeed fire OnClick events. But they fire when the sub-menu opens rather than when you click on the parent menu item.
I'm pretty sure you don't want to invoke all sub-items when that happens. The OnClick event for a parent menu fires whenever the sub-menu is opened. Either when you click on the parent menu item, hover over it, or press the right arrow key when the menu item is selected via the keyboard.
So, the OnClick event for a parent menu corresponds to opening the sub-menu. Invoking all the child menu item actions when the sub-menu is opened goes against all standard expected UI behaviour. What you should do is add another sub-item that can be used to invoke all actions. Don't go against the platform standard UI unless there are no sane alternatives.

Related

Get the calling component of TPopupMenu

I have a TStringGrid, that has a TPopupMenu connected.
By clicking one event of the popup menu, I would like to get the calling component. Is that possible?
Background:
It is a bigger project, every form has a "BasicForm" I can inherited from. So I would like to provide a "default popup menu" for grids that have stuff like Copy, Select, and so on in it. In the inherited form I only match the grid (if exists) with that popup and I'm done.
Seems you are looking for the PopupComponent property of TPopupMenu:
Vcl.Menus.TPopupMenu.PopupComponent
Indicates the component that last displayed the popup menu in response
to a right mouse click.
Read PopupComponent to determine which control is currently using the
popup menu. In applications where multiple controls share the same
pop-up menu, use PopupComponent to determine which of them displayed
the menu.
Set PopupComponent to associate a control with the menu before calling
the Popup method programmatically to bring up the pop-up menu.

Dynamically Modify ActionMenuBar Items When Category is Clicked

I am creating a menu using an ActionManager and an ActionMenuBar. I want to add and subtract items from the menu when the top-level menu node is clicked but I can't find a clean way to do this. For example, I want to create a top-level menu "Windows" that hosts items corresponding to every modeless form. I can create the top-level "Windows" menu by creating a Category named Windows in the ActionManager and dragging "Windows" to the menu bar. When "Windows" is clicked I would then like to populate Items property with TActionClientItems corresponding to the application's modeless forms. I do know the mechanics of dynamically adding action clients at runtime (for example, in the form's oncreate event) but I can't find an action that fires when a Category (in this case, "Windows") is clicked.
I could work around this by updating the menu whenever a form is hidden or shown, but this seems inelegant compared to updating the menu on demand. I tried attaching an action to the "Windows" actionclientitem but the action's onexecute doesn't fire (apparently because it is a Category).
The failure of the onexecute handler to be called can be demonstrated with the following steps:
In Actionmanager create action named "Action1" and assigned its
category property to "Windows".
Drag the "Windows" category to
the menubar.
Create an action named WindowAction and assigned no
category to it.
Add "Showmessage('x');" to the OnExecute of
WindowAction.
In designer click on ActionManager1->ActionBars->0->Items-."0-Windows" (which is TActionClients[0]). Set TActionClients[0].Action := WindowAction.
Correct the caption of TActionClients[0] so that it is again "Windows".
Run program, click "Windows" on menu and showmessage not shown.

prevent popup menu of parent control from showing

I assigned a popup menu to the TPageControl because I want to display it when I rightclick a tab.
So that works...
Unfortunately it also shows the popup menu when I right-click within the actual tab sheet.
This I do not want because my ListBox1 in the tab sheet responds to a right-click to execute some code.
So right now it's a mess, the code fires upon rightclick of the listbox but also then displays a popup menu.
How can I nullify this popup menu in the tabsheet or at least within the listbox itself?
ok, Handled := True; was all that was needed in the popup event of the listbox. Thanks Rufo for pointing me in the right direction.

FireMonkey: how to suppress default popup menu

I've got a TMemo with an associated TPopupMenu on a FireMonkey form.
When I rightclick on the memo, I get my own popup menu, but after my popup disappears I still get the default popup (the one that says cut, copy, paste, select all).
How do I disable the default menu, or can I add my own items to the default menu perhaps?
I can't reproduce this behavior. Here's what I tried:
File->New->FireMonkey HD Application
Drop a TMemo and TPopupMenu on the form
Assign PopupMenu to Memo1.PopupMenu in the Object Inspector
Create two menu items in the PopupMenu, and assign them both the same OnClick event (generated in the Object Inspector). I left the default caption of MenuItem1 and MenuItem2 in the Caption of both items.
Wrote a simple MessageDlg that displays TMenuItem(Sender).Caption with a single Ok button in the OnClick handler.
Run the application, right-click Memo1, and choose either menu item
I get a single menu displayed with my two items (MenuItem1 and MenuItem2). Choosing either item displays the appropriate Caption in a message dialog, and clicking Ok in that dialog. There is no default popup menu displayed.
EDIT: Found it for you. This is a bug fixed in Update 3 - see the list of bug fixes in Update 3, and search for 98705, or scroll through until you reach the section on FireMonkey\Components (it's the second or third entry under that section).

How can I make a menu stay visible after it's clicked?

I'm using Delphi. I have my popup menu ready, and in a submenu I want to click, but I don't want the popup menu to disappear. I want to click and make it stay.
Easy one, disable the item. < g >
Joke aside, not an easy task.
If you want the popup menu to act like a top-most form (that is you can both interact with the items and with controls on your form without deactivating the menu), forget it, it cannot be done with a standard menu.
But if your requirement is as exactly as stated in your question (click an item, and the menu is not closed - click outside and it is closed), with some work, it would be possible.
Your aim would be to subclass the window that your submenu will reside in to override some message handling. First, derive a new class from 'TPopupList' and override its 'WndProc'. Here is an example doing this.
If you intend to prevent the closing of the menu by selecting root items then in PopupList's WndProc you'd handle WM_ENTERIDLE and get the popup menu's window handle from the message's lParam and subclass the popup menu's window.
If you only intend to prevent the closing of the menu by selecting submenu items, then in PopupList's WndProc you'd watch for WM_INITMENUPOPUP messages where the wParam is "not" the handle of the PopupMenu itself, that would mean a submenu is about to be shown. Only then you'd handle WM_ENTERIDLE and get the window handle that the submenu resides in and subclass that window.
After subclassing the window that the popup menu or the popup submenu resides in, you'd intercept an undocumented 'MN_BUTTONDOWN' ($01ED) message and prevent further handling (not call the original window procedure). Probably you'd also want to prevent closing of the menu with the keyboard; you'd watch for WM_KEYDOWN (Enter) and WM_CHAR (accelerator) messages.
Well, would take some work I guess.
I don't know how can you do that but TAdvStickyPopupMenu component (TMS software) can do this.

Resources