我具有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
处理程序不被调用!当我在Delphi中的TForm1.WMCommand中设置断点时,然后在Delphi中
在主要形式出现之前停止了很多次。拉撒路从未停止
在这个断点上。我认为WM_COMMAND有点问题
在拉撒路(Lazarus),但也许我一无所知。任何想法?

我在WinXP上将Fazard 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

我认为WM_COMMAND消息方法处理中的Lazarus/FPC中存在错误,我报告了此错误:http://bugs.freepascal.org/view.php?id=15521

最佳答案

在LCL应用程序中,您具有以下几层:

  • 应用程序
  • 拼箱
  • 小组件集接口(interface)(例如win32/win64,qt,gtk2,carbon)
  • 小部件设置

  • WM_COMMAND是从窗口小部件集层到窗口小部件集接口(interface)层的winapi消息。考虑到可移植性,这些消息不会传递到更高的层,其他小部件集不会产生此类消息。

    如果要捕获消息,则必须编写非便携式控件集特定的代码(在这种情况下为winapi代码)。您可以使用setwindowlong覆盖windowproc。有关示例,请参见Lazarus wiki

    10-08 14:01