1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Donation with Paypal!!!

    Go to your paypal account and send directly donation to [email protected]

    1 month - 10 $ - Standart VIP

    6 months - 20 $- Standart VIP

    1 year - 30 $- Standart VIP

    2 years - 50 $- Standart VIP

    Gold member for life - 150 $- Standart VIP

    High Vip (Standart VIP include) group please send PM or email to [email protected] for info

    After Donation please send email to [email protected]

  3. Donation Ways 2020


    Paysend
  4. Telegram
Dismiss Notice

Donation with Paypal!!!

Go to your paypal account and send directly donation to [email protected]

1 month - 10 $ - Standart VIP

6 months - 20 $- Standart VIP

1 year - 30 $- Standart VIP

2 years - 50 $- Standart VIP

Gold member for life - 150 $- Standart VIP

High Vip (Standart VIP include) group please send PM or email to [email protected] for info

After Donation please send email to [email protected]

Dismiss Notice
For open hidden message no need write thanks, thank etc. Enough is click to like button on right side of thread.

ShowModal on Android

Discussion in 'Delphi Android And IOS' started by AdminDF, Aug 5, 2014.

  1. AdminDF
    Online

    AdminDFAdminDF is a Verified Member Delphifan Staff Member DF Staff

    FireMonkey does a lot of work to allow you to write one set of code that compiles and runs on different platforms.

    Not only that, it also does a lot of work to make many of the coding patterns that some of you are used to from the VCL on Windows, work unchanged on other platforms.

    That’s great, but in some cases, re-using old patterns is not desirable. ShowModal is a case in point.

    If you’ve come from VCL, you’ve written code like this a million times:


    Code:
    procedure THeaderFooterForm.btnPickClick(Sender: TObject);
    var
      dlg: TForm1;
    begin
      dlg := TForm1.Create(nil);
      try
        if dlg.ShowModal = mrOK then
          // do something here
          ...
      finally
        dlg.Free;
      end; 
    end;
    
    The key things to note are that:

     the call to ShowModal is bHIDE-THANKSing. By the time the comparison to mrOK is done, the child form has been shown and closed.
    dlg.Free actually causes the form’s destructor to run and the memory be reclaimed.
    All good. However, two things trip us up when we move this pattern to mobile:

    With ARC, a call to Free does not invoke the destructor. It decrements the object’s reference count. If it is greater than zero, the object won’t be destroyed. If you want to force the destructor to run, call DisposeOf instead.
    Android doesn’t really have the concept of modal forms. As a result, a call to ShowModal is not bHIDE-THANKSing. If we have code that we want to run after the form has closed, we can’t structure it like the code above.
    So, what to do?

    Fortunately, FireMonkey has an alternative pattern, one that let’s us solve both these issues. Further, it works across all the platforms that FireMonkey supports, so we can still have one set of source. We just have to learn a new pattern.

    So here’s the same code above following the new pattern:


    Code:
    procedure TfrmParent.Button1Click(Sender: TObject);
    var
      dlg : TForm1;
    begin
      dlg := TForm1.Create(nil);
      dlg.ShowModal(procedure(ModalResult : TModalResult)
                    begin
                      if ModalResult = mrOK then
                        // do something here
                    end);
    end;
    
    ShowModal has been overloaded to allow you to pass in an anonymous method that takes a ModalResult as a parameter. This anonymous method will run when the child form has been closed, giving you a chance to check the ModalResult  and do whatever you need to.

    So, that’s fixed half the problem, but where does my form get destroyed?

    You might be tempted to call dlg.DisposeOf inside that anonymous method. Don’t. Well, not unless you want to generate a segfault. During that anonymous method, our child form is still running. If you look in the source, our anonymous method is invoked as part of the ModalResult property’s setter. After our anonymous method runs, the rest of this setter is going to continue, so destroying the object is probably a bad idea.

    What do we do instead? Forms have an OnClose event, where you can specify an Action that should take place after the form is closed. Some code like this will allow the form to finish what it is doing, and then destroy itself.


    Code:
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      Action := TCloseAction.caFree;
    end;
    
     
    asachanr likes this.
  2. johncs
    Offline

    johncs DF Junior

    RE:

    thanks
     
  3. eduardomrj
    Offline

    eduardomrj DF Member

    RE:

    thanks!
     
  4. bujitos
    Offline

    bujitos DF Junior

    RE:

    [font=Verdana, Arial, sans-serif]thanks[/font]
     
  5. yneves
    Offline

    yneves DF Member

    RE:

    Thanks man.
     

Share This Page