为什么我的 TFrame 没有“看到”已发布的消息?

发布于 2024-11-02 17:50:49 字数 891 浏览 1 评论 0原文

我最近刚刚开始大量使用 TFrame(好吧,是的,我一直生活在岩石下......)。我认为框架支持消息处理方法声明——而且我见过很多这样的例子。那么为什么这个简单的 TFrame 测试单元永远看不到它发送给自身的消息呢? (当我发现在我的大型应用程序中没有调用消息处理程序时,我创建了测试。)

unit JunkFrame;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

const
  DO_FORM_INITS = WM_USER + 99;

type
  TFrame1 = class(TFrame)
    Panel1: TPanel;
  private
    procedure DoFormInits(var Msg: TMessage); message DO_FORM_INITS;
  public
    constructor Create(AOwner: TComponent); override;
  end;

implementation

{$R *.dfm}

constructor TFrame1.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  PostMessage(self.Handle, DO_FORM_INITS, 0, 0);
end;

procedure TFrame1.DoFormInits(var Msg: TMessage);
begin
  ShowMessage('In DoFormInits!');
end;

end.

该框架仅包含一个 TPanel,并且该框架用于一个简单的主窗体,该主窗体仅包含该框架和一个关闭按钮。

我缺少什么?

I just recently begun using TFrames heavily (OK, yes, I've been living under a rock...). I thought frames supported Message hander method declaration--and I've seen many examples of that. So why does this simple test unit for a TFrame never see the message it posts to itself? (I created the test when I figured out that message handlers weren't being called in my larger application.)

unit JunkFrame;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

const
  DO_FORM_INITS = WM_USER + 99;

type
  TFrame1 = class(TFrame)
    Panel1: TPanel;
  private
    procedure DoFormInits(var Msg: TMessage); message DO_FORM_INITS;
  public
    constructor Create(AOwner: TComponent); override;
  end;

implementation

{$R *.dfm}

constructor TFrame1.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  PostMessage(self.Handle, DO_FORM_INITS, 0, 0);
end;

procedure TFrame1.DoFormInits(var Msg: TMessage);
begin
  ShowMessage('In DoFormInits!');
end;

end.

This frame only contains a TPanel, and the frame is used on a simple mainform which contains only the frame and a Close button.

What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

牵你手 2024-11-09 17:50:49

我看到两种可能性:

  1. 您的程序尚未开始处理消息。仅当您的程序调用 GetMessagePeekMessage,然后调用 DispatchMessage 时,才会处理已发布的消息。这发生在 Application.Run 内部,因此如果您的程序尚未到达那里,那么它不会处理任何已发布的消息。

  2. 您的框架的窗口句柄已被销毁并重新创建。访问 Handle 属性会强制创建框架的窗口句柄,但如果框架的父级尚未完全稳定,则它可能会销毁自己的窗口句柄并重新创建它。这会强制它的所有子级执行相同的操作,因此当您的程序开始处理消息时,您发布消息的句柄并不存在。

要解决第一个问题,只需等待。您的程序最终将开始处理消息。要解决第二个问题,请重写框架的 CreateWnd 方法并在其中发布消息。该方法在创建窗口句柄后被调用,因此您可以避免强制过早创建句柄。不过,句柄仍然有可能被销毁并重新创建,每次发生这种情况时都会调用 CreateWnd,因此您需要小心,因为您的初始化消息可能会多次发布(但绝不会多次发布到同一窗口句柄)。这是否正确取决于您需要执行哪种初始化。

I see two possibilities:

  1. Your program hasn't started processing messages yet. Posted messages are only processed when your program calls GetMessage or PeekMessage and then DispatchMessage. That occurs inside Application.Run, so if your program hasn't gotten there yet, then it won't process any posted messages.

  2. Your frame's window handle has been destroyed and re-created. Accessing the Handle property forces the frame's window handle to be created, but if the frame's parent hasn't quite stabilized yet, then it might destroy its own window handle and re-create it. That forces all its children to do the same, so the handle you posted the message to doesn't exist by the time your program starts processing messages.

To fix the first problem, just wait. Your program will start processing messages eventually. To fix the second problem, override your frame's CreateWnd method and post the message there. That method gets called after the window handle has been created, so you avoid forcing the handle to be created prematurely. It's still possible for the handle to be destroyed and re-created, though, and CreateWnd will be called each time that happens, so you'll need to be careful since your initialization message might be posted more than once (but never to the same window handle multiple times). Whether that's correct depends on what kind of initialzation you need to do.

灯角 2024-11-09 17:50:49

我能想到的唯一解释是,在发布消息之后和泵送消息队列之前,会重新创建框架的句柄。尝试在 OnShow 中发帖。

The only explanation for this that I can come up with is that your frame's handle is recreated after you post the message and before the message queue is pumped. Try posting in an OnShow.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文