Search code examples
formsdelphiinitializationdatamodule

Delphi: App initialization - best practices / approach


I run into this regularly, and am just looking for best practice/approach. I have a database / datamodule-containing app, and want to fire up the database/datasets on startup w/o having "active at runtime" set to true at design time (database location varies). Also run a web "check for updates" routine when the app starts up.

Given TForm event sequences, and results from various trial and error, I'm currently using this approach:

I use a "Globals" record set up in the main form to store all global vars, have one element of that called Globals.AppInitialized (boolean), and set it to False in the Initialization section of the main form.

At the main form's OnShow event (all forms are created by then), I test Globals.AppInitialized; if it's false, I run my "Initialization" stuff, and then finish by setting Globals.AppInitialized := True.

This seems to work pretty well, but is it the best approach? Looking for insight from others' experience, ideas and opinions. TIA..


Solution

  • I generally always turn off auto creation of all forms EXCEPT for the main form and possibly the primary datamodule.

    One trick that I learned you can do, is add your datamodule to your project, allow it to auto-create and create BEFORE your main form. Then, when your main form is created, the onCreate for the datamodule will have already been run.

    If your application has some code to say, set the focus of a control (something you can't do on creation, since its "not visible yet") then create a user message and post it to the form in your oncreate. The message SHOULD (no guarantee) be processed as soon as the forms message loop is processed. For example:

    const
      wm_AppStarted = wm_User + 101;
    
    
    type
      Form1 = class(tForm)
        :
        procedure wmAppStarted(var Msg:tMessage); message wm_AppStarted;
      end; 
    
    // in your oncreate event add the following, which should result in your wmAppStarted event firing.
    PostMessage(handle,wm_AppStarted,0,0);
    

    I can't think of a single time that this message was never processed, but the nature of the call is that it is added to the message queue, and if the queue is full then it is "dropped". Just be aware that edge case exists.