Why isn't my TFrame "seeing" a posted message?
Asked Answered
S

2

9

I just recently begun using TFrames heavily (OK, yes, I've been living under a rock...). I thought frames supported Message hander method declaration--and I've seen many examples of that. So why does this simple test unit for a TFrame never see the message it posts to itself? (I created the test when I figured out that message handlers weren't being called in my larger application.)

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.

This frame only contains a TPanel, and the frame is used on a simple mainform which contains only the frame and a Close button.

What am I missing?

Spotty answered 22/4, 2011 at 13:8 Comment(0)
D
9

I see two possibilities:

  1. Your program hasn't started processing messages yet. Posted messages are only processed when your program calls GetMessage or PeekMessage and then DispatchMessage. That occurs inside Application.Run, so if your program hasn't gotten there yet, then it won't process any posted messages.

  2. Your frame's window handle has been destroyed and re-created. Accessing the Handle property forces the frame's window handle to be created, but if the frame's parent hasn't quite stabilized yet, then it might destroy its own window handle and re-create it. That forces all its children to do the same, so the handle you posted the message to doesn't exist by the time your program starts processing messages.

To fix the first problem, just wait. Your program will start processing messages eventually. To fix the second problem, override your frame's CreateWnd method and post the message there. That method gets called after the window handle has been created, so you avoid forcing the handle to be created prematurely. It's still possible for the handle to be destroyed and re-created, though, and CreateWnd will be called each time that happens, so you'll need to be careful since your initialization message might be posted more than once (but never to the same window handle multiple times). Whether that's correct depends on what kind of initialzation you need to do.

Dad answered 22/4, 2011 at 13:16 Comment(1)
Rob - Your second posibility was what was happening; overriding CreateWnd did the trick. Thanks.Spotty
L
3

The only explanation for this that I can come up with is that your frame's handle is recreated after you post the message and before the message queue is pumped. Try posting in an OnShow.

Lagos answered 22/4, 2011 at 13:16 Comment(8)
David - You and Rob both identified the base problem - thanks. Rob's answer gets accepted for being first + more precisely spot on.Spotty
You should have gone for the concise one! ;-)Lagos
Mine wasn't first. It came 42 seconds later.Dad
@Rob - Guess I need to brush up on how to keep time as well... Thanks to you both.Spotty
@mark by the way, you now have the privilege that you can voteLagos
You can always vote on answers to your own questions, can't you, David? I thought it was the same as the commenting rule.Dad
@rob I'm not sure. You are probably right though. You usually are!Lagos
David & @Rob ...I did vote: I selected Rob's answer (the checkmark) and also up-voted it. I think Rob's right: regardless of how few reputation points one has, it's always possible to vote on answers to your own questions.Spotty

© 2022 - 2024 — McMap. All rights reserved.