1. Tech

Your suggestion is on its way!

An email with a link to:

http://delphi.about.com/od/beginners/l/aa071503a.htm

was emailed to:

Thanks for sharing About.com with others!

Communicating Between Forms
Page 1: Finding out how a modal form was closed
 Win prizes by sharing code!
Do you have some Delphi code you want to share? Are you interested in winning a prize for your work?
Delphi Programming Quickies Contest
 More of this Feature
• Page 2: Getting the values from another form
• Page 3: Moving records of data between two forms
 Join the Discussion
"Post your views and comments to this chapter of the free Delphi Programming Course"
Discuss!
 Related Resources
• A Beginner's Guide to Delphi Programming.TOC

• Delphi Project file (dpr)
• Working with forms
• Delphi forms - Life Cycle

Article submitted by: Kevin S. Gallagher

Welcome to the fifteenth chapter of the FREE online programming course:
A Beginner’s Guide to Delphi Programming.
In the previous chapter we looked at simple SDI forms and considered some good reasons for not letting your program auto-create forms. This instalment builds on that to demonstrate techniques available when closing modal forms and how one form can retrieve user input or other data from a secondary form.

Finding out how a modal form was closed
Modal forms offer specific features that we cannot have when displaying non-modally. Most commonly, we will display a form modally to isolate its processes from anything that might otherwise happen on the main form. Once these processes complete, you might want to know whether the user pressed the Save or Cancel button to close the modal form. You can write some interesting code to accomplish this, but it does not have to be difficult. Delphi supplies modal forms with the ModalResult property, which we can read to tell how the user exited the form.

The following code returns a result, but the calling routine ignores it:

var
  F:TForm2;
begin
 F := TForm2.Create(nil);
 F.ShowModal;
 F.Release;
 ...

The example shown above just shows the form, lets the user do something with it, then releases it. To check how the form was terminated we need to take advantage of the fact that the ShowModal method is a function that returns one of several ModalResult values. Change the line

F.ShowModal

to

if F.ShowModal = mrOk then

We need some code in the modal form to set up whatever it is we want to retrieve. There is more than one way to get the ModalResult because TForm is not the only component having a ModalResult property - TButton has one too.

Let us look at TButton's ModalResult first. Start a new project, and add one additional form (Delphi IDE Main menu: File -> New -> Form). This new form will have a 'Form2' name. Next add a TButton (Name: 'Button1') to the main form (Form1), double click the new button and enter the following code:

procedure TForm1.Button1Click(Sender: TObject);
var f : TForm2;
begin
  f := TForm2.Create(nil);
  try
    if f.ShowModal = mrOk then
      Caption := 'Yes'
    else
      Caption := 'No';
  finally
      f.Release;
  end;
end;

Object Inspector: ModalResult PropertyNow select the additional form. Give it two TButtons, labelling one 'Save' (Name : 'btnSave'; Caption: 'Save') and the other 'Cancel' (Name : 'btnCancel'; Caption: 'Cancel'). Select the Save button and press F4 to bring up the Object Inspector, scroll up/down until you find the property ModalResult and set it to mrOk. Go back to the form and select the Cancel button, press F4, select the property ModalResult, and set it to mrCancel.

It's as simple as that. Now press F9 to run the project. (Depending on your environment settings, Delphi may prompt to save the files.) Once the main form appears, press the Button1 you added earlier, to show the child form. When the child form appears press the Save button and the form closes, once back to the main form note that it's caption says "Yes". Press the main form's button to bring up the child form again but this time press the Cancel button (or the System menu Close item or the [x] button in the caption area). The main form's caption will read "No".

How does this work? To find out take a look at the Click event for TButton (from StdCtrls.pas):

procedure TButton.Click;
var Form: TCustomForm;
begin
  Form := GetParentForm(Self);
  if Form <> nil then 
    Form.ModalResult := ModalResult;
  inherited Click;
end;

What happens is that the Owner (in this case the secondary form) of TButton gets its ModalResult set according to the value of the TButton's ModalResult. If you don't set TButton.ModalResult, then the value is mrNone (by defaolt). Even if the TButton is placed on another control the parent form is still used to set its result. The last line then invokes the Click event inherited from its ancestor class.

To understand what goes on with the Forms ModalResult it is worthwhile reviewing the code in Forms.pas, which you should be able to find in ..\DelphiN\Source (where N represents the version number).

In TForm's ShowModal function, directly after the form is shown, a Repeat-Until loop starts, which keeps checking for the variable ModalResult to become a value greater than zero. When this occurs, the final code closes the form.

You can set ModalResult at design-time, as described above, but you can also set the form's ModalResult property directly in code at run-time.

Now, knowing whether the user wants to accept or reject what occurred on the child form, the calling form can react by using the information from the child form or ignoring it. Let's see how...

Next page > How to react on the information from the child form? > Page 1, 2, 3

A Beginner's Guide to Delphi Programming: Next Chapter >>
>> Creating flat (non-relational) databases with no database components

©2014 About.com. All rights reserved.