Проблема с WM_COMMAND на Lazarus / FPC

У меня есть форма с MainMenu, и я хочу перехватить, когда пользователь выбирает пункт команды из меню. Это работает в Delphi:

type
  TForm1 = class(TForm)
    ... // Memo and MainMenu created
  protected
    procedure WMCommand(var Info: TWMCommand); message WM_COMMAND;
  end;


procedure TForm1.WMCommand(var Info: TWMCommand);
begin
  if (Info.ItemID < 10) then
    Memo1.Lines.Add('WMCommand ' + IntToStr(Info.ItemID));
end;

В MainMenu я добавил несколько элементов, и когда я выбираю эти элементы из меню, мой Memo1 заполняется:

WMCommand 2
WMCommand 3
WMCommand 3
WMCommand 2
WMCommand 5
...

Я портировал это приложение на FPC / Lazarus, но похоже, что обработчик WM_COMMAND не вызывается! Когда я установил точку останова в TForm1.WMCommand в Delphi, Delphi останавливался много раз до появления основной формы. Lazarus никогда не останавливался на этой точке останова. Я думаю, что что-то не работает с WM_COMMAND в Lazarus, но, возможно, я чего-то не знаю. Любая идея?

Я использую бета-версию Lazarus 0.9.28.2 с FPC 2.2.4 на WinXP.

РЕДАКТИРОВАТЬ:

Используя Winspector, я проверил, что MainMenu генерирует WM_COMMAND:

WM_COMMAND
    Code: 0
    Control ID: 2
    Control HWND: 0x00000000
    Message Posted
    Time: 09:37:14.0968

Я думаю, что есть ошибка в Lazarus / FPC при обработке метода сообщений WM_COMMAND, и я сообщил об этом: http://bugs.freepascal.org/view.php?id=15521


person Michał Niklas    schedule 12.01.2010    source источник


Ответы (1)


В приложении LCL у вас есть следующие уровни:

  • Применение
  • LCL
  • Интерфейс набора виджетов (например, win32 / win64, qt, gtk2, carbon)
  • Набор виджетов

WM_COMMAND - это сообщение winapi от уровня набора виджетов к уровню интерфейса набора виджетов. Эти сообщения не передаются на более высокие уровни, имея в виду переносимость, другие наборы виджетов не создают такие сообщения.

Если вы хотите перехватить сообщение, вы должны написать непереносимый код, специфичный для набора виджетов (в данном случае код winapi). Вы можете переопределить windowproc с помощью setwindowlong. См. Пример в Lazarus wiki.

person Vincent Snijders    schedule 15.01.2010
comment
Разве это не ошибка / отсутствующая функция, что LM_COMMAND и CN_COMMAND также не работают, iow также невозможен захват события на переносимом уровне? - person Marco van de Voort; 16.01.2010