【问题标题】:Custom Messages in Non-Windowed Classes - need a default handler?非窗口类中的自定义消息 - 需要默认处理程序?
【发布时间】:2012-06-10 10:53:29
【问题描述】:

我有一个类(TObject):

private
  FHwnd : HWND;
  procedure HandleMyMessage(var Message : TMessage); message TH_MYMESSAGE;

在哪里TH_MYMESSAGE = WM_USER + 1

在类构造函数中:

FHwnd := AllocateHWND(HandleMyMessage);

接收对FHwnd 的引用的唯一对象是私有自定义TThread(在此类中创建),它发布的唯一消息是TH_MYMESSAGE。我的理解是过程声明中的message 指令将其处理限制为仅TH_MYMESSAGE

这在测试中运行良好,但在集成到更大的应用程序后,我收到反馈,HandleMyMessage 也正在触发其他消息(具有明显的不良结果)。

这很容易通过在HandleMyMessage 中添加if Message.Msg <> TH_MYMESSAGE then Exit; 来纠正。我的问题是:为什么会这样?

我最好的猜测是 AllocateHWND 使 HandleMyMessage 等同于 DefWndProc 尽管它具有 message 指令。有没有正确的方法来实现我所缺少的?

【问题讨论】:

  • 你的猜测是正确的HandleMyMessage 变成WndProc 创建的非可视窗口。所以它接收所有消息;您过滤Message.Msg 的解决方案也是正确的。 message Delphi 用于默认处理 TObject.Dispatch 调用的方法修改器(在非窗口类中)
  • @teran 那么假设我确实想要一个默认的WndProc 用于其他消息,如果我在其他一些常规过程中完成了AllocateHWND,那么HandleMyMessage 将使用message 指令正确过滤?
  • @Ken 这里的 WM_USER 没问题。

标签: multithreading delphi message delphi-xe2 hwnd


【解决方案1】:

嗯,当然可以。 AllocateHWnd 接受TWndMethod 作为创建窗口的窗口过程。我猜,这种混乱是因为编译器接受了messsage 指令。别说:

private
  FHwnd : HWND;
  procedure HandleMyMessage(var Message : TMessage);

..

procedure TMyClass.HandleMyMessage(var Message: TMessage);
begin
  case Message.Msg of
    TH_MYMESSAGE: //
  end;
  Message.Result := DefWindowProc(FHWnd, Message.Msg, Message.WParam, Message.LParam);
end;


编辑:(对评论的回应)。要在创建实用程序窗口的类上处理消息,您可以将消息从 AllocateHWnd 创建的窗口路由到您的类:
private
  FHwnd : HWND;
  procedure HandleMyMessage(var Message : TMessage);
  procedure THMyMessage(var Message: TMessage); message TH_MYMESSAGE;

..

procedure TMyClass.HandleMyMessage(var Message: TMessage);
begin
  case Message.Msg of
    TH_MYMESSAGE: Dispatch(Message);
  end;
  Message.Result := DefWindowProc(FHWnd, Message.Msg, Message.WParam, Message.LParam);
end;

procedure TMyClass.THMyMessage(var Message: TMessage);
begin
  //
end;

【讨论】:

  • AllocateHwnd 是否创建一个接收广播的窗口?对于这样的事情,我会寻找一个只有消息的窗口,HWND_MESSAGE。
  • 这是有道理的。问题的第二部分:是否可以在同一个类中定义另一个使用message 指令来引导特定消息远离主处理程序的过程?
  • @David - 当然,但是使用 AllocateHWnd 容易得多。我的系统在任何给定时间都充满了“TPUtilWindow”。
  • TObject.DefaultHandler 会做我猜的路由,但除非你有很多消息,否则它是矫枉过正的。
  • 不,我记错了,Dispatch 做路由。 @Sertac 为什么不总是调用 Dispatch?为什么会这样?在 DefaultHandler 中提取未处理的消息。
猜你喜欢
  • 2011-05-19
  • 1970-01-01
  • 2010-11-24
  • 2014-05-25
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 2012-04-13
相关资源
最近更新 更多