2010-01-12 50 views
5

我使用MainMenu创建了窗体,并且当用户从菜单中选择一个命令项时我想拦截。 这工作在Delphi:关于Lazarus/FPC上的WM_COMMAND的问题

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 /拉撒路,但似乎没有调用WM_COMMAND 处理程序!当我在Delphi中设置TForm1.WMCommand断点时,Delphi 在主窗体出现之前停止了很多次。在这个断点处,拉撒路从未停止过 。我认为拉扎鲁斯的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 

我认为这是错误的拉撒路/ FPC在WM_COMMAND消息的方法处理我报告说,它:http://bugs.freepascal.org/view.php?id=15521

回答

2

在拼箱应用中,您有以下几层:

  • 应用程序
  • LCL
  • 控件集接口(例如,的Win32/Win64的,QT,GTK2,碳)
  • 外集件组

WM_COMMAND是从视窗元件层到外集件组界面层一个WINAPI消息。这些消息不会传递到更高层,考虑到可移植性,其他小部件集不会产生这样的消息。

如果要捕获消息,则必须编写非便携式widgetset特定代码(本例中为winapi代码)。你可以用setwindowlong覆盖windowproc。例如,请参阅Lazarus wiki

+0

是不是可能是一个错误/缺少的功能,LM_COMMAND和CN_COMMAND也无法正常工作,便携式级别的事件捕获也是不可能的? – 2010-01-16 17:53:06