如何禁用菜单项并停止 ActionMainMenuBar 中的下拉菜单?
How to disable menuitem and stop dropdown in ActionMainMenuBar?
Delphi 10.4.2
我的 TActionMainMenuBar 有问题。当我在代码中禁用一个菜单项时,它显示为禁用,但如果我下拉它旁边的一个启用的菜单项,然后移动到禁用的菜单项,它的子菜单就会下拉!
如果这不是错误,是否有办法防止禁用的菜单项掉落?
谢谢
托尼
一个简单的解决方案是在禁用项目时关闭 TActionMainMenuBar.OnPopup
事件中的菜单:
procedure TForm1.ActionMainMenuBar1Popup(Sender: TObject; Item: TCustomActionControl);
begin
if not Item.Enabled then
ActionMainMenuBar1.CloseMenu;
end;
但是我不推荐这样做,因为它也会退出菜单循环,这可能会导致糟糕的用户体验。
您描述的行为可以被视为缺陷,您可以 report it to Embarcadero. To fix that in your code you should override method CreatePopup
of TActionMainMenuBar
to prevent creating popup menus (return nil
) for disabled items. But returning nil
in that method will cause another problem (access violation) when opening submenu using ↑ or ↓ on keyboard. Therefore you should handle that case too by patching WMKeyDown
. Ideally you should derive your own class from TActionMainMenuBar
or use an interposer class:
type
TActionMainMenuBar = class(Vcl.ActnMenus.TActionMainMenuBar)
private
procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN;
protected
function CreatePopup(AOwner: TCustomActionMenuBar;
Item: TCustomActionControl): TCustomActionPopupMenu; override;
end;
{ ... }
function TActionMainMenuBar.CreatePopup(AOwner: TCustomActionMenuBar;
Item: TCustomActionControl): TCustomActionPopupMenu;
begin
if Item.Enabled then
Result := inherited CreatePopup(AOwner, Item)
else
Result := nil;
end;
procedure TActionMainMenuBar.WMKeyDown(var Message: TWMKeyDown);
begin
if Assigned(Selected) and (not Selected.Control.Enabled) and
(Orientation in [boLeftToRight, boRightToLeft]) and
(Message.CharCode in [VK_UP, VK_DOWN]) then
Exit; { do not try to popup disabled items }
inherited;
end;
Delphi 10.4.2 我的 TActionMainMenuBar 有问题。当我在代码中禁用一个菜单项时,它显示为禁用,但如果我下拉它旁边的一个启用的菜单项,然后移动到禁用的菜单项,它的子菜单就会下拉! 如果这不是错误,是否有办法防止禁用的菜单项掉落?
谢谢 托尼
一个简单的解决方案是在禁用项目时关闭 TActionMainMenuBar.OnPopup
事件中的菜单:
procedure TForm1.ActionMainMenuBar1Popup(Sender: TObject; Item: TCustomActionControl);
begin
if not Item.Enabled then
ActionMainMenuBar1.CloseMenu;
end;
但是我不推荐这样做,因为它也会退出菜单循环,这可能会导致糟糕的用户体验。
您描述的行为可以被视为缺陷,您可以 report it to Embarcadero. To fix that in your code you should override method CreatePopup
of TActionMainMenuBar
to prevent creating popup menus (return nil
) for disabled items. But returning nil
in that method will cause another problem (access violation) when opening submenu using ↑ or ↓ on keyboard. Therefore you should handle that case too by patching WMKeyDown
. Ideally you should derive your own class from TActionMainMenuBar
or use an interposer class:
type
TActionMainMenuBar = class(Vcl.ActnMenus.TActionMainMenuBar)
private
procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN;
protected
function CreatePopup(AOwner: TCustomActionMenuBar;
Item: TCustomActionControl): TCustomActionPopupMenu; override;
end;
{ ... }
function TActionMainMenuBar.CreatePopup(AOwner: TCustomActionMenuBar;
Item: TCustomActionControl): TCustomActionPopupMenu;
begin
if Item.Enabled then
Result := inherited CreatePopup(AOwner, Item)
else
Result := nil;
end;
procedure TActionMainMenuBar.WMKeyDown(var Message: TWMKeyDown);
begin
if Assigned(Selected) and (not Selected.Control.Enabled) and
(Orientation in [boLeftToRight, boRightToLeft]) and
(Message.CharCode in [VK_UP, VK_DOWN]) then
Exit; { do not try to popup disabled items }
inherited;
end;