Fechar Form dentro de TabSheet
Boa tarde pessoal, eu tenho uma aplicação e abro forms dentro de TabSheets, mas qdo fecho o form a Tab continua aberta...
alguém sabe como eu faço pra fechar o form e a Tab tbm???
Mt obrigado a todos que puderem colaborar.....
No aguardo..
Vlw..
alguém sabe como eu faço pra fechar o form e a Tab tbm???
Mt obrigado a todos que puderem colaborar.....
No aguardo..
Vlw..
Wdrocha
Curtidas 0
Melhor post
Jgscarvalho
08/10/2008
Olá Pessoal, essa técnica de TDI é muito legal, aqui na empresa nos desenvolvemos um componente q funciona muito bem, vou colocar o código ai pra vcs.
esquence MDI, é muito trabalhoso isso, e a aplicação fica horrivel !
[code:1:a2f1902ab2]
unit SFormTabSet;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, Tabs, ComCtrls, Contnrs;
type
TSFormTabSet = class;
TFormInfo = class
private
FForm: TForm;
FFormTabSet: TSFormTabSet;
FTabIndex: Integer;
FFormClose: TCloseEvent;
procedure setForm(AForm: TForm);
procedure setFormTabSet(AFormTabSet: TSFormTabSet);
protected
procedure formClose(Sender: TObject; var Action: TCloseAction);
public
constructor Create(var AForm: TForm; AFormTabSet: TSFormTabSet);
procedure createTab;
function getForm: TForm;
function getFormTabSet: TSFormTabSet;
function getTabIndex: Integer;
procedure setTabIndex(const Value: Integer);
end;
TBackgroundImage = class(TImage)
public
constructor Create(AOwner: TComponent); override;
end;
TSFormTabSet = class(TCustomPanel)
private
FTabSet: TTabSet;
FDockPanel: TPanel;
FBackgroundImage: TBackgroundImage;
FForms: TObjectList;
FBackgroundColor: TColor;
FImageList: TImageList;
FFormIndex: Integer;
procedure setBackgroundColor(const Value: TColor);
procedure setBackgroundImage(const Value: TBackgroundImage);
procedure createDockPanel;
procedure createFormList;
procedure createImage(Owner: TComponent);
procedure createTabSet;
function getFormIndex(var AForm: TForm): Integer; overload;
procedure tabSetChange(Sender: TObject; NewTab: Integer;
var AllowChange: Boolean);
protected
procedure DoAddDockClient(Client: TControl; const ARect: TRect); override;
function getTabSet: TTabSet;
function getDockPanel: TPanel;
function getBackgroundImage: TBackgroundImage;
function getForms: TObjectList;
function getBackgroundColor: TColor;
function getImageList: TImageList;
function getFormIndex: Integer; overload;
procedure setFormIndex(Index: Integer);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function addForm(AForm: TForm): Integer;
function getForm(Index: Integer): TForm;
procedure removeForm(Index: Integer); overload;
procedure removeForm(AForm: TForm); overload;
property DockManager;
published
property BackgroundImage: TBackgroundImage read FBackgroundImage write setBackgroundImage;
property Align;
property Alignment;
property Anchors;
property BiDiMode;
property BackgroundColor: TColor read FBackgroundColor
write setBackgroundColor;
property Constraints;
property Ctl3D;
property Enabled;
property ParentBiDiMode;
property ParentBackground;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property OnCanResize;
property OnClick;
property OnConstrainedResize;
property OnContextPopup;
property OnDockDrop;
property OnDockOver;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnGetSiteInfo;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnResize;
property OnStartDock;
property OnStartDrag;
property OnUnDock;
end;
implementation
{ TSFormTabSet }
function TSFormTabSet.addForm(AForm: TForm): Integer;
var
FormInfo: TFormInfo;
formIndex: Integer;
begin
Result := -1;
if getFormIndex >= 0 then
TFormInfo(getForms[getFormIndex]).getForm.Hide;
formIndex := getFormIndex(AForm);
if formIndex >= 0 then
begin
getTabSet.TabIndex := TFormInfo(getForms[formIndex]).getTabIndex;
AForm.Show;
Abort;
end
else
begin
if Align <> alClient then
Align := alClient;
FormInfo := TFormInfo.Create(AForm, Self);
FormInfo.createTab;
FormInfo.getForm.Position := poDesigned;
FormInfo.getForm.Top := 0;
FormInfo.getForm.Left := 0;
FormInfo.getForm.Show;
Result := getForms.Add(FormInfo);
setFormIndex(Result);
end;
end;
constructor TSFormTabSet.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
createTabSet;
createDockPanel;
createImage(getDockPanel);
createFormList;
BevelOuter := bvNone;
Height := getTabSet.Height + 1;
setBackgroundColor(clWhite);
setFormIndex(-1);
end;
procedure TSFormTabSet.createDockPanel;
begin
FDockPanel := TPanel.Create(Self);
FDockPanel.Parent := Self;
FDockPanel.Color := clWhite;
FDockPanel.BevelOuter := bvNone;
FDockPanel.Height := 0;
FDockPanel.AutoSize := True;
FDockPanel.Align := alClient;
end;
procedure TSFormTabSet.createFormList;
begin
FForms := TObjectList.Create;
end;
procedure TSFormTabSet.createImage(Owner: TComponent);
begin
FBackgroundImage := TBackgroundImage.Create(Owner);
FBackgroundImage.Parent := TWinControl(Owner);
FBackgroundImage.Align := alClient;
end;
procedure TSFormTabSet.createTabSet;
begin
FTabSet := TTabSet.Create(Self);
FTabSet.Parent := Self;
FTabSet.Align := alTop;
FTabSet.DitherBackground := False;
FTabSet.SelectedColor := getBackgroundColor;
FTabSet.Font.Name := ´Tahoma´;
FTabSet.Height := FTabSet.TabHeight + 2;
FTabSet.OnChange := tabSetChange;
end;
destructor TSFormTabSet.Destroy;
begin
if Assigned(FForms) then
begin
FForms.Clear;
FForms.Free;
end;
inherited;
end;
procedure TSFormTabSet.DoAddDockClient(Client: TControl; const ARect: TRect);
begin
Abort;
end;
function TSFormTabSet.getBackgroundColor: TColor;
begin
Result := FBackgroundColor;
end;
function TSFormTabSet.getBackgroundImage: TBackgroundImage;
begin
Result := FBackgroundImage;
end;
function TSFormTabSet.getDockPanel: TPanel;
begin
Result := FDockPanel;
end;
function TSFormTabSet.getForm(Index: Integer): TForm;
begin
Result := TFormInfo(getForms[Index]).getForm;
end;
function TSFormTabSet.getFormIndex: Integer;
begin
Result := FFormIndex;
end;
function TSFormTabSet.getForms: TObjectList;
begin
Result := FForms;
end;
function TSFormTabSet.getImageList: TImageList;
begin
Result := FImageList;
end;
function TSFormTabSet.getTabSet: TTabSet;
begin
Result := FTabSet;
end;
function TSFormTabSet.getFormIndex(var AForm: TForm): Integer;
var
i: Integer;
FormInfo: TFormInfo;
begin
Result := -1;
for i := 0 to (getForms.Count - 1) do
begin
FormInfo := TFormInfo(getForms[i]);
if (FormInfo.getForm = AForm) then
begin
Result := i;
Break;
end;
end;
end;
procedure TSFormTabSet.removeForm(Index: Integer);
var
itemIndex, i: Integer;
begin
itemIndex := TFormInfo(getForms[Index]).getTabIndex;
getForms.Delete(Index);
getTabSet.Tabs.Delete(itemIndex);
for i := 0 to
esquence MDI, é muito trabalhoso isso, e a aplicação fica horrivel !
[code:1:a2f1902ab2]
unit SFormTabSet;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, Tabs, ComCtrls, Contnrs;
type
TSFormTabSet = class;
TFormInfo = class
private
FForm: TForm;
FFormTabSet: TSFormTabSet;
FTabIndex: Integer;
FFormClose: TCloseEvent;
procedure setForm(AForm: TForm);
procedure setFormTabSet(AFormTabSet: TSFormTabSet);
protected
procedure formClose(Sender: TObject; var Action: TCloseAction);
public
constructor Create(var AForm: TForm; AFormTabSet: TSFormTabSet);
procedure createTab;
function getForm: TForm;
function getFormTabSet: TSFormTabSet;
function getTabIndex: Integer;
procedure setTabIndex(const Value: Integer);
end;
TBackgroundImage = class(TImage)
public
constructor Create(AOwner: TComponent); override;
end;
TSFormTabSet = class(TCustomPanel)
private
FTabSet: TTabSet;
FDockPanel: TPanel;
FBackgroundImage: TBackgroundImage;
FForms: TObjectList;
FBackgroundColor: TColor;
FImageList: TImageList;
FFormIndex: Integer;
procedure setBackgroundColor(const Value: TColor);
procedure setBackgroundImage(const Value: TBackgroundImage);
procedure createDockPanel;
procedure createFormList;
procedure createImage(Owner: TComponent);
procedure createTabSet;
function getFormIndex(var AForm: TForm): Integer; overload;
procedure tabSetChange(Sender: TObject; NewTab: Integer;
var AllowChange: Boolean);
protected
procedure DoAddDockClient(Client: TControl; const ARect: TRect); override;
function getTabSet: TTabSet;
function getDockPanel: TPanel;
function getBackgroundImage: TBackgroundImage;
function getForms: TObjectList;
function getBackgroundColor: TColor;
function getImageList: TImageList;
function getFormIndex: Integer; overload;
procedure setFormIndex(Index: Integer);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function addForm(AForm: TForm): Integer;
function getForm(Index: Integer): TForm;
procedure removeForm(Index: Integer); overload;
procedure removeForm(AForm: TForm); overload;
property DockManager;
published
property BackgroundImage: TBackgroundImage read FBackgroundImage write setBackgroundImage;
property Align;
property Alignment;
property Anchors;
property BiDiMode;
property BackgroundColor: TColor read FBackgroundColor
write setBackgroundColor;
property Constraints;
property Ctl3D;
property Enabled;
property ParentBiDiMode;
property ParentBackground;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property OnCanResize;
property OnClick;
property OnConstrainedResize;
property OnContextPopup;
property OnDockDrop;
property OnDockOver;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnGetSiteInfo;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnResize;
property OnStartDock;
property OnStartDrag;
property OnUnDock;
end;
implementation
{ TSFormTabSet }
function TSFormTabSet.addForm(AForm: TForm): Integer;
var
FormInfo: TFormInfo;
formIndex: Integer;
begin
Result := -1;
if getFormIndex >= 0 then
TFormInfo(getForms[getFormIndex]).getForm.Hide;
formIndex := getFormIndex(AForm);
if formIndex >= 0 then
begin
getTabSet.TabIndex := TFormInfo(getForms[formIndex]).getTabIndex;
AForm.Show;
Abort;
end
else
begin
if Align <> alClient then
Align := alClient;
FormInfo := TFormInfo.Create(AForm, Self);
FormInfo.createTab;
FormInfo.getForm.Position := poDesigned;
FormInfo.getForm.Top := 0;
FormInfo.getForm.Left := 0;
FormInfo.getForm.Show;
Result := getForms.Add(FormInfo);
setFormIndex(Result);
end;
end;
constructor TSFormTabSet.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
createTabSet;
createDockPanel;
createImage(getDockPanel);
createFormList;
BevelOuter := bvNone;
Height := getTabSet.Height + 1;
setBackgroundColor(clWhite);
setFormIndex(-1);
end;
procedure TSFormTabSet.createDockPanel;
begin
FDockPanel := TPanel.Create(Self);
FDockPanel.Parent := Self;
FDockPanel.Color := clWhite;
FDockPanel.BevelOuter := bvNone;
FDockPanel.Height := 0;
FDockPanel.AutoSize := True;
FDockPanel.Align := alClient;
end;
procedure TSFormTabSet.createFormList;
begin
FForms := TObjectList.Create;
end;
procedure TSFormTabSet.createImage(Owner: TComponent);
begin
FBackgroundImage := TBackgroundImage.Create(Owner);
FBackgroundImage.Parent := TWinControl(Owner);
FBackgroundImage.Align := alClient;
end;
procedure TSFormTabSet.createTabSet;
begin
FTabSet := TTabSet.Create(Self);
FTabSet.Parent := Self;
FTabSet.Align := alTop;
FTabSet.DitherBackground := False;
FTabSet.SelectedColor := getBackgroundColor;
FTabSet.Font.Name := ´Tahoma´;
FTabSet.Height := FTabSet.TabHeight + 2;
FTabSet.OnChange := tabSetChange;
end;
destructor TSFormTabSet.Destroy;
begin
if Assigned(FForms) then
begin
FForms.Clear;
FForms.Free;
end;
inherited;
end;
procedure TSFormTabSet.DoAddDockClient(Client: TControl; const ARect: TRect);
begin
Abort;
end;
function TSFormTabSet.getBackgroundColor: TColor;
begin
Result := FBackgroundColor;
end;
function TSFormTabSet.getBackgroundImage: TBackgroundImage;
begin
Result := FBackgroundImage;
end;
function TSFormTabSet.getDockPanel: TPanel;
begin
Result := FDockPanel;
end;
function TSFormTabSet.getForm(Index: Integer): TForm;
begin
Result := TFormInfo(getForms[Index]).getForm;
end;
function TSFormTabSet.getFormIndex: Integer;
begin
Result := FFormIndex;
end;
function TSFormTabSet.getForms: TObjectList;
begin
Result := FForms;
end;
function TSFormTabSet.getImageList: TImageList;
begin
Result := FImageList;
end;
function TSFormTabSet.getTabSet: TTabSet;
begin
Result := FTabSet;
end;
function TSFormTabSet.getFormIndex(var AForm: TForm): Integer;
var
i: Integer;
FormInfo: TFormInfo;
begin
Result := -1;
for i := 0 to (getForms.Count - 1) do
begin
FormInfo := TFormInfo(getForms[i]);
if (FormInfo.getForm = AForm) then
begin
Result := i;
Break;
end;
end;
end;
procedure TSFormTabSet.removeForm(Index: Integer);
var
itemIndex, i: Integer;
begin
itemIndex := TFormInfo(getForms[Index]).getTabIndex;
getForms.Delete(Index);
getTabSet.Tabs.Delete(itemIndex);
for i := 0 to
GOSTEI 3
Mais Respostas
Weber
07/10/2008
É um dilema. O que acontece é que quando você fecha o Form, o mesmo é dado um Free e o TabSheet continua existindo. Você pode dar um Free no TabSheet porém, quando for criar um novo TabSheet, em determinado momento dá erro de Access Violation. Talvez fosse melhor e mais fácil você estudar a viabilidade de utilizar forms MDI.
GOSTEI 0
Wdrocha
07/10/2008
Mt obrigado pela dica Weber....
resolvi o problema....
eu tow destruindo e recriando várias vezes e não tah dando AcessViolation....
d qualquer forma...obrigado pela dica...
bom dia e vlw
resolvi o problema....
eu tow destruindo e recriando várias vezes e não tah dando AcessViolation....
d qualquer forma...obrigado pela dica...
bom dia e vlw
GOSTEI 0
Discorpio
07/10/2008
Bom dia WDRocha.
Pelo que eu entendi, você quer destruir o Form que está dentro do TabSheet logo assim que ele perde o Foco.
Se for isso, então é simples, basta utilizar o Evento OnHide do TabSheet e destruir o Form usando a propriedade Components[] que é um array de components dentro do Tabsheet, assim:
Valendo lembrar que se houver mais de um form dentro do TabSheet todos eles serão destruídos.
O porque do Evento OnHide e não OnExit ?
Sinceramente ainda não sei porque cargas d´áqua, o OnExit dos TabSheet não são disparados, pois fiz um teste aqui e não deu certo, talvez este evento esteja relacionado ao PageControl, ou seja, só são disparados quando o PageControl perde o Foco e não somente um TabSheet. Se for exatamente que estou pensando, então eu considero um erro de lógica.
Voltando ao que realmente interessa, pois o melhor e deixar a sua aplicação funcionando do jeito que queres, creio eu que voce que esse procedimento funcione em todos os TabSheets, correto ?
Será que eu terei que configurar os Eventos OnHide de cada TabSheet :?:
A resposta e não, basta voce escrever apenas um Procedure e direcionar todos os Eventos OnHide para esta única procedure, desde que ela tenha os mesmos parâmetros do Evento OnHide original, pode até ter nome diferente, porém o nome e o tipo dos parâmetros tem que ser os mesmos:
primeiramente declare uma procedure fora dos blocos Private e Public da Classe do Formulário onde se encontra o seu PageControl, porém tem que ser dentro da Classe, assim:
Coloque o código dentro da procedure recém criada, assim:
Agora click em cada TabSheet e vá no Object Inspector e na aba Events, vá no Evento OnHide e aponte para tsHide.
Pronto, em qualquer TabSheet que voce colocar Form, ao perder o Foco, destruir os Forms contidos nela.
Pelo que eu entendi, você quer destruir o Form que está dentro do TabSheet logo assim que ele perde o Foco.
Se for isso, então é simples, basta utilizar o Evento OnHide do TabSheet e destruir o Form usando a propriedade Components[] que é um array de components dentro do Tabsheet, assim:
procedure TForm3.TabSheet1Hide(Sender: TObject); var I: Integer; begin for I := 0 to Pred(TabSheet1.ComponentCount) do begin if TabSheet1.Components[I] is TForm then TForm(TabSheet1.Components[I]).Free; end; end;
Valendo lembrar que se houver mais de um form dentro do TabSheet todos eles serão destruídos.
O porque do Evento OnHide e não OnExit ?
Sinceramente ainda não sei porque cargas d´áqua, o OnExit dos TabSheet não são disparados, pois fiz um teste aqui e não deu certo, talvez este evento esteja relacionado ao PageControl, ou seja, só são disparados quando o PageControl perde o Foco e não somente um TabSheet. Se for exatamente que estou pensando, então eu considero um erro de lógica.
Voltando ao que realmente interessa, pois o melhor e deixar a sua aplicação funcionando do jeito que queres, creio eu que voce que esse procedimento funcione em todos os TabSheets, correto ?
Será que eu terei que configurar os Eventos OnHide de cada TabSheet :?:
A resposta e não, basta voce escrever apenas um Procedure e direcionar todos os Eventos OnHide para esta única procedure, desde que ela tenha os mesmos parâmetros do Evento OnHide original, pode até ter nome diferente, porém o nome e o tipo dos parâmetros tem que ser os mesmos:
primeiramente declare uma procedure fora dos blocos Private e Public da Classe do Formulário onde se encontra o seu PageControl, porém tem que ser dentro da Classe, assim:
type
TForm3 = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
TabSheet3: TTabSheet;
BitBtn1: TBitBtn;
procedure BitBtn1Click(Sender: TObject);
procedure TabSheet1Hide(Sender: TObject);
.....
.....
[color=darkblue:8032897a14] procedure tsHide(Sender: TObject);[/color:8032897a14]
private
{ Private declarations }
Form: TForm;
public
{ Public declarations }
end;
Coloque o código dentro da procedure recém criada, assim:
procedure TForm3.tsHide(Sender: TObject); var I: Integer; begin for I := 0 to Pred(TTabSheet(Sender).ComponentCount) do begin if TTabSheet1(Sender).Components[I] is TForm then TForm(TTabSheet1(Sender).Components[I]).Free; end; end;
Agora click em cada TabSheet e vá no Object Inspector e na aba Events, vá no Evento OnHide e aponte para tsHide.
Pronto, em qualquer TabSheet que voce colocar Form, ao perder o Foco, destruir os Forms contidos nela.
GOSTEI 0
Wdrocha
07/10/2008
Bom dia Discorpio.....
é quase isso q eu quero...ao invés d fechar a tab qdo a mesma perder o focus..eu quero fechar qdo, por exemplo...
Um form de cadastros....o usário faz o cadastro e qdo clicar em Concluir...será fechado o form e a tab em q o mesmo está contido....
mas se o usuário abrir uma tab e mudar para outra...a mesma continuaria aberta....
é quase isso q eu quero...ao invés d fechar a tab qdo a mesma perder o focus..eu quero fechar qdo, por exemplo...
Um form de cadastros....o usário faz o cadastro e qdo clicar em Concluir...será fechado o form e a tab em q o mesmo está contido....
mas se o usuário abrir uma tab e mudar para outra...a mesma continuaria aberta....
GOSTEI 0
Discorpio
07/10/2008
Olá sou eu de novo.
No último código, retire o número um dos TTabSheet1, digite somente TTabSheet.
No último código, retire o número um dos TTabSheet1, digite somente TTabSheet.
GOSTEI 0
Wdrocha
07/10/2008
Eu fiz aq um código q tah funcionando...ma não gostei mt..fiz assim...
e na hora de fechar o Form q tah aberto dentro da TabSheet eu faço assim...
Mas não gostei mt....pq tow passando o PageControl do form principal..
vc acha q pod ser melhor??
Vlw
//****************************************************************************** Procedure FechaTab (Var PageControl : TPageControl); Var Tab : TTabSheet; Begin Tab := PageControl.ActivePage; If Assigned (Tab) Then Begin Tab.Parent := Nil; Tab.PageControl := Nil; End; End; //******************************************************************************
e na hora de fechar o Form q tah aberto dentro da TabSheet eu faço assim...
NomeDoForm.Close; FechaTab(FormQueContémPageControl.PageControl);
Mas não gostei mt....pq tow passando o PageControl do form principal..
vc acha q pod ser melhor??
Vlw
GOSTEI 0
Wdrocha
07/10/2008
Olá jgscarvalho, vc tem como enviar este componente por email....caso não haja algum empecilho por parte da empresa???
Vlw
Vlw
GOSTEI 0
Discorpio
07/10/2008
Boa tarde WDRocha.
Quanto ao código que voce passou, melhor ficaria assim:
Agora pensando melhor, se o Form está dentro de uma TabSheet, ou seja, está sendo criado como seu proprietário ´FormCad := TFormCad.Create(TabSheet)´ e FormCad.parent := TabSheet, isto significa dizer que voce não precisa destruir o Form. Basta apenas destruir o objeto Container do Form, ou seja o TabSheet somente, que todos os objetos contidos no TabSheet serão automaticamente destruídos.
Como :?:
Lá no botão concluir do Form, voce simplesmente digita uma única linha de código, aliás se preferir, duas, uma para fechar o Form e a outra para destruir o TabSheet, assim:
Isto é claro, voce terá que declarar a Unit do Form Principal na seção Uses do form de cadastro, já que o seu PageControl está no Form Principal.
Ou se preferir continuar usando o código que voce passou, entretanto se o PageControl estiver no Form Principal, então voce terá que de qualquer jeito, fazer o que vinha fazendo, ou seja, passar o PageControl do Form Principal como referência.
Agora cá pra nós, o nosso amigo Jgscarvalho postou o código de um componente criado por ele, o qual achei bastante interessante, vou colocá-lo dentro de um Package (Pacote) e instalar o componente dele aqui no meu Delphi 2007, e vou testá-lo.
Acredito que o Componente dele possa ser a solução do seu problema, mais ou menos a Lei de Murphy ao contrário, ou seja:
[color=darkblue:2b54ca9299]´Se algo pode dar certo, ...com certeza dará certo´[/color:2b54ca9299]
Quanto ao código que voce passou, melhor ficaria assim:
Procedure FechaTab (Var PageControl : TPageControl); Var Tab : TTabSheet; Begin Tab := PageControl.ActivePage; If Assigned (Tab) Then Begin FreeAndNil(Tab.Parent); FreeAndNil(Tab.PageControl); End; End;
Agora pensando melhor, se o Form está dentro de uma TabSheet, ou seja, está sendo criado como seu proprietário ´FormCad := TFormCad.Create(TabSheet)´ e FormCad.parent := TabSheet, isto significa dizer que voce não precisa destruir o Form. Basta apenas destruir o objeto Container do Form, ou seja o TabSheet somente, que todos os objetos contidos no TabSheet serão automaticamente destruídos.
Como :?:
Lá no botão concluir do Form, voce simplesmente digita uma única linha de código, aliás se preferir, duas, uma para fechar o Form e a outra para destruir o TabSheet, assim:
procedure TForm3.btnConcluirClick(Sender: TObject); begin .... .... Self.Close; FormPrincipal.PageControl.ActivePage.Free; end;
Isto é claro, voce terá que declarar a Unit do Form Principal na seção Uses do form de cadastro, já que o seu PageControl está no Form Principal.
Ou se preferir continuar usando o código que voce passou, entretanto se o PageControl estiver no Form Principal, então voce terá que de qualquer jeito, fazer o que vinha fazendo, ou seja, passar o PageControl do Form Principal como referência.
Agora cá pra nós, o nosso amigo Jgscarvalho postou o código de um componente criado por ele, o qual achei bastante interessante, vou colocá-lo dentro de um Package (Pacote) e instalar o componente dele aqui no meu Delphi 2007, e vou testá-lo.
Acredito que o Componente dele possa ser a solução do seu problema, mais ou menos a Lei de Murphy ao contrário, ou seja:
[color=darkblue:2b54ca9299]´Se algo pode dar certo, ...com certeza dará certo´[/color:2b54ca9299]
GOSTEI 0
Wdrocha
07/10/2008
Discorpio...obrigado pela dica....acho melhor fazer como vc falow...
E qto ao componente do colega...qdo vc colocar no pacote...vc pod , por favor, enviar pra mim tbm??
No aguardo....obrigado...
E qto ao componente do colega...qdo vc colocar no pacote...vc pod , por favor, enviar pra mim tbm??
No aguardo....obrigado...
GOSTEI 0
Valdir.marcos
07/10/2008
Baixei o exemplo da Revista Club Delphi 74 ( https://www.devmedia.com.br/clubedelphi/downloads/Ed_74.htm ), mas falta o exemplo não compila por falta do arquivo FormFactory.pas ...
Alguém poderia me enviar esse arquivo?
Meu email é valdir.marcos(arroba)pop.com.br
Alguém poderia me enviar esse arquivo?
Meu email é valdir.marcos(arroba)pop.com.br
GOSTEI 0
Pedro Andrade
07/10/2008
Olá Pessoal, essa técnica de TDI é muito legal, aqui na empresa nos desenvolvemos um componente q funciona muito bem, vou colocar o código ai pra vcs.
esquence MDI, é muito trabalhoso isso, e a aplicação fica horrivel !
esquence MDI, é muito trabalhoso isso, e a aplicação fica horrivel !
unit SFormTabSet; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Tabs, ComCtrls, Contnrs; type TSFormTabSet = class; TFormInfo = class private FForm: TForm; FFormTabSet: TSFormTabSet; FTabIndex: Integer; FFormClose: TCloseEvent; procedure setForm(AForm: TForm); procedure setFormTabSet(AFormTabSet: TSFormTabSet); protected procedure formClose(Sender: TObject; var Action: TCloseAction); public constructor Create(var AForm: TForm; AFormTabSet: TSFormTabSet); procedure createTab; function getForm: TForm; function getFormTabSet: TSFormTabSet; function getTabIndex: Integer; procedure setTabIndex(const Value: Integer); end; TBackgroundImage = class(TImage) public constructor Create(AOwner: TComponent); override; end; TSFormTabSet = class(TCustomPanel) private FTabSet: TTabSet; FDockPanel: TPanel; FBackgroundImage: TBackgroundImage; FForms: TObjectList; FBackgroundColor: TColor; FImageList: TImageList; FFormIndex: Integer; procedure setBackgroundColor(const Value: TColor); procedure setBackgroundImage(const Value: TBackgroundImage); procedure createDockPanel; procedure createFormList; procedure createImage(Owner: TComponent); procedure createTabSet; function getFormIndex(var AForm: TForm): Integer; overload; procedure tabSetChange(Sender: TObject; NewTab: Integer; var AllowChange: Boolean); protected procedure DoAddDockClient(Client: TControl; const ARect: TRect); override; function getTabSet: TTabSet; function getDockPanel: TPanel; function getBackgroundImage: TBackgroundImage; function getForms: TObjectList; function getBackgroundColor: TColor; function getImageList: TImageList; function getFormIndex: Integer; overload; procedure setFormIndex(Index: Integer); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function addForm(AForm: TForm): Integer; function getForm(Index: Integer): TForm; procedure removeForm(Index: Integer); overload; procedure removeForm(AForm: TForm); overload; property DockManager; published property BackgroundImage: TBackgroundImage read FBackgroundImage write setBackgroundImage; property Align; property Alignment; property Anchors; property BiDiMode; property BackgroundColor: TColor read FBackgroundColor write setBackgroundColor; property Constraints; property Ctl3D; property Enabled; property ParentBiDiMode; property ParentBackground; property ParentColor; property ParentCtl3D; property ParentFont; property ParentShowHint; property PopupMenu; property ShowHint; property TabOrder; property TabStop; property Visible; property OnCanResize; property OnClick; property OnConstrainedResize; property OnContextPopup; property OnDockDrop; property OnDockOver; property OnDblClick; property OnDragDrop; property OnDragOver; property OnEndDock; property OnEndDrag; property OnEnter; property OnExit; property OnGetSiteInfo; property OnMouseDown; property OnMouseMove; property OnMouseUp; property OnResize; property OnStartDock; property OnStartDrag; property OnUnDock; end; implementation { TSFormTabSet } function TSFormTabSet.addForm(AForm: TForm): Integer; var FormInfo: TFormInfo; formIndex: Integer; begin Result := -1; if getFormIndex >= 0 then TFormInfo(getForms[getFormIndex]).getForm.Hide; formIndex := getFormIndex(AForm); if formIndex >= 0 then begin getTabSet.TabIndex := TFormInfo(getForms[formIndex]).getTabIndex; AForm.Show; Abort; end else begin if Align <> alClient then Align := alClient; FormInfo := TFormInfo.Create(AForm, Self); FormInfo.createTab; FormInfo.getForm.Position := poDesigned; FormInfo.getForm.Top := 0; FormInfo.getForm.Left := 0; FormInfo.getForm.Show; Result := getForms.Add(FormInfo); setFormIndex(Result); end; end; constructor TSFormTabSet.Create(AOwner: TComponent); begin inherited Create(AOwner); createTabSet; createDockPanel; createImage(getDockPanel); createFormList; BevelOuter := bvNone; Height := getTabSet.Height + 1; setBackgroundColor(clWhite); setFormIndex(-1); end; procedure TSFormTabSet.createDockPanel; begin FDockPanel := TPanel.Create(Self); FDockPanel.Parent := Self; FDockPanel.Color := clWhite; FDockPanel.BevelOuter := bvNone; FDockPanel.Height := 0; FDockPanel.AutoSize := True; FDockPanel.Align := alClient; end; procedure TSFormTabSet.createFormList; begin FForms := TObjectList.Create; end; procedure TSFormTabSet.createImage(Owner: TComponent); begin FBackgroundImage := TBackgroundImage.Create(Owner); FBackgroundImage.Parent := TWinControl(Owner); FBackgroundImage.Align := alClient; end; procedure TSFormTabSet.createTabSet; begin FTabSet := TTabSet.Create(Self); FTabSet.Parent := Self; FTabSet.Align := alTop; FTabSet.DitherBackground := False; FTabSet.SelectedColor := getBackgroundColor; FTabSet.Font.Name := ´Tahoma´; FTabSet.Height := FTabSet.TabHeight + 2; FTabSet.OnChange := tabSetChange; end; destructor TSFormTabSet.Destroy; begin if Assigned(FForms) then begin FForms.Clear; FForms.Free; end; inherited; end; procedure TSFormTabSet.DoAddDockClient(Client: TControl; const ARect: TRect); begin Abort; end; function TSFormTabSet.getBackgroundColor: TColor; begin Result := FBackgroundColor; end; function TSFormTabSet.getBackgroundImage: TBackgroundImage; begin Result := FBackgroundImage; end; function TSFormTabSet.getDockPanel: TPanel; begin Result := FDockPanel; end; function TSFormTabSet.getForm(Index: Integer): TForm; begin Result := TFormInfo(getForms[Index]).getForm; end; function TSFormTabSet.getFormIndex: Integer; begin Result := FFormIndex; end; function TSFormTabSet.getForms: TObjectList; begin Result := FForms; end; function TSFormTabSet.getImageList: TImageList; begin Result := FImageList; end; function TSFormTabSet.getTabSet: TTabSet; begin Result := FTabSet; end; function TSFormTabSet.getFormIndex(var AForm: TForm): Integer; var i: Integer; FormInfo: TFormInfo; begin Result := -1; for i := 0 to (getForms.Count - 1) do begin FormInfo := TFormInfo(getForms[i]); if (FormInfo.getForm = AForm) then begin Result := i; Break; end; end; end; procedure TSFormTabSet.removeForm(Index: Integer); var itemIndex, i: Integer; begin itemIndex := TFormInfo(getForms[Index]).getTabIndex; getForms.Delete(Index); getTabSet.Tabs.Delete(itemIndex); for i := 0 to (getForms.Count - 1) do begin if TFormInfo(getForms[i]).getTabIndex > itemIndex then TFormInfo(getForms[i]).setTabIndex( TFormInfo(getForms[i]).getTabIndex - 1); end; if (itemIndex = 0) and (getTabSet.Tabs.Count > 0) then getTabSet.TabIndex := itemIndex else getTabSet.TabIndex := Pred(itemIndex); if (Index = 0) and (getForms.Count > 0) then setFormIndex(Index) else setFormIndex(Pred(Index)); if getFormIndex >= 0 then TFormInfo(getForms[getFormIndex]).getForm.Show; end; procedure TSFormTabSet.removeForm(AForm: TForm); var i: Integer; begin for i := 0 to (getForms.Count - 1) do begin if TFormInfo(getForms[i]).getForm = AForm then begin removeForm(i); Break; end; end; end; procedure TSFormTabSet.setBackgroundColor(const Value: TColor); begin if FBackgroundColor <> Value then begin FBackgroundColor := Value; getDockPanel.Color := getBackgroundColor; getTabSet.SelectedColor := getBackgroundColor; end; end; procedure TSFormTabSet.setBackgroundImage(const Value: TBackgroundImage); begin FBackgroundImage.Assign(Value); end; procedure TSFormTabSet.setFormIndex(Index: Integer); begin FFormIndex := Index; end; procedure TSFormTabSet.tabSetChange(Sender: TObject; NewTab: Integer; var AllowChange: Boolean); var i: Integer; FormInfo: TFormInfo; begin for i := 0 to (getForms.Count - 1) do begin FormInfo := TFormInfo(getForms[i]); if FormInfo.getTabIndex = NewTab then begin TFormInfo(getForms[getFormIndex]).getForm.Hide; FormInfo.getForm.Show; setFormIndex(i); end; end; end; { TFormInfo } constructor TFormInfo.Create(var AForm: TForm; AFormTabSet: TSFormTabSet); begin setForm(AForm); FFormClose := AForm.OnClose; AForm.OnClose := formClose; setFormTabSet(AFormTabSet); setTabIndex(-1); end; procedure TFormInfo.createTab; begin if getTabIndex = -1 then begin setTabIndex(getFormTabSet.getTabSet.Tabs.Add(FForm.Caption)); getFormTabSet.getTabSet.TabIndex := getTabIndex; end; getForm.ManualDock(FFormTabSet.getDockPanel); end; procedure TFormInfo.formClose(Sender: TObject; var Action: TCloseAction); begin if Assigned(FFormClose) then FFormClose(Sender, Action); if Action <> caNone then begin if Sender is TForm then begin getFormTabSet.removeForm(TForm(Sender)); TForm(Sender).OnClose := FFormClose; end; end; end; function TFormInfo.getForm: TForm; begin Result := FForm; end; function TFormInfo.getFormTabSet: TSFormTabSet; begin Result := FFormTabSet; end; function TFormInfo.getTabIndex: Integer; begin Result := FTabIndex; end; procedure TFormInfo.setForm(AForm: TForm); begin FForm := AForm; end; procedure TFormInfo.setFormTabSet(AFormTabSet: TSFormTabSet); begin FFormTabSet := AFormTabSet; end; procedure TFormInfo.setTabIndex(const Value: Integer); begin FTabIndex := Value; end; { TBackgroundImage } constructor TBackgroundImage.Create(AOwner: TComponent); begin inherited Create(AOwner); SetSubComponent(True); end; end.
GOSTEI 0
Pedro Andrade
07/10/2008
Enviei antes de escrever, gostei desta ideia, sei que o post é antigo, por isso queria saber se voces ainda usam este modelo TDI ou não deu certo, se sim, como usar este componente.
Obrigado
Obrigado
GOSTEI 0
Júnior Pinheiro
07/10/2008
Enviei antes de escrever, gostei desta ideia, sei que o post é antigo, por isso queria saber se voces ainda usam este modelo TDI ou não deu certo, se sim, como usar este componente.
Obrigado
Obrigado
olá amigo Pedro, vc teria um mini exemplo de como usar? se possívei por favor, com um form principal e um form 2 abrindo dentro de um tab no form principal, obrigado mesmo.
GOSTEI 0
Fabio Palagar
07/10/2008
Eu criei uma TDI para abrir os forms em abas. consegui colocar um botão para fechar o formulário de forma muito simples. Inseri o seguinte código no onclick do botão:
FTDI.Fechar(true);
FTDI.Fechar(true);
GOSTEI 0
Emerson Nascimento
07/10/2008
tem um artigo muito, muito bom, aqui mesmo no devmedia.
https://www.devmedia.com.br/artigo-clube-delphi-74-aplicacoes-tdi/12027
pra baixar os fontes:
https://videos.web-03.net/artigos/Wesley_Yamazack/Artigos/Fontes_ED_10_CD_Delphi-TDI.zip
https://www.devmedia.com.br/artigo-clube-delphi-74-aplicacoes-tdi/12027
pra baixar os fontes:
https://videos.web-03.net/artigos/Wesley_Yamazack/Artigos/Fontes_ED_10_CD_Delphi-TDI.zip
GOSTEI 0
Emerson Nascimento
07/10/2008
na verdade o artigo é esse aqui:
https://www.devmedia.com.br/artigo-clube-delphi-110-formularios-em-abas/14379
pra baixar os fontes:
https://videos.web-03.net/artigos/Wesley_Yamazack/Artigos/Fontes_ED_10_CD_Delphi-TDI.zip
https://www.devmedia.com.br/artigo-clube-delphi-110-formularios-em-abas/14379
pra baixar os fontes:
https://videos.web-03.net/artigos/Wesley_Yamazack/Artigos/Fontes_ED_10_CD_Delphi-TDI.zip
GOSTEI 0
Adriano
07/10/2008
Bom dia Discorpio.....
é quase isso q eu quero...ao invés d fechar a tab qdo a mesma perder o focus..eu quero fechar qdo, por exemplo...
Um form de cadastros....o usário faz o cadastro e qdo clicar em Concluir...será fechado o form e a tab em q o mesmo está contido....
mas se o usuário abrir uma tab e mudar para outra...a mesma continuaria aberta....
é quase isso q eu quero...ao invés d fechar a tab qdo a mesma perder o focus..eu quero fechar qdo, por exemplo...
Um form de cadastros....o usário faz o cadastro e qdo clicar em Concluir...será fechado o form e a tab em q o mesmo está contido....
mas se o usuário abrir uma tab e mudar para outra...a mesma continuaria aberta....
Encontrei uma solução bem mais fácil de implementar.
ao final da implementação do botão concluir coloque:
close;//fecha o form atual
tpagecontrol(Self.Parent.Parent).Pages[ tpagecontrol(Self.Parent.Parent).ActivePageIndex].Free; //libera a tab criada pelo TTdi
GOSTEI 0
Arthur Heinrich
07/10/2008
Todo componente possui duas propriedades: Owner e Parent
O Owner é o "dono" do componente. Se você destroi o dono, usando o método Free, todos os componentes que pertencem a ele também são destruídos.
O Parent é o componente no qual ele é exibido. Para que um form apareça dentro de um tabsheet, o form.parent precisa ser o tabsheet.
Ao criar o form, teralmente fazemos TForm.Create(Owner).
Ao fazer TForm.Create(TabSheet), o tabsheet passa a ser o dono do form. Logo, destruindo apenas o tabsheet com o método Free, o form também é destruído.
Se você atribui ambos ao TabSheet:
Form:=TForm.Create(TabSheet);
Form.Parent:=TabSheet;
O forma passa a pertencer ao TabSheet e é exibido nele.
Para destruir tudo, bastaria fazer TabSheet.Free;
Ou, no seu caso, em que está em algumn método do Form, poderia imaginar em fazer Form.Parent.Free;
O problema aqui é que, ao destruir o TabSheet, o controle de execução volta para o método do form que não existe mais. Qualquer referência a uma propriedade do forma pode ocasionar um Access Violation.
Uma outra possibilidade seria fazer um Form.Close, utilizando o método OnClose e setando o patâmetro Action:=caFree. Porém, embora isto libere o Form corretamente, ele apenas o exclui da lista de componentes pertencentes ao TabSheet, que permanece ativo.
É complicado.
Talvez dê para armazenar o TabSheet em uma lista de TabSheets ou componentes a serem excluídos e, através de um timer, varrer a lista e ir liberando. Como o evento do timer será executado posteriormente, depois de sair do método do Form, acho que daria para excluir sem problema.
O Owner é o "dono" do componente. Se você destroi o dono, usando o método Free, todos os componentes que pertencem a ele também são destruídos.
O Parent é o componente no qual ele é exibido. Para que um form apareça dentro de um tabsheet, o form.parent precisa ser o tabsheet.
Ao criar o form, teralmente fazemos TForm.Create(Owner).
Ao fazer TForm.Create(TabSheet), o tabsheet passa a ser o dono do form. Logo, destruindo apenas o tabsheet com o método Free, o form também é destruído.
Se você atribui ambos ao TabSheet:
Form:=TForm.Create(TabSheet);
Form.Parent:=TabSheet;
O forma passa a pertencer ao TabSheet e é exibido nele.
Para destruir tudo, bastaria fazer TabSheet.Free;
Ou, no seu caso, em que está em algumn método do Form, poderia imaginar em fazer Form.Parent.Free;
O problema aqui é que, ao destruir o TabSheet, o controle de execução volta para o método do form que não existe mais. Qualquer referência a uma propriedade do forma pode ocasionar um Access Violation.
Uma outra possibilidade seria fazer um Form.Close, utilizando o método OnClose e setando o patâmetro Action:=caFree. Porém, embora isto libere o Form corretamente, ele apenas o exclui da lista de componentes pertencentes ao TabSheet, que permanece ativo.
É complicado.
Talvez dê para armazenar o TabSheet em uma lista de TabSheets ou componentes a serem excluídos e, através de um timer, varrer a lista e ir liberando. Como o evento do timer será executado posteriormente, depois de sair do método do Form, acho que daria para excluir sem problema.
GOSTEI 0