Вопрос, который возник у пользователя Tony, связан с нежелательным поведением компонента TActionMainMenuBar в среде разработки Delphi 10.4.2. При отключении пункта меню в коде, хотя он и отображается как неактивный, при выборе соседнего активного пункта и последующем перемещении курсора на отключенный пункт, его подменю все равно отображается. Пользователь ищет способ предотвратить это поведение.
Описание проблемы
В Delphi 10.4.2 при использовании компонента TActionMainMenuBar происходит ситуация, когда отключенный пункт меню все еще может отображать подменю при определенных условиях. Это может быть связано с ошибкой в компоненте или с особенностями его работы, требующими специфического подхода в программировании.
Альтернативный ответ
Попытки решения проблемы путем изменения видимости дочерних элементов пункта меню не привели к успеху. Однако, были предложения, которые заслуживают внимания.
Подтвержденный ответ
Пользователю предложили использовать событие OnPopup компонента TActionMainMenuBar, чтобы закрыть меню, если пункт меню отключен. Однако, такой подход может привести к нежелательному выходу из цикла меню, что может ухудшить пользовательский опыт.
В качестве решения, рекомендуется переопределить метод CreatePopup компонента TActionMainMenuBar, чтобы предотвратить создание подменю для отключенных пунктов. Однако, это может вызвать другую проблему с доступом к памяти при попытке открыть подменю с помощью клавиш управления курсором. Следовательно, необходимо также обработать этот случай, перехватив сообщение WM_KEYDOWN.
Идеальным решением будет создание собственного класса, наследуемого от TActionMainMenuBar, или использование класса-посредника (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; { не пытаться открыть отключенные пункты }
inherited;
end;
Пользователь Tony применил предложенное решение, создав класс-посредник, и это устранило проблему с отображением подменю для отключенных пунктов.
Заключение
Проблема, с которой столкнулся пользователь в Delphi 10.4.2, связана с неправильным поведением компонента TActionMainMenuBar. Решением стало изменение логики создания подменю и обработки клавиш управления курсором. Создание собственного класса или использование класса-посредника позволило корректно обрабатывать отключенные пункты меню и предотвратить отображение подменю в таких случаях.
Пользователь столкнулся с проблемой отображения подменю в компоненте `TActionMainMenuBar` в среде Delphi 10.4.2, даже если соответствующий пункт меню отключен, и ищет способ предотвратить это поведение.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.