Lazarus/FPC 上的 WM_COMMAND 问题
-
20-09-2019 - |
题
我有 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处理程序!当我设置断点时 TForm1.WMCommand
然后,在德尔菲(Delphi)中,德尔菲(Delphi)停了很多次,然后才出现主形式。拉撒路从未停止过这个断点。我认为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
我认为 Lazarus/FPC 中的 WM_COMMAND 消息方法处理存在错误,我报告了它: http://bugs.freepascal.org/view.php?id=15521
解决方案
在 LCL 应用程序中,您具有以下层:
- 应用
- 拼箱
- 小部件集接口(例如win32/win64、qt、gtk2、碳)
- 小工具集
WM_COMMAND 是一个从 widgetset 层到 Widget Set 接口层的 winapi 消息。这些消息不会传递到更高层,考虑到可移植性,其他小部件集不会产生此类消息。
如果您想捕获消息,则必须编写不可移植的 widgetset 特定代码(在本例中为 winapi 代码)。您可以使用 setwindowlong 覆盖 windowproc。请参阅 拉撒路维基 举个例子。
不隶属于 StackOverflow