How to Open/Close Multiple Forms from a Main Form

Asked

Viewed 3,162 times

-2

I have a FormPrincipal which has a Tmenu with Tactionlist and from this form I want to call several other Forms, according to the menu items.

In the main form, I have a Panel and I want the others to open inside this panel.

I adjusted the code below, after help from other colleagues of Stackoverflow in English, and it worked:

procedure TFormPrincipal.AbreFormBancoExecute(Sender: TObject);
begin   
  Formbanco := Tformbanco.Create(Self);
  Formbanco.Parent := PanelCorpo;
  Formbanco.Align := alclient;
  Formbanco.BorderIcons := [];
  Formbanco.BorderStyle := bsNone;
  Formbanco.Show;
end;

But now I need to know which form is active in the Panel to be able to close it once I close the other, IE, I need to modify the above routine :

procedure TFormPrincipal.AbreFormBancoExecute(Sender: TObject);
begin   

  // identificar qual form está ativo dentro do FormPrincipal
  // fechar este form e em seguida rodar o código abaixo  
  Formbanco := Tformbanco.Create(Self);
  Formbanco.Parent := PanelCorpo;
  Formbanco.Align := alclient;
  Formbanco.BorderIcons := [];
  Formbanco.BorderStyle := bsNone;
  Formbanco.Show;
end;

This is a good approach to handling Forms calls from a correct main form?

. Adjust the code to get the currently open form. In Formbanco I put the following :

procedure TFormbanco.FormShow(Sender: TObject);
begin     
  Edit1.text := Screen.Activeform.Name;  // não mostra Formbanco !!  
                                             // só mostra FormPrincipal !!
end;

2 answers

1

Consider this example:

procedure TForm4.Button1Click(Sender: TObject);
begin
  vForm1 := TForm.Create(Self);
  vForm1.Parent := Panel1;
  vForm1.Width := 100;
  vForm1.Align := alLeft;
  vForm1.Name := 'Form1Teste1';
  vForm1.Show;
end;

procedure TForm4.Button2Click(Sender: TObject);
begin
  vForm2 := TForm.Create(Self);
  vForm2.Parent := Panel1;
  vForm2.Width := 100;
  vForm2.Align := alLeft;
  vForm2.Name := 'Form1Teste2';
  vForm2.Show;
end;

procedure TForm4.Button3Click(Sender: TObject);
begin
  if (Assigned(vForm1)) then
  begin
    ShowMessage('1 esta criado');
  end;

  if (Assigned(vForm2)) then
  begin
    ShowMessage('2 esta criado');
  end;
end;

Being vForm1 and vForm2 respectively type variables TForm that you would replace with the forms themselves!

if Assigned() Tests if an object was signed, ie if the creation occurred, if it exists. The Result is a boolean.

You can also test whether the object is different from nil which would also work. In case you would create a function to validate if the form has already been created, so avoid the code redundancy I left in the example (Button3click)!

  • Junior, thank you very much. But I still have a question, because the main point is to know which Forms is open on the screen, with the focus on it, at the moment I will open another Forms. I need to find this Forms open before opening a new one with Button1 or Button2 above. if Assigned() tells me which one is currently open?

  • I will modify the answer complementing... In case we go through the Panel Children components to know which are forms and which close!

  • Why not create a simple variable with the last form loaded?

  • Actually the best option for him is a ShowModal, let’s wait for his reaction to reading here.

  • Junio and Tiago, thank you. in the code above, when replacing Form.Show or Form.showmodal the application is locked after pressing Button2, because it opens Form2 but I do not change the focus for it and does not return to the main Form1 ! James, I thought and use this variable to store the last loaded form, that’s why I asked for help to get the name of the Visible form at the time. I adjusted the code by placing in the Onshow event of Forms that was opened Edit1.text := Screen.Activeform.Name , BUT IT DIDN’T WORK, as it always keeps the name of the Main form !!

  • Guys, I’d appreciate it if you could see my latest code.

Show 1 more comment

1

Junior and Tiago, I made an adjustment in the code and got the desired behavior. However, the Closeactiveform (Forname : String) is named after the Forms and runs a Freeandnil(form) on the corresponding Forms is very hard-coded ! Note that in the code to get the form to be closed is with several Ifs. I think there should be a better way and get the form (form variable). Can you help me with that ?

The Program There are 3 Forms with Form1 being the main one that will call form2 and form3 that will open on a panel in Form1. As soon as the form2 or form3 is opened, I show the name of the open form and I have a Check Active button that returns Screen.ActiveForm.Name

Form1 - Main ...

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses unit2, unit3;


procedure Tform1.CloseActiveForm (Formname : string);
// Free memory allocated to the current form , set it to nil
// I'll have to find a better way to perform FreeanNil without
// use many IFs command
begin
     if Formname  = 'form2' then FreeAndnil(Form2) else
         if Formname = 'form3' then FreeandNil(Form3);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
       CloseActiveForm(Edit1.Text); //Edit1 has the current active form name
       if form2 = nil  then
        begin
              Application.CreateForm(Tform2,Form2);
              Form2.Parent  := Panel1;
              Form2.Align   := alclient;

              Form2.Show;
              Form2.BorderStyle :=  bsnone;
              Form2.SetFocus;
              Form2.OnActivate(Sender);   //Method Show blocks Activate event
        //    Showmessage('Form2 is  Nil');
        end;

end;

procedure TForm1.Button2Click(Sender: TObject);
begin
       CloseActiveForm(Edit1.Text); //Edit1 has the current active form name
       if form3 = nil  then
        begin
              Application.CreateForm(Tform3,Form3);
              Form3.Parent  := Panel1;
              Form3.Align   := alclient;

              Form3.Show;
              Form3.BorderStyle := bsnone;
              Form3.SetFocus;
              Form3.OnActivate(Sender);  //Method Show blocks Activate event
          //  Showmessage('Form3 is Nil');
        end;
end;


procedure TForm1.FormActivate(Sender: TObject);
begin
   Edit1.Text := Screen.ActiveForm.Name;
end;
end.

Form2 (equals form3)

... 
   var
      Form2: TForm2;

    implementation

    {$R *.dfm}
    uses unit1;

    procedure TForm2.Button1Click(Sender: TObject);
    begin
           Edit2.Text := Screen.ActiveForm.Name;
    end;

    procedure TForm2.FormActivate(Sender: TObject);
    begin
         setfocus;
         Edit1.Text       := Form2.Name;
         Form1.Edit1.Text := Form2.Name;

    // a propriedade Screen.ActiveForm.Name se for usada trará
    // sempre o nome do Form1 - principal, porque este forms aqui
    // está com o Parent setado omo Painel1 do Forms 1 !!
    end;

    end.

Screens of the program inserir a descrição da imagem aqui

inserir a descrição da imagem aqui

Browser other questions tagged

You are not signed in. Login or sign up in order to post.