Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
Member Area
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Become a Member
-Why sign up!
-Chat Online!
-Indexes NEW!!
-Build your resume
-Find a job
-Post a job
-Resume Search
-Link to us
Visit Embarcadero
Embarcadero Community
How to call another form and return multiple values Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
Delphi 2.x
User Rating
No Votes
# Votes
DSP, Administrator
Reference URL:
			Author: Jonas Bilinkevicius

I have a main form that will call a second form to use for searching on different 
criteria. How can I return multiple values retrieved in the second form to the main 


Solve 1:

Well, you need to add the second forms Unit to the first ones Uses clause, so you 
can call up the form. This gives you access to the forms controls and methods. It 
is usually bad design to access the forms controls from outside, since this tightly 
couples the outside code to the form. Any change you make to the form may require a 
change to the code accessing the form. So decouple them. One way to do that is to 
add properties (public section of the form) for each data item you may need to 
access from outside. This way the form controls how the data is fetched from the 
controls or internal fields of the form, usually via Set and Get methods for the 
properties. The form is then used like this (assuming it is not autocreated):

1   with TSearchform.create(application) do
2   try
3     {... assign start values to the forms properties here, if required}
4     if ShowModal = mrOK then
5     begin
6       {... read values from the form properties here}
7     end
8     else
9       {... user aborted, take appropriate action}
10  finally
11    free;
12  end;

This can be taken a step further to avoid the necessity for public properties in 
the first place (which exposes a kind of working contract to the outside world, 
which may reveal too much about the form or limit how you could modify it later too 
much). For that you create a non-visible class, derived from TPersistent, which 
holds the data items you need to transfer in and out of the form. The form is given 
overriden Assign and Assignto methods, which, when fed an instance of this data 
container, will copy the data between the form and the data container. Now all 
knowledge of how the forms handles the data is internal to the form, all the 
outside world needs to know is that it can assign a data container to it and vice 

13  datacontainer := TDataContainer.Create;
14  {... set up datacontainers data to fed into the form}
15  searchform := TSearchform.create(application);
16  try
17    searchform.Assign(datacontainer);
18    if searchform.ShowModal = mrOK then
19      datacontainer.Assign(searchform)
20    else
21      {... user aborted, take appropriate action}
22  finally
24  end;
25  {... use datacontainer if user entered data and free it when done}

The TDatacontainer class would reside in its own Unit, which is used by both form 

Solve 2:

You have a variety of options:

26  //1. Use "var" parameters:
28  procedure TForm2.DoSomething(var Return1, Return2, Return3: Integer);
29  begin
30    Return1 := 1;
31    Return2 := 2;
32    Return3 := 3;
33  end;
35  procedure TForm1.Button1Click(Sender: TObject);
36  var
37    X, Y, Z: Integer;
38  begin
39    Form2.DoSomething(X, Y, Z);
40    ShowMessage(IntToStr(X));
41  end;
43  //2. Declare a record which aggregates your return values:
45  type
46    TReturnRecord = record
47      Value1: Integer;
48      Value2: Integer;
49      Value3: Integer;
50    end;
52  function TForm2.DoSomething: TReturnRecord;
53  begin
54    Result.Value1 := 1;
55    Result.Value2 := 2;
56    Result.Value3 := 3;
57  end;
59  procedure TForm1.Button1Click(Sender: TObject);
60  var
61    R: TReturnRecord;
62  begin
63    R := Form2.DoSomething;
64    ShowMessage(IntToStr(R.Value1));
65  end;
67  //3. Declare a class which aggregates your return values:
69  type
70    TReturnClass = class
71      Value1: Integer;
72      Value2: Integer;
73      Value3: Integer;
74    end;
76  function TForm2.DoSomething(AReturn: TReturnClass);
77  begin
78    AReturn.Value1 := 1;
79    AReturn.Value2 := 2;
80    AReturn.Value3 := 3;
81  end;
83  procedure TForm1.Button1Click(Sender: TObject);
84  var
85    R: TReturnClass;
86  begin
87    R := TReturnClass.Create;
88    try
89      Form2.DoSomething(R);
90      ShowMessage(R.Value1);
91    finally
92      R.Free;
93    end;
94  end;

Or you could use a list or array structure, or you could use an open array parameter.

Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10


Share this page
Download from Google

Copyright © Mendozi Enterprises LLC