Fechar Form dentro de TabSheet

Delphi

07/10/2008

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..


Wdrocha

Wdrocha

Curtidas 0

Melhor post

Jgscarvalho

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
GOSTEI 3

Mais Respostas

Weber

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

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


GOSTEI 0
Discorpio

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:


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

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....


GOSTEI 0
Discorpio

Discorpio

07/10/2008

Olá sou eu de novo.

No último código, retire o número um dos TTabSheet1, digite somente TTabSheet.


GOSTEI 0
Wdrocha

Wdrocha

07/10/2008

Eu fiz aq um código q tah funcionando...ma não gostei mt..fiz assim...

//******************************************************************************
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

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


GOSTEI 0
Discorpio

Discorpio

07/10/2008

Boa tarde WDRocha.

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

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...


GOSTEI 0
Valdir.marcos

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


GOSTEI 0
Pedro Andrade

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 !


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

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

GOSTEI 0
Júnior Pinheiro

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



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

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);
GOSTEI 0
Emerson Nascimento

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

GOSTEI 0
Emerson Nascimento

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


GOSTEI 0
Adriano

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....


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

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.
GOSTEI 0
POSTAR