Immediate TTimer to emulate PostCreate / PostOnCreate event in Delphi

Learn how to create the equivalent of an PostCreate / PostOnCreate event that executes just after the form’s OnCreate event has fired.

To do this, we will use an “Immediate Timer”

Huh – I dont get it.
When would I want to do this ?

I have used this technique when third party code code is firing just after Form.OnCreate and I want my code to fire just after that point

A real world example

In my earlier post about getting and setting the Z order of FireMonkey controls, we hit a strange situation where FireMonkey creates a TRectangle that is owned by the form. This TRectangle is used to display the form background.  I needed to manipulate this rectangle on form startup, but it gets creates after Form OnCreate so I couldnt modify it within the OnCreate event.  As a workaround, I created an “immediate timer” that would fire just after OnCreate and after FireMonkey has done its thing.

Immediate TTimer

To implement this, we will use an “Immediate TTimer” that executed after the OnCreate event.

We normally think of TTimer as an event that fires some time in the future.  However, for this solution we will make the timer execute immediately.

Its like setting an alarm clock that will wake you up right now – that’s weird

postformcreateevent

Less Code, or Easier To Understand

There are two ways to do this.  The choice of which one to use will depend on whether you want less code and less event, or want the code to be easier to understand

Method 1) Enabled Timer

This solution is nicely self-contained as it uses just one event.

Create a timer with these properties

  • Name = PostFormCreateTimer
  • Enabled = TRUE
  • Interval = 1     must be 1 or higher otherwise the timer wont fire even when enabled

Add an OnTimer event to the timer with this code

procedure TMainForm.PostFormCreateTimerTimer(Sender: TObject);
   // This timer fires after the form's OnCreate event
begin
      // disable this timer so it doesnt fire again
  PostFormCreateTimer.Enabled := FALSE;
end;

Method 2) Disabled Timer activated in Form OnCreate

This requires two events so its more code than Method 1, but it can be easier to follow the logic when debugging because it is obvious that the timer will fire after OnCreate.

Create a timer with these properties

  • Name = PostFormCreateTimer
  • Enabled = FALSE
  • Interval = 1     must be 1 or higher otherwise the timer wont fire even when enabled

Add an OnTimer event to the timer with this code

procedure TMainForm.PostFormCreateTimerTimer(Sender: TObject);
  // This timer fires after the form's OnCreate event
begin
          // disable this timer so it doesnt fire again
 PostFormCreateTimer.Enabled := FALSE;  
end;

Add an OnCreate method to the form with this code

procedure TForm1.FormCreate(Sender: TObject);
begin
     // make the timer fire
 PostFormCreateTimer.enabled := TRUE;
end;

Is this just for TForms ?

No, you can use this for other type of objects as well as TForm.
The example used TForm just because that made it easy to understand.

However, you would probably use Method 2 rather than Method 1 for objects other than TForm so that you have more control over the firing sequence.

Other Solutions

The “Immediate Timer” technique works for me.
You are welcome to add a comment about other options

+1 this post

If you like this post, please +1 vote here to get it listed on Delphi Feeds and also here on BeginEnd.  Thank You

About Me

scott_hollows_201611

  • Oracle & Delphi software developer based in Perth, Western Australia
  • Australian Delphi User Group – WA Chief Cat Herder
  • Australian Delphi User Group – President
blog email linkedinlogo

Author: Scott Hollows

Enterprise software developer based in Perth, Western Australia. Focused on Oracle, Delphi, Data Warehouse design and ETL, Data Architect, Business Intelligence, Oracle performance tuning. President of the Australian Delphi User Group (ADUG) LinkedIn www.linkedin.com/in/scotthollows

6 thoughts on “Immediate TTimer to emulate PostCreate / PostOnCreate event in Delphi”

  1. You could use PostMessage in the OnCreate event and a custom windows message / message handler for it. I do that e.g. to automatically process command line parameters after the program’s main form has completely been created.

  2. Hi,
    I thought I was wrong but I also use a TTimer event OnCreate … especially with FireMonkey ios / android why put code at the start of a mobile application crashes.

    nice article

  3. On Windows, some input (keyboard, mouse, etc.) may slip in before the timer is fired, due to the order in which Windows processes messages (https://msdn.microsoft.com/en-us/library/windows/desktop/ms644936(v=vs.85).aspx). I prefer to use PostMessage when I need to do this because messages posted with PostMessage are always processed before input messages. I don’t know if there’s a portable way to do the equivalent with FireMonkey as I’ve never used it.

  4. Thanks for the feedback everyone.

    I think you should consider how often the event will fire and have to check for your condition.
    The timer event will fire once only.
    OnShow and message handler events will fire more frequently

    I dont think you will see a noticeable difference in performance with any of these options so using a solution that that you prefer and is good enough for your needs should be ok.

    Im interested to know if any these options have problems on non-Windows platforms

  5. Yep, I’ve been doing setup stuff that relies on FormCreate to be complete by checking a flag each time the form activates. This approach, at the expense of an extra timer in the project, makes it easier to do the same thing.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s