Lazarus/FPC中的WM_COMMAND问题

5

我有一个带有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;

在主菜单中,我添加了一些项,当我从菜单中选择这些项时,我的Memo1会被填充:
WMCommand 2
WMCommand 3
WMCommand 3
WMCommand 2
WMCommand 5
...

我将此应用程序移植到FPC/Lazarus,但似乎WM_COMMAND处理程序没有被调用!当我在Delphi中设置断点时,在主窗体出现之前,Delphi停止了很多次。Lazarus从未停止在这个断点上。我认为Lazarus的WM_COMMAND可能有问题,但也许我不知道某些东西。有任何想法吗?
我使用带有WinXP的FPC 2.2.4的Lazarus 0.9.28.2 beta。
编辑:
使用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

1个回答

2
在LCL应用程序中,您有以下层:
  • 应用程序
  • LCL
  • 部件集接口(例如win32/win64、qt、gtk2、carbon)
  • 部件集

WM_COMMAND是从部件集层到部件集接口层的winapi消息。为了实现可移植性,这些消息不会传递到更高的层,因为其他部件集不会产生这样的消息。

如果您想捕获消息,则必须编写非可移植的部件集特定代码(在本例中为winapi代码)。您可以使用setwindowlong覆盖windowproc。请参阅Lazarus wiki中的示例。


LM_COMMAND和CN_COMMAND也无法工作,即在可移植事件级别上捕获事件也不可能,这难道不可能是一个错误/缺失的功能吗? - Marco van de Voort

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接