Michél Nguyen
Michél Nguyen

Reputation: 71

Delphi - passing variables to another form (without global variables)

I'm referring to question Passing the variable to another Form

Is there also a way to handover data - for example from a settings form to the application's main form without using a global variable?

Upvotes: 1

Views: 1209

Answers (2)

fpiette
fpiette

Reputation: 12292

The settings form has several possibilities to handover data to application mainform without using global variable. I'll assume that the setting form has bee created by the mainform like this:

SettingForm := TSettingForm.Create(Self);
SettingForm.ShowModal;

When the setting form is done (closed), ShowModal returns and mainform can access any filed (variable) or property of the setting form, before destroying it:

ShowMessage(SettingForm.SomeVariable.ToString);
SettingForm.Free;

Another way to do is to use an event.

type
    TSettingFormValueAvailableEvent = procedure (Sender : TObject; Value : Integer) of object;

// Create the form and assign an event handler then show the form
SettingForm := TSettingForm.Create(Self);
SettingForm.OnValueAvailable    := SettingFormValueAvailable;
SettingForm.ShowModal;

// The event handler in main form
procedure TForm1.SettingFormValueAvailable(Sender: TObject; Value : Integer);
begin
    ShowMessage(Value.ToString);
end;

// The event declaration in TFormSetting
private
    FOnValueAvailable : TSettingFormValueAvailableEvent ;
public
    property OnValueAvailable : TSettingFormValueAvailableEvent read FOnValueAvailable write FOnValueAvailable;


// The use of the event in the form setting
procedure TFormSetting.Button1.Click(Sender : TObject);
begin
    if Assigned(FOnValueAvailable) then
        FOnValueAvailable(Self, 1234);   // Pass value 1234
end;

Using an event is a little bit more code but it is "real time". The main form can react immediately when something happens while SettingForm is being displayed.

Upvotes: 2

Andreas Rejbrand
Andreas Rejbrand

Reputation: 108963

Since you are talking about a "settings form", I assume that the form is shown modally. Then it is actually almost trivial.

As an example, create a new VCL application with a label and a button:

Screenshot of main window

Then create a settings form used to set the font of the main label in the middle. It can look like this, with two TLabel controls, two TEdit controls, two TCheckBox controls, and two TButton controls.

Screenshot of settings form

Don't forget to make sure the tab order is correct, that each control has a unique access key (use the FocusControl property of the label to make the connection to the appropriate edit box), that the OK button has Default = True and ModalResult = mrOk, and that the Cancel button has Cancel = True and ModalResult = mrCancel.

(As a bonus, set NumbersOnly = True on the size edit box.)

Now, to pass information between the forms, it is as simple as this:

procedure TfrmMain.btnSettingsClick(Sender: TObject);
var
  dlg: TfrmSettings;
begin

  dlg := TfrmSettings.Create(Self);
  try

    // Populate dialog
    dlg.eFont.Text := lblCaption.Font.Name;
    dlg.eSize.Text := lblCaption.Font.Size.ToString;
    dlg.cbBold.Checked := fsBold in lblCaption.Font.Style;
    dlg.cbItalic.Checked := fsItalic in lblCaption.Font.Style;

    if dlg.ShowModal = mrOk then
    begin

      // Apply settings from dialog
      lblCaption.Font.Name := dlg.eFont.Text;
      lblCaption.Font.Size := StrToInt(dlg.eSize.Text);
      if dlg.cbBold.Checked then
        lblCaption.Font.Style := lblCaption.Font.Style + [fsBold]
      else
        lblCaption.Font.Style := lblCaption.Font.Style - [fsBold];
      if dlg.cbItalic.Checked then
        lblCaption.Font.Style := lblCaption.Font.Style + [fsItalic]
      else
        lblCaption.Font.Style := lblCaption.Font.Style - [fsItalic];

    end;

  finally
    dlg.Free;
  end;

end;

Screen recording

Upvotes: 2

Related Questions