Delphi Programming Guide
Delphi Programmer 

Menu  Table of contents

Part I - Foundations
  Chapter 1 – Delphi 7 and Its IDE
  Chapter 2 – The Delphi Programming Language
  Chapter 3 – The Run-Time Library
  Chapter 4 – Core Library classes
  Chapter 5 – Visual Controls
  Chapter 6 – Building the User Interface
  Chapter 7 – Working with Forms
Part II - Delphi Object-Oriented Architectures
  Chapter 8 – The Architecture of Delphi Applications
  Chapter 9 – Writing Delphi Components
  Chapter 10 – Libraries and Packages
  Chapter 11 – Modeling and OOP Programming (with ModelMaker)
  Chapter 12 – From COM to COM+
Part III - Delphi Database-Oriented Architectures
  Chapter 13 – Delphi's Database Architecture
  Chapter 14 – Client/Server with dbExpress
  Chapter 15 – Working with ADO
  Chapter 16 – Multitier DataSnap Applications
  Chapter 17 – Writing Database Components
  Chapter 18 – Reporting with Rave
Part IV - Delphi, the Internet, and a .NET Preview
  Chapter 19 – Internet Programming: Sockets and Indy
  Chapter 20 – Web Programming with WebBroker and WebSnap
  Chapter 21 – Web Programming with IntraWeb
  Chapter 22 – Using XML Technologies
  Chapter 23 – Web Services and SOAP
  Chapter 24 – The Microsoft .NET Architecture from the Delphi Perspective
  Chapter 25 – Delphi for .NET Preview: The Language and the RTL
       
  Appendix A – Extra Delphi Tools by the Author
  Appendix B – Extra Delphi Tools from Other Sources
  Appendix C – Free Companion Books on Delphi
       
  Index    
  List of Figures    
  List of tables    
  List of Listings    
  List of Sidebars  

 
Previous Section Next Section

Creating and Closing Forms

Up to now I have ignored the issue of form creation. You know that when the form is created, you receive the OnCreate event and can change or test some of the initial form's properties or fields. The statement responsible for creating the form is in the project's source file:

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

To skip the automatic form creation, you can either modify this code or use the Forms page of the Project Options dialog box (see Figure 7.10). In this dialog box, you can decide whether the form should be automatically created. If you disable automatic creation, the project's initialization code becomes the following:

Click To expand
Figure 7.10:  The Forms page of the Delphi Project Options dialog box
begin
  Applications.Initialize;
  Application.Run;
end.

If you now run this program, nothing happens. It terminates immediately because no main window is created. The call to the application's CreateForm method creates a new instance of the form class passed as the first parameter and assigns it to the variable passed as the second parameter.

Something else happens behind the scenes. When CreateForm is called, if there is currently no main form, the current form is assigned to the application's MainForm property. For this reason, the form indicated as Main Form in the dialog box shown in Figure 7.10 corresponds to the first call to the application's CreateForm method (that is, when several forms are created at startup).

The same holds for closing the application. Closing the main form terminates the application, regardless of the other forms. If you want to perform this operation from the program's code, call the Close method of the main form, as you've done several times in past examples.

Form Creation Events

Regardless of the manual or automatic creation of forms, when a form is created, you can intercept many events. Form-creation events are fired in the following order:

  1. OnCreate indicates that the form is being created.

  2. OnShow indicates that the form is being displayed. Besides main forms, this event happens after you set the Visible property of the form to True or call the Show or ShowModal method. This event is fired again if the form is hidden and then displayed again.

  3. OnActivate indicates that the form becomes the active form within the application. This event is fired every time you move from another form of the application to the current one.

  4. Other events, including OnResize and OnPaint, indicate operations always done at startup but then repeated many times.

Note 

In Qt, the OnResize event won't fire as it does in Windows when the form is created. To make the code more portable from Delphi to Kylix, CLX simulates this event, although it would make more sense to tweak the VCL to avoid this odd behavior (a comment in the CLX source code describes this situation).

As you can see in the previous list, every event has a specific role apart from form initialization, except OnCreate, which is guaranteed to be called only once as the form is created.

However, there is an alternative approach to adding initialization code to a form: overriding the constructor. This is usually done as follows:

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited Create (AOwner);
  // extra initialization code
end;

Before the call to the Create method of the base class, the properties of the form are still not loaded and the internal components are not available. For this reason the standard approach is to call the base class constructor first and then do the custom operations.

Note 

Up to version 3, Delphi used a different creation order, which has led to the OldCreateOrder compatibility property of the VCL. When this property is set to the default value of False, all the code in a form constructor is executed before the code in the OnCreate event handler (which is fired by the special AfterConstruction method). If you enable the old creation order, instead, the constructor's inherited call leads to the call of the OnCreate event handler. You can examine the behavior of the CreateOrd example using the two values of the OldCreateOrder property.

Closing a Form

When you close the form using the Close method or by the usual means (Alt+F4, the system menu, or the Close button), the OnCloseQuery event is called. In this event, you can ask the user to confirm the action, particularly if there is unsaved data in the form. Here is an example of the code you can write:

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if MessageDlg ('Are you sure you want to exit?', mtConfirmation,
      [mbYes, mbNo], 0) = mrNo then
    CanClose := False;
end;

If OnCloseQuery indicates that the form should still be closed, the OnClose event is called. The third step is to call the OnDestroy event, which is the opposite of the OnCreate event and is generally used to de-allocate objects related to the form and free the corresponding memory.

Note 

To be more precise, the BeforeDestruction method generates an OnDestroy event before the Destroy destructor is called. That is, unless you have set the OldCreateOrder property to True, in which case Delphi uses a different closing sequence.

So, what is the use of the intermediate OnClose event? In this method, you have another chance to avoid closing the application, or you can specify alternative "close actions." The method has an Action parameter passed by reference. You can assign the following values to this parameter:

caNone  The form is not allowed to close. This corresponds to setting the CanClose parameter of the OnCloseQuery method to False.

caHide  The form is not closed, just hidden. This makes sense if there are other forms in the application; otherwise, the program terminates. This is the default for secondary forms, and it's the reason I had to handle the OnClose event in the previous example to close the secondary forms.

caFree  The form is closed, freeing its memory, and the application eventually terminates if this was the main form. This is the default action for the main form and the action you should use when you create multiple forms dynamically (if you want to remove the windows and destroy the corresponding Delphi object as the form closes).

caMinimize  The form is not closed but only minimized. This is the default action for MDI child forms.

Note 

When a user shuts down Windows, the OnCloseQuery event is activated, and a program can use it to stop the shutdown process. In this case, the OnClose event is not called even if OnCloseQuery sets the CanClose parameter to True.


 
Previous Section Next Section


 


 

Delphi Sources


Copyright © 2004-2024 "Delphi Sources" by BrokenByte Software. Delphi Programming Guide
ร๐๓๏๏เ ยส๎ํ๒เ๊๒ๅ   Facebook   ั๑๛๋๊เ ํเ Twitter