【问题标题】:Why isn't my TFrame "seeing" a posted message?为什么我的 TFrame 没有“看到”已发布的消息?
【发布时间】:2011-08-10 23:25:18
【问题描述】:

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

我错过了什么?

【问题讨论】:

    标签: delphi message handler postmessage tframe


    【解决方案1】:

    我看到了两种可能性:

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

    2. 框架的窗口句柄已被销毁并重新创建。访问Handle 属性会强制创建框架的窗口句柄,但如果框架的父级还没有完全稳定,那么它可能会破坏自己的窗口句柄并重新创建它。这会强制它的所有子级都这样做,因此在您的程序开始处理消息时,您向其发布消息的句柄并不存在。

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

    【讨论】:

    • Rob - 你的第二个可能性是发生了什么;覆盖CreateWnd 成功了。谢谢。
    【解决方案2】:

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

    【讨论】:

    • David - 你和 Rob 都发现了根本问题 - 谢谢。 Rob 的回答被接受为第一个 + 更准确地发现了。
    • 你应该选择简洁的! ;-)
    • 我的不是第一个。 42 秒后。
    • @Rob - 我想我也需要重新了解如何保持时间......谢谢你们俩。
    • @mark 顺便说一句,你现在有投票的特权了
    猜你喜欢
    • 2012-11-06
    • 1970-01-01
    • 2012-05-01
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 2017-07-08
    相关资源
    最近更新 更多