Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Bom dia pessoal,
Preciso abrir o mesmo form varias vezes simultaneamente.
Tipo, eu exibo um grid que pode ser gerado um grafico com dados apresentados, pode ser alterado alguns valores no grid e o grafico é atualizado, daí
o usuario pode abrir uma nova tela do mesmo form e mudar outros valores e gerar grafico diferente, e comparar os dois.
Usando apenas show para exibir o form ele não abre dois.
Tem a ver com SDI?
desde já, agradeço quem puder colaborar.
>
Não sei se eu entendi corretamente, mas me parece que o colega que fazer um form que possa ser chamado recursivamente dentro de outro form, seria isto?
[]'s
Isto, pois preciso poder ter aberto ao mesmo tempo varias telas do mesmo form, porque preciso comparar os graficos gerados para os mesmos dados com filtros diferentes. e visualizá-los ao mesmo tempo.
Se for fazer isso, você tem em mente uma limitação máxima de quantas vezes o mesmo form vai ser aberto? Abrir um form recursivamente sem um limite máximo pode não ser muito bom, por questão de performance.
Geralmente são analisados vários cenários simultaneamente, atualmente eles usam excel e costumam trabalhar com uma média de 20 planilhas com graficos resultantes de filtros variados na mesma base.
Bom, vou por um exemplo aqui bem básico de como criar forms recursivos.... para este exemplo, usaremos dois forms (que nomeei aqui como unit1 e unit2 mesmo). No Form1, teremos um PageControl com 3 abas (que você depois pode adaptar para o seu código), que vai chamar o form2 como parte do form1 e permitir inclusive a manipulação dos dados entre os forms criados.
Segue abaixo os códigos das units e dos forms...
Unit1.pas
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, unit2,
StdCtrls, ExtCtrls, ComCtrls;
type
TForm1 = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
Panel1: TPanel;
Button1: TButton;
Panel2: TPanel;
Button2: TButton;
TabSheet3: TTabSheet;
Panel3: TPanel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
texto : string;
U1 : TForm2;
U2 : TForm2;
U3 : TForm2;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
U2 := TForm2.Create(Self).Execute(Panel2, U1.Edit1.Text + 'Texto 2');
TabSheet2.TabVisible := True;
PageControl1.ActivePageIndex := 1;
showmessage(U1.Edit1.Text);
end;
procedure TForm1.Button2Click(Sender: TObject); U3 := TForm2.Create(Self).Execute(Panel3, U2.Edit1.Text + 'Texto 3');
TabSheet3.TabVisible := True;
PageControl1.ActivePageIndex := 2;
end;
procedure TForm1.FormShow(Sender: TObject); U1 := TForm2.Create(Self).Execute(Panel1, 'Texto 1');
PageControl1.ActivePageIndex := 0;
TabSheet2.TabVisible := False;
TabSheet3.TabVisible := False;
end;
end.
Unit1.dfm
object Form1: TForm1
Left = 192
Top = 108
Width = 696
Height = 480
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object PageControl1: TPageControl
Left = 32
Top = 32
Width = 289
Height = 233
ActivePage = TabSheet3
TabOrder = 0
object TabSheet1: TTabSheet
Caption = 'TabSheet1'
object Panel1: TPanel
Left = 0
Top = 0
Width = 281
Height = 165
Align = alTop
Caption = 'Panel1'
TabOrder = 0
end
object Button1: TButton
Left = 200
Top = 172
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 1
OnClick = Button1Click
end
end
object TabSheet2: TTabSheet
Caption = 'TabSheet2'
ImageIndex = 1
object Panel2: TPanel
Left = 0
Top = 0
Width = 281
Height = 165
Align = alTop
Caption = 'Panel1'
TabOrder = 0
end
object Button2: TButton
Left = 200
Top = 172
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 1
OnClick = Button2Click
end
end
object TabSheet3: TTabSheet
Caption = 'TabSheet3'
ImageIndex = 2
object Panel3: TPanel
Left = 0
Top = 0
Width = 281
Height = 205
Align = alClient
Caption = 'Panel1'
TabOrder = 0
end
end
end
end
Unit2.pas
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm2 = class(TForm)
Label1: TLabel;
Edit1: TEdit;
private
{ Private declarations }
public
{ Public declarations }
Function Execute(Parent: TWinControl; Texto : String):TForm2;
end;
var
Form2: TForm2;
implementation
{$R *.DFM}
{ TForm2 }
Function TForm2.Execute(Parent: TWinControl; Texto : String):TForm2;
begin
Self.Parent:=Parent;
BorderStyle:=bsNone; // Can be set at design time
Align:=alClient; // Can be set at design TimeSeparator
Self.Edit1.Text := Texto;
result := Self;
Show;
end;
end.
Unit2.dfm
object Form2: TForm2
Left = 192
Top = 108
Width = 418
Height = 369
Caption = 'Form2'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
Position = poDefault
Visible = True
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 32
Top = 24
Width = 32
Height = 13
Caption = 'Label1'
end
object Edit1: TEdit
Left = 88
Top = 24
Width = 121
Height = 21
TabOrder = 0
Text = 'Edit1'
end
end
Como você poderá ver, o exemplo aqui é bem simples... acho que você consegue adaptar para as suas necessidades.
[]'s
beleza, vou testar e depois posto o resultado
Chrnos, eu to usando o delphi 2007
não sei se tem alguma diferença, mas da erro na seguinte linha:
U1 := TForm2.Create(Self);//.Execute(Panel1, 'Texto 1');
quando deixo comentado onde está execute.... roda normalmente.
mas isso não me atrapalha nada, pois depois de testar do jeito que você postou eu alterei para dar um show no form instanciado e consegui abrir varios e usar filtros diferentes, assim pude comparar os resultados de acordo com os filtros, sem ter q fechar uma para abrir outra.
pelo q vi o segredo era mesmo em criar uma nova instancia do form:
U1 : TForm2;
...
U2 := TForm2.Create(Self)
correto?
Obrigado.
Sim e não... o exemplo que eu fiz, ao invés de abrir multiplos forms, cria os mesmos e joga eles dentro de um painel que está dentro de um TTabSheet do pagecontrol... assim, eu teria numa mesma tela N forms abertos simultaneos, um em cada sheet. Associando eles a uma variável (U1, U2, U3.. UN), você pode enviar dados entre os forms e controlar o que quiser neles.
Se você observar, a função Execute que coloquei na Unit2 é que faz a "mágica", ao ligar o Parent do form2 ao panel que eu enviei como parâmetro na passagem da procedure.
Uma coisa que não está neste código e que é necessária é, quando fechar a Unit1, dar um FreeAndNil para cada form que foi criado.
Como eu disse, esse é um exemplo bem cru de como criar um form recursivo... com base nisso eu já criei relatórios recursivos que faziam detalhamentos recursivos, enviando para cada TTabSheet criada os filtros já utilizados anteriormente para usá-los combinados aos filtros que ainda estavam disponíveis no detalhamento.
Posta ai como fez seu código para que eu possa comentar algo se quiser.
[]'s
Chrnos, nem preciso postar, pois eu tava comendo bola.
Não havia percebido a função execute, por isso deu erro, pensei que era alguma função nativa q não tava funfando.
então sem usar o execute, eu tava só instanciando: U2 := TForm2.Create(Self)
e dando u2.show.
funciona, mas fica estranho, um monte de form aberto.
já com seu exemplo, não preciso dar show, pois a execute já faz isto e como ligou o Parent do form2 ao panel:Self.Parent:=Parent;
ele abre no panel dentro do pagecontrol, e ficou muito mais elegante.
agora só uma dúvida:
eu não to conseguindo deixar cada panel dentro de um tabsheet, aparece todos ao mesmo tempo, independente do tabsheet ativo, o q tenho q arrumar?
Pode explicar melhor o que está acontecendo? Talvez com uma imagem do problema pra ajudar a clarear?
[]'s
da pra faze sim cara
crie o seu form (suponhamos que seja o Form2, na Unit2 do seu projeto.Repare como o delphi "cria" uma classe "TForm2" que extende a classe "TForm");
bom, va na sua uni1 (ou na unit que vai chamar o formulario) e crie um vetor deste tipo (TForm2)
uses
Unit2;
var
formularios : array of TForm2
agora utilize "setLength" para dimensionar o seu vetor dinamicamente (Ex.: setLength(formularios, 10));
bom, agora para cada posição do vetor você precisa instanciar o objeto e exibir na tela
formularios[1] := TForm2.Create(nil);
formularios[1].Show;
formularios[2] := TForm2.Create(nil);
formularios[2].Show;
formularios[3] := TForm2.Create(nil);
formularios[3].Show;
formularios[4] := TForm2.Create(nil);
formularios[4].Show;
formularios[5] := TForm2.Create(nil);
formularios[5].Show;
...
Bom, espero que ajude.
Só tome cuidado com vetores dinamicos, em Delphi, eles costumar ocupar "mmmuuuita" memória
Não sei se eu entendi corretamente, mas me parece que o colega que fazer um form que possa ser chamado recursivamente dentro de outro form, seria isto?
[]'s