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

时间:2011-04-22 13:08:59

标签: delphi message handler postmessage tframe

我最近刚刚开始大量使用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,框架用于仅包含框架和关闭按钮的简单主窗体。

我错过了什么?

2 个答案:

答案 0 :(得分:8)

我看到两种可能性:

  1. 您的程序尚未开始处理邮件。已发布的消息仅在您的程序调用{​​{1}}或GetMessage然后PeekMessage时处理。这发生在DispatchMessage内,所以如果您的程序尚未到达,那么它将不会处理任何已发布的消息。

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

  3. 要解决第一个问题,请稍等。您的程序最终将开始处理消息。要解决第二个问题,请覆盖框架的Handle方法并在此处发布消息。在创建窗口句柄后调用该方法,因此可以避免强制过早创建句柄。但是,仍然可以销毁和重新创建句柄,并且CreateWnd将被称为每个时间,因此您需要小心,因为您的初始化消息可能被发布不止一次(但永远不会在同一个窗口处理多次)。这是否正确取决于你需要做什么样的初始化。

答案 1 :(得分:3)

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