Почему мой TFrame "не видит" опубликованное сообщение? - PullRequest
8 голосов
/ 22 апреля 2011

Я только недавно начал активно использовать TFrames (хорошо, да, я жил под скалой ...).Я думал, что фреймы поддерживают декларацию метода задержанных сообщений - и я видел много примеров этого.Так почему же этот простой тестовый модуль для 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 ]

8 голосов
/ 22 апреля 2011

Я вижу две возможности:

  1. Ваша программа еще не начала обрабатывать сообщения.Отправленные сообщения обрабатываются только тогда, когда ваша программа вызывает GetMessage или PeekMessage, а затем DispatchMessage.Это происходит внутри Application.Run, поэтому, если ваша программа еще не попала туда, она не будет обрабатывать отправленные сообщения.

  2. Дескриптор окна вашего фрейма был уничтожен и повторносоздано.Доступ к свойству Handle заставляет создать дескриптор окна фрейма, но если родительский фрейм еще не совсем стабилизировался, то он может уничтожить свой собственный дескриптор окна и воссоздать его.Это заставляет всех его дочерних элементов делать то же самое, поэтому дескриптор, который вы опубликовали сообщение, не существует к тому времени, когда ваша программа начинает обрабатывать сообщения.

Чтобы исправить первую проблему, простоПодождите.Ваша программа начнет обрабатывать сообщения в конце концов.Чтобы решить вторую проблему, переопределите метод CreateWnd вашего фрейма и опубликуйте сообщение там.Этот метод вызывается после того, как дескриптор окна был создан, поэтому вы избегаете принудительного создания дескриптора преждевременно.Тем не менее, дескриптор все еще может быть уничтожен и воссоздан, и CreateWnd будет называться каждый раз, когда это происходит, поэтому вам нужно быть осторожным, так как ваше сообщение инициализации может быть опубликовано большечем один раз (но никогда не обрабатывать одно и то же окно несколько раз).Правильно ли это, зависит от того, какую инициализацию вам нужно сделать.

3 голосов
/ 22 апреля 2011

Единственное объяснение этому, которое я могу придумать, заключается в том, что дескриптор вашего фрейма воссоздается после того, как вы публикуете сообщение и до того, как очередь сообщений прокачана.Попробуйте опубликовать в OnShow.

...