Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrong Form is focused after closing form in firemonkey

When showing and closing Forms in firemonkey, the application cannot remember wich form was the last activated form, and activates the wrong form.

How can I activate the last active form instead of an arbitrary form chosen by the application?

To replicate : Create 3 forms and open each one in succession from previous form.

I a mainform and 2 ChildForms, the second form is parent to the third form.

I open the first childForm from my MainForm.

var
  tmpForm2:TForm2;
begin
  tmpForm2:=TForm2.Create(self);
  tmpForm2.Show;
end;

In this Form there is a button that shows second childform

var
  form3:Tform3;
begin
  form3:=TForm3.Create(nil);
  form3.Show;
end;

When I open the second ChildForm and close it, the Mainform is activated. Instead of the first ChildForm

Now I repeat the process but when closing the second ChildForm, the first one is actived, as one would expect.

Next time the Mainform is again activated, so the order keeps chainging, instead of the real last active form.

like image 831
r_j Avatar asked Dec 14 '25 02:12

r_j


1 Answers

Looks like it was bug in Delphi XE7/XE7 Update 1 in function

function TScreen.NextActiveForm(const OldActiveForm: TCommonCustomForm): TCommonCustomForm;

On Delphi XE8 this function works correctly and you return to previous window.

In XE8 they rewrite function function TScreen.NextActiveForm(const OldActiveForm: TCommonCustomForm): TCommonCustomForm;

Dog-nail for XE7. I copy function from XE8 and using it before close form. I tested it only under Windows platform.

unit ufmForm3;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls;

type
  TfmForm3 = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
    function NextActiveForm(const OldActiveForm: TCommonCustomForm): TCommonCustomForm;
  end;

var
  fmForm3: TfmForm3;

implementation

{$R *.fmx}

procedure TfmForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  NextActiveForm(Self);
end;

function TfmForm3.NextActiveForm(const OldActiveForm: TCommonCustomForm): TCommonCustomForm;
var
  I, CurrIndex: integer;
begin
  Result := nil;
  CurrIndex := Screen.IndexFormOfObject(OldActiveForm);
  if CurrIndex >= 0 then
  begin
    I := CurrIndex - 1;
    while (I >= 0) and (Screen.Forms[I].Released or not Screen.Forms[I].Visible) do
      Dec(I);
    if I < 0 then
    begin
      I := Screen.FormCount - 1;
      while (I >= 0) and (I <> CurrIndex) and (Screen.Forms[I].Released or not Screen.Forms[I].Visible) do
        Dec(I);
    end;
    if (I >= 0) and (I <> CurrIndex) then
    begin
      Result := Screen.Forms[I];
      Screen.ActiveForm := Result;
    end;
  end;
end;


end.
like image 187
Zam Avatar answered Dec 16 '25 22:12

Zam



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!