Is it possible for a menu item to receive an OnClick event, even if it is not enabled?

I am trying to allow the administrator to enable / disable menu items in the main menu of my application by pressing Ctrl + Click. To do this, I introduced the TMenuItem class in my main form using a special version and redefined the virtual Click method, for example:

uses Forms, Menus; type TMenuItem = class(Menus.TMenuItem) public ControlActivationState: Boolean; procedure Click; override; end; TMyMainForm = class(TForm) ... procedure TMenuItem.Click; begin if ControlActivationState and IsKeyPressed(VK_CONTROL) then Self.Enabled := not Self.Enabled else inherited; end; 

This works, but only for the top-level menu. Why do top-level menu items receive OnClick events even if they are disabled and other menu items are not displayed? Is there a way to make child menu items also receive these events?

+4
source share
3 answers

The OnClick top-level OnClick fired when a WM_INITMENUPOPUP message is WM_INITMENUPOPUP . This message is sent even if the top-level item is disabled. I am not sure why it is posted in this scenario, but it is. The same is true for a subitem that has children.

However, for a subtitle without children, OnClick triggered by the WM_COMMAND message. But the system does not even send a message if the menu item is disabled.

What you are trying to do cannot be easily accomplished. The only way I see you doing this is to handle the raw mouse and keyboard events. Personally, I would not think about that.

+4
source

TMenuItem is a TComponent, i.e. It is not a window control and does not have classic events. Instead, click events that occur in the real window control are delegated to the TMenuItem instance. I do not know which window control is the real host for events, but even if I did, it would be difficult for me to determine which TMenuItem corresponds to the actual click point.

My advice is to make a highlighted window for editing the menu using the tree control, which generally fills its elements at runtime based on the actual layout of the menu, and then provides on / off options for tree nodes that reflect the corresponding menu items. Then you can save / load menuitem list etc. It should be much cleaner and easier than diving into the muddy depths of VCL and computing (and redefining) how events propagate from "real" controls to design-time representations called TComponent s ...

+2
source

In fact, you are trying to do this hard ...

An easy solution to your problem would be to override the OnDrawItem() method of your TMenuItem to display it as if it were disabled, and handle the OnClick event alternatively.

(Remember to set the .OwnerDraw property on the menu for this solution to work.)

Edit:

According to Delphi's help, using the OnAdvancedDrawItem event makes it easier as it provides information about the menu itself.

0
source

Source: https://habr.com/ru/post/1495741/


All Articles