可以在类过程中使用消息吗?

ped*_*pio 0 delphi delphi-7

我想messages在我的程序中使用,我有一个问题:我可以在一个中使用消息,class procedure还是可以messagesprocedure没有的情况下使用class

这是我的代码:

const

  WM_CUSTOM_TCP_CLIENT = WM_USER + 10;

type
    TFeedbackEvent = class
      public
        class procedure feedback(var msg: TMessage); message WM_CUSTOM_TCP_CLIENT;
      end;
Run Code Online (Sandbox Code Playgroud)

Delphi返回以下消息:

[Error] unit.pas(33): Invalid message parameter list
Run Code Online (Sandbox Code Playgroud)

非常感谢你.

qua*_*oft 9

关于这个主题有一篇非常好的文章:在Delphi 6中处理消息.这是必读的.

处理或处理消息意味着您的应用程序以某种方式响应Windows消息.在标准Windows应用程序中,在每个窗口过程中执行消息处理.

但是,通过内化窗口过程,Delphi可以更轻松地处理单个消息; 而不是有一个处理所有消息的过程,每个消息都有自己的过程.对于作为消息处理过程的过程,必须满足三个要求:

  • 该过程必须是对象的方法.

  • 该过程必须采用TMessage或其他特定于消息的记录类型的一个var参数.

  • 该过程必须使用message指令,后跟要处理的消息的常量值.

正如您在本文中所读到的,该过程必须是对象的方法,而不是类.所以你不能只在类过程中使用消息处理程序.


处理类实例(也在对象实例或无窗口应用程序中)中的消息的可能解决方法是通过AllocateHWND手动创建窗口句柄,并通过WndProc过程自己处理消息.

在delphi.about.com中有一个很好的例子:向非窗口应用程序发送消息(页面2):

以下示例是上述示例的一个版本,经过修改后可以使用类方法.(如果不是真的需要使用类方法,请使用上面链接中的原始示例):

首先,您需要声明一个窗口句柄字段和一个WndProc过程:

TFeedbackEvent = class
private
  FHandle: HWND;
protected
  class procedure ClassWndProc(var msg: TMessage); 
end;

procedure WndProc(var msg: TMessage); 
Run Code Online (Sandbox Code Playgroud)

然后,手动处理消息:

procedure WndProc(var msg: TMessage); 
begin
    TFeedbackEvent.ClassWndProc(msg);
end;

procedure TFeedbackEvent.ClassWndProc(var msg: TMessage);
begin
  if msg.Msg = WM_CUSTOM_TCP_CLIENT then
    // TODO: Handle your message
  else
    // Let default handler process other messages
    msg.Result := DefWindowProc(FHandle, msg.Msg, msg.wParam, msg.lParam);
end;
Run Code Online (Sandbox Code Playgroud)

最后,在文件的末尾,声明初始化和完成部分以创建/销毁句柄:

initialization
    FHandle := AllocateHWND(WndProc);

finalization
    DeallocateHWnd(FHandle);
Run Code Online (Sandbox Code Playgroud)

当然,这不是推荐的方法(特别注意初始化/终结的问题),这只是一个示例,表明它是可能的.

除非你有一些非常奇怪的要求使用类方法,否则最好使用常规类方法和对象构造函数和析构函数来代替初始化和终结部分(如向非窗口应用程序发送消息(页2)中所示).