Show: Object Pascal C++
Display Preferences

ShowModal Dialogs in FireMonkey Mobile Apps

From Appmethod Topics
Jump to: navigation, search

Go Up to Android Mobile Application Development

Go Up to iOS Mobile Application Development

This topic presents two code snippets that demonstrate how to display a modal dialog in your mobile app:

  • Typical Object Pascal and C++ code used for Desktop apps.
  • Revised Object Pascal and C++ code to be used with Android apps.

You should use ShowModal in your mobile apps as demonstrated in the second code snippet (as an anonymous method). Following these code patterns allows you to change any old ShowModal code to be compatible with all the supported platforms.

  • In Object Pascal:
The difference between the two code snippets is that the second snippet uses an anonymous method. An anonymous method is simply a method that is passed to a procedure/function and that can be executed in the procedure/function. In this case, dlg.ShowModal takes an anonymous method as a parameter.
In the second code snippet, the code from the first snippet (that checks the user's result and processes the data) is placed in an anonymous method and is executed when the form, dlg.ModalResult, is set. In this example, the modal result is passed in the parameter ModalResult; this is the same modal result that dlg.ShowModal returns.
Note also that the second code snippet frees the form with DisposeOf, which is required when running on the mobile frameworks that use ARC (automatic reference counting).
  • In C++:
In the second code snippet, the code from the first snippet (that checks the user's result and processes the data) is placed in a new definition class that takes an interface. C++ code that seeks to specify a function or member function as a method reference parameter has to wrap the latter behind an interface that exposes an Invoke() method.

This is the only code that changes between the first and second code snippets:

Object Pascal:

dlg.ShowModal(procedure(ModalResult: TModalResult)
begin
  if ModalResult = mrOK then
  // if OK was pressed and an item is selected, pick it
    if dlg.ListBox1.ItemIndex >= 0 then
      edit1.Text := dlg.ListBox1.Items [dlg.ListBox1.ItemIndex];
      dlg.DisposeOf;
end);

C++:

//Inside the event handler "Onclick":
  TMethodReference* MethodReference = new TMethodReference;
  MethodReference->dlg = dlg;
  MethodReference->HeaderFooterForm = this;
  dlg->ShowModal(MethodReference);

// Define a class that implements the TProc__1 interface: 
class TMethodReference : public TCppInterfacedObject<TProc__1<TModalResult> > {
public:
  TForm1 *dlg;
  THeaderFooterForm *HeaderFooterForm;

  void __fastcall Invoke(TModalResult ModalResult) {
    if (ModalResult == mrOk) {
      if (dlg->ListBox1->ItemIndex >= 0) {
        HeaderFooterForm->Edit1->Text = dlg->ListBox1->Items->Strings[dlg->ListBox1->ItemIndex];
	dlg->Free();
      }
    }
  }
};

First Code Snippet: Typical Code for Calling ShowModal

Here is an example of typical code that shows a modal form:

Object Pascal:

procedure THeaderFooterForm.btnPickClick(Sender: TObject);
var
  dlg: TForm1;
begin
  dlg := TForm1.Create(nil);
  try
    // select current value, if available in the list
    dlg.ListBox1.ItemIndex := dlg.ListBox1.Items.IndexOf(edit1.Text);

    if dlg.ShowModal = mrOK then
      // if OK was pressed and an item is selected, pick it
      if dlg.ListBox1.ItemIndex >= 0 then
        edit1.Text := dlg.ListBox1.Items [dlg.ListBox1.ItemIndex];
  finally
    dlg.Free;
  end;

end;

C++:

void __fastcall THeaderFooterForm::btnPickClick(TObject *Sender) {
  TForm1 *dlg = new TForm1(NULL);

  dlg->ListBox1->ItemIndex = dlg->ListBox1->Items->IndexOf(Edit1->Text);
  if (dlg->ShowModal() == mrOk) {
    if (dlg->ListBox1->ItemIndex >= 0) {
      Edit1->Text = dlg->ListBox1->Items->Strings[dlg->ListBox1->ItemIndex];
    dlg->Free();
    }
  }
}

Pseudo-Code Interpretation of Typical ShowModal Code Snippet

Here is a description of what each part of this procedure does:

Object Pascal:

//Declare local variables
dlg: TForm1;

//Create form and initialize member in the form
dlg := TForm1.Create(nil);
dlg.ListBox1.ItemIndex := dlg.ListBox1.Items.IndexOf(edit1.Text);

//Show the form modal
if dlg.ShowModal = mrOK then

//Check the user's result and process the data
if dlg.ListBox1.ItemIndex >= 0 then
edit1.Text := dlg.ListBox1.Items [dlg.ListBox1.ItemIndex];

//Free the form
dlg.Free;

C++:

//Declare local variables and create form:
TForm1 *dlg = new TForm1(NULL);

//Initialize member in the form:
dlg->ListBox1->ItemIndex = dlg->ListBox1->Items->IndexOf(Edit1->Text);

//Show the form modal
if (dlg->ShowModal() == mrOk) 

//Check the user's result and process the data
if (dlg->ListBox1->ItemIndex >= 0) {
  Edit1->Text = dlg->ListBox1->Items->Strings[dlg->ListBox1->ItemIndex];

//Free the form
dlg->Free();

Second Code Snippet: Calling ShowModal as an Anonymous Method on All Platforms

With the mobile platforms, you should change this code sightly to allow ShowModal to work on all the Supported Target Platforms.

Object Pascal:

procedure THeaderFooterForm.btnPickClick(Sender: TObject);
var
  dlg: TForm1;
begin
  dlg := TForm1.Create(nil);
  // select current value, if available in the list
  dlg.ListBox1.ItemIndex := dlg.ListBox1.Items.IndexOf(edit1.Text);

  dlg.ShowModal(procedure(ModalResult: TModalResult)
    begin
      if ModalResult = mrOK then
      // if OK was pressed and an item is selected, pick it
        if dlg.ListBox1.ItemIndex >= 0 then
          edit1.Text := dlg.ListBox1.Items [dlg.ListBox1.ItemIndex];
      dlg.DisposeOf;
    end);

end;

C++:

1. Define a class that takes the TProc__1 interface:
class TMethodReference : public TCppInterfacedObject<TProc__1<TModalResult> > {
public:
  TForm1 *dlg;
  THeaderFooterForm *HeaderFooterForm;

  void __fastcall Invoke(TModalResult ModalResult) {
    if (ModalResult == mrOk) {
      if (dlg->ListBox1->ItemIndex >= 0) {
        HeaderFooterForm->Edit1->Text = dlg->ListBox1->Items->Strings[dlg->ListBox1->ItemIndex];
        dlg->Free();
      }
    }
  }
};
2. Then pass an instance of this class to ShowModal:
void __fastcall THeaderFooterForm::btnPickClick(TObject *Sender) {
  TForm1 *dlg = new TForm1(NULL);

  dlg->ListBox1->ItemIndex = dlg->ListBox1->Items->IndexOf(Edit1->Text);

  TMethodReference* MethodReference = new TMethodReference;
  MethodReference->dlg = dlg;
  MethodReference->HeaderFooterForm = this;
  dlg->ShowModal(MethodReference);
}

Pseudo-Code Interpretation of Anonymous Method ShowModal Code Snippet

Here is a description of what happens in the second code snippet (it does the same thing as the first code snippet):

Object Pascal:

//Declare local variables
dlg: TForm1;

//Create form and initialize member in the form
dlg := TForm1.Create(nil);
dlg.ListBox1.ItemIndex := dlg.ListBox1.Items.IndexOf(edit1.Text);

//Show the form modal
dlg.ShowModal(procedure(ModalResult: TModalResult)

//Check the user's result and process the data
if ModalResult = mrOK then
  if dlg.ListBox1.ItemIndex >= 0 then
    edit1.Text := dlg.ListBox1.Items [dlg.ListBox1.ItemIndex];

//Free the form
dlg.DisposeOf;

C++:

1. Define a class that takes the TProc__1 interface:

//Declare the class TMethodReference
class TMethodReference : public TCppInterfacedObject<[[lib_en:System.SysUtils.TProc | TProc__1]]<TModalResult> >

//Declare local variables on class TMethodReference
TForm1 *dlg;
THeaderFooterForm *HeaderFooterForm;

//Check the user's result and process the data 
if (ModalResult == mrOk) {
  if (dlg->ListBox1->ItemIndex >= 0) {
    HeaderFooterForm->Edit1->Text = dlg->ListBox1->Items->Strings[dlg->ListBox1->ItemIndex];

//Free the form
dlg->Free();

2. Then pass an instance of this class to ShowModal:

//Create form and initialize member in the form
TForm1 *dlg = new TForm1(NULL);
dlg->ListBox1->ItemIndex = dlg->ListBox1->Items->IndexOf(Edit1->Text);  

//Create method reference 
TMethodReference* MethodReference = new TMethodReference;

//Assign the values of the class to the main form
MethodReference->dlg = dlg;
MethodReference->HeaderFooterForm = this;

//Show the form modal
dlg->ShowModal(MethodReference);

See Also

Personal tools
In other languages