delphi - 为什么我的 TFrame "seeing"不是已发布的消息?

标签 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,该框架用于一个简单的主窗体,该主窗体仅包含该框架和一个关闭按钮。

我错过了什么?

最佳答案

我看到两种可能性:

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

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

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

关于delphi - 为什么我的 TFrame "seeing"不是已发布的消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5755747/

相关文章:

asp.net - 如何使用 asp.net 处理程序设置 html 正文背景图像?

java - 如何按条件唤醒线程

delphi - 如何设置与 TEdit 控件关联的可访问名称?

Delphi 网格每行具有不同的数据类型,动态显示

delphi - 如何使用 CCR EXIF 获取拍摄图像的日期/时间?

ios - 类似于 iPhone 消息应用程序的消息分组

Django 消息仅在下一个请求时显示

c++ - C++ 中 protobuf 消息的长度前缀

Delphi - 检测 Int64 溢出错误

android - 让一个 Activity 根据另一个 Activity 的结果运行一些代码