Applications usually have an About box in which you can display information such as the version of the product, a copyright notice, and so on. The simplest way to build an About box is to use the MessageDlg function. With this method, you can show only a limited amount of text and no special graphics.
Therefore, the usual method for creating an About box is to use a dialog box, such as the one generated with one of the Delphi default templates. In this About box, you might want to add some code to display system information, such as the version of Windows or the amount of free memory, or some user information, such as the registered user name.
Another typical technique displays an initial screen before the application's main form is shown. Doing so makes the application seem more responsive, because you show something to the user while the program is loading, and it also makes a nice visual effect. Sometimes this same window is displayed as the application's About box. For an example in which a splash screen is particularly useful, I've built a program displaying a list box filled with prime numbers.
The prime numbers are computed on program startup, with a for loop running from 1 to 30,000; the numbers are displayed as soon as the form becomes visible. Because I've used (on purpose) a slow function to compute prime numbers, this initialization code takes quite some time. The numbers are added to a list box that covers the full client area of the form and allows multiple columns to be displayed, as you can see in Figure 7.14.
There are three versions of the Splash program (plus the three corresponding CLX versions). As you can see by running the Splash0 example, the problem with this program is that the initial operation, which takes place in the FormCreate method, takes a lot of time. When you start the program, it takes several seconds to display the main form. If your computer is very fast or very slow, you can change the upper limit of the for loop in the FormCreate method to make the program faster or slower.
This program has a simple dialog box with an image component, a caption, and a bitmap button, all placed inside a panel taking up the whole surface of the About box. This form is displayed when you select the Help ® About menu item. But you really want to display this About box while the program starts. You can see this effect by running the Splash1 and Splash2 examples, which show a splash screen using two different techniques.
First, I've added a method to the TAboutBox class. This method, called MakeSplash, changes some properties of the form to make it suitable for a splash form. Basically, it removes the border and caption, hides the OK button, makes the border of the panel thick (to replace the border of the form), and then shows the form, repainting it immediately:
procedure TAboutBox.MakeSplash; begin BorderStyle := bsNone; BitBtn1.Visible := False; Panel1.BorderWidth := 3; Show; Update; end;
This method is called after creating the form in the project file of the Splash1 example. This code is executed before creating the other forms (in this case only the main form), and the splash screen is then removed before running the application. These operations take place within a try/finally block. Here is the source code of the main block of the project file for the Splash2 example:
var SplashAbout: TAboutBox; begin Application.Initialize; // create and show the splash form SplashAbout := TAboutBox.Create (Application); try SplashAbout.MakeSplash; // standard code... Application.CreateForm(TForm1, Form1); // get rid of the splash form SplashAbout.Close; finally SplashAbout.Free; end; Application.Run; end.
This approach makes sense only if your application's main form takes a while to create, to execute its startup code (as in this case), or to open database tables. Notice that the splash screen is the first form created, but because the program doesn't use the Application object's CreateForm method, it doesn't become the main form of the application. In this case, closing the splash screen would terminate the program!
An alternative approach is to keep the splash form on the screen a little longer and use a timer to get rid of it. I've implemented this technique in the Splash2 example. This example also uses a different approach for creating the splash form: Instead of creating the splash form in the project source code, it creates the form at the very beginning of the FormCreate method of the main form.
procedure TForm1.FormCreate(Sender: TObject); var I: Integer; SplashAbout: TAboutBox; begin // create and show the splash form SplashAbout := TAboutBox.Create (Application); SplashAbout.MakeSplash; // slow code (omitted)... // get rid of the splash form, after a while SplashAbout.Timer1.Enabled := True; end;
The timer is enabled just before terminating the method. After its interval has elapsed (in the example, 3 seconds) the OnTimer event is activated, and the splash form handles it by closing and destroying itself, calling Close and then Release.
The Release method of a form is similar to the Free method of objects, but the destruction of the form is delayed until all event handlers have completed execution. Using Free inside a form might cause an access violation, because the internal code that fired the event handler might refer again to the form object.
There is one more thing to fix. The main form will be displayed later and in front of the splash form, unless you make it a top-most form. For this reason, I've added one line to the MakeSplash method of the About box in the Splash2 example:
FormStyle := fsStayOnTop;