Delphi 为什么不是';“我的t框架”;“看见”;一条留言?

Delphi 为什么不是';“我的t框架”;“看见”;一条留言?,delphi,message,handler,postmessage,tframe,Delphi,Message,Handler,Postmessage,Tframe,我最近才开始大量使用TFrame(好的,是的,我一直生活在岩石下…)。我认为框架支持MessageHander方法声明——我已经看到了很多这样的例子。那么,为什么TFrame的这个简单测试单元从未看到它向自身发布的消息呢?(当我发现我的大型应用程序中没有调用消息处理程序时,我创建了测试。) 此框架仅包含一个TPanel,该框架用于仅包含框架和关闭按钮的简单mainform 我遗漏了什么?对此,我能给出的唯一解释是,在发布消息之后,在消息队列被压缩之前,会重新创建帧的句柄。尝试在网上发布。我发现有

我最近才开始大量使用TFrame(好的,是的,我一直生活在岩石下…)。我认为框架支持MessageHander方法声明——我已经看到了很多这样的例子。那么,为什么TFrame的这个简单测试单元从未看到它向自身发布的消息呢?(当我发现我的大型应用程序中没有调用消息处理程序时,我创建了测试。)

此框架仅包含一个TPanel,该框架用于仅包含框架和关闭按钮的简单mainform


我遗漏了什么?

对此,我能给出的唯一解释是,在发布消息之后,在消息队列被压缩之前,会重新创建帧的句柄。尝试在网上发布。

我发现有两种可能性:

  • 您的程序尚未开始处理消息。仅当程序调用
    GetMessage
    PeekMessage
    然后调用
    DispatchMessage
    时,才会处理已发布的消息。这发生在
    应用程序中。请运行
    ,这样,如果您的程序尚未到达,则它将不会处理任何已发布的消息

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


  • 要解决第一个问题,请稍候。您的程序最终将开始处理消息。要解决第二个问题,请覆盖帧的
    CreateWnd
    方法并将消息发布到那里。该方法在创建窗口句柄后被调用,因此可以避免过早地强制创建句柄。尽管如此,句柄仍有可能被销毁和重新创建,并且每次发生这种情况时都会调用
    CreateWnd
    ,因此您需要小心,因为初始化消息可能会被发布多次(但决不能多次发布到同一窗口句柄)。这是否正确取决于你需要做什么样的初始化。

    Rob-你的第二个可能性是发生了什么;重写
    CreateWnd
    成功了。谢谢。大卫-你和罗布都发现了基本问题-谢谢。罗布的回答被认为是第一个+更准确的答案。你应该选择简洁的答案!;-)我的不是第一个。42秒后就来了。@Rob-我想我也需要温习一下如何保持时间。。。“谢谢你们两位!”顺便说一句,你们现在有了投票的特权
    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.