Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Проблема выделения элементов всплывающего меню в интерфейсе на Delphi

Delphi , Компоненты и Классы , Меню

При разработке интерфейсов на Delphi иногда возникает необходимость программно выделить определенные элементы всплывающего меню без их клика. Вопрос, который часто встречается среди разработчиков, заключается в том, как можно выделить конкретный элемент всплывающего меню (TPopupMenu), не совершая при этом его активацию.

Описание проблемы

Разработчик столкнулся с задачей выделения определенного элемента меню после его отображения с помощью метода Popup. Попытка использовать функцию Winapi.Windows.HiliteMenuItem не увенчалась успехом, так как всплывающее меню (TPopupMenu) отличается от меню бара (TMenu).

Пример кода всплывающего меню

object pmTest: TPopupMenu
  OnPopup = pmTestPopup
  Left = 32
  Top = 24
  object mTest1: TMenuItem
    Caption = 'Test 1'
    OnClick = mTest1Click
  end
  object mTest2: TMenuItem
    Caption = 'Test 2'
    OnClick = mTest2Click
  end
end

Подтвержденное решение

По умолчанию свойство TPopupMenu.WindowHandle ссылается на окно приложения, а не на внутреннее окно (HWND), которое используется TPopupMenu для обработки сообщений WM_COMMAND. Это окно создается при вызове метода Popup(), и оно не обновляет свойство TPopupMenu.WindowHandle.

Для решения проблемы следует использовать свойство TPopupList.Window вместо TPopupMenu.WindowHandle в функции HiliteMenuItem. В unités Vcl.Menus имеется глобальный объект PopupList, который можно применить для этой цели.

procedure TMyForm.pmTestPopup(Sender: TObject);
begin
  Winapi.Windows.HiliteMenuItem(PopupList.Window, pmTest.Handle, 1, MF_BYPOSITION or MF_HILITE);
end;

Если предыдущий способ не работает, можно использовать функцию Winapi.Windows.SetMenuItemInfo, которая не требует передачи HWND.

procedure TMyForm.pmTestPopup(Sender: TObject);
var
  mii: MENUITEMINFO;
begin
  ZeroMemory(@mii, SizeOf(mii));
  mii.cbSize := SizeOf(mii);
  mii.fMask := MIIM_STATE;
  mii.fState := MFS_HILITE;

  Winapi.Windows.SetMenuItemInfoW(pmTest.Handle, 1, True, mii);
end;

Обновление: После дополнительного рассмотрения было выяснено, что событие TPopupMenu.OnPopup срабатывает до отображения меню, а TPopupMenu может пересоздать меню после вызова OnPopup и перед его фактическим отображением. В этом случае рекомендуется использовать подкласс TPopupList, чтобы перехватить сообщение WM_ENTERMENULOOP, и затем можно будет модифицировать элементы меню.

type
  TPopupListEx = class(TPopupList)
  protected
    procedure WndProc(var Message: TMessage); override;
  end;

procedure TPopupListEx.WndProc(var Message: TMessage);
begin
  inherited;
  if (Message.Msg = WM_ENTERMENULOOP) and (Message.WParam = 1) then
  begin
    // модификация элементов pmTest по необходимости...
  end;
end;

initialization
  PopupList.Free; // освобождение "стандартного", "старого" списка
  PopupList := TPopupListEx.Create; // создание нового
  // Новый PopupList будет освобожден в блоке finalization модуля Menus.
end.

Заключение

Выделение элементов всплывающего меню в интерфейсе на Delphi может быть выполнено различными способами, включая использование свойства TPopupList.Window и функции SetMenuItemInfo, а также с помощью подклассирования TPopupList для перехвата сообщений. Важно понимать, в какой момент следует выполнять эти действия, чтобы достичь желаемого результата.

Создано по материалам из источника по ссылке.

Проблема заключается в необходимости программного выделения элементов всплывающего меню в интерфейсе на Delphi без их активации.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Меню ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-02-10 19:14:34/0.0035488605499268/0