5

我有 MainMenu 的表单,我想在用户从菜单中选择命令项时进行拦截。这适用于德尔福:

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 在主窗体出现之前停止了很多次。Lazarus 从未在这个断点上停下来。我认为 Lazarus 中的 WM_COMMAND 有问题,但也许我不知道。任何的想法?

我在 WinXP 上使用 Lazarus 0.9.28.2 beta 和 FPC 2.2.4。

编辑:

使用 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

4

1 回答 1

2

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

  • 应用
  • 拼箱
  • Widget set Interface (eg win32/win64, qt, gtk2, carbon)
  • 小部件集

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

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

于 2010-01-15T12:36:38.420 回答