Tempo fa avevo preso spunto dalla soluzione proposta da Marco, che ringrazio ancora. L'accrocchio (perchè non sono un bravo programmatore) funzionava come ci si aspetta, tuttavia sono sicuro si possa migliorare. Approfitto quindi per condividere la soluzione.
Alla base c'è un Frame-modello nel quale sono definite le funzionalità standard e da cui derivano i Frame veri e propri che costituiscono l'applicazione a pagine.
Questo il codice:
****************************************
unit FraPaginaModello;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ToolWin, PngImageList, ImgList, ExtCtrls;
type
TPaginaModello = class(TFrame)
tlb: TToolBar;
tlbSalva: TToolButton;
private
{ Private declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
TPaginaFrame = class of TPaginaModello;
implementation
Uses
FormA, Modulo1, FraPaginaHome;
constructor TPaginaModello.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// codice di apertura
end;
destructor TPaginaModello.Destroy;
begin
// codice di chiusura
inherited;
end;
{$R *.dfm}
end.
****************************************
Qui un Frame ereditato (una pagina vera e propria dell'applicazione):
****************************************
unit FraPaginaProtocolli;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, FraPaginaModello, ComCtrls, ToolWin, ExtCtrls, Grids, StdCtrls;
type
TPaginaProtocolli = class(TPaginaModello)
panMobile: TPanel;
tlbChiudi: TToolButton;
tlbAggiungi: TToolButton;
tlbModifica: TToolButton;
tlbElimina: TToolButton;
gridProtocollo: TDBGrid;
procedure tlbChiudiClick(Sender: TObject);
procedure tlbFiltriClick(Sender: TObject);
procedure tlbAggiungiClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
constructor Create(AOwner: Tcomponent); override;
end;
var
PaginaProtocolli: TPaginaProtocolli;
implementation
uses FormA, Modulo1, FraPaginaProtocollo, FormAutorizzazioniTipi;
{$R *.dfm}
constructor TPaginaProtocolli.Create(AOwner: TComponent);
begin
inherited;
mdl.sdsProtocollo.Open;
panMobile.Height := 15;
end;
// questo il codice contenuto nella FormA per aprire una pagina
procedure TPaginaProtocolli.tlbAggiungiClick(Sender: TObject);
begin
inherited;
frmA.ApriPagina(TPaginaProtocollo, 'NuovoProtocollo', 'Nuovo Protocollo');
end;
// questo il codice contenuto nella FormA per chiudere una pagina
procedure TPaginaProtocolli.tlbChiudiClick(Sender: TObject);
begin
inherited;
frmA.ChiudiPagina;
end;
end.
****************************************
Nella FormA ho messo:
- una toolbar anzichè una tree (per avere più spazio)
- un componente rkSmartTabs che potete trovare qui
http://rmklever.com/
che in pratica crea delle linguette con pulsante di chiusura
molto personalizzabili
- un PageControl (chiamato ContenitorePagine)
Questo il codice saliente della FormA:
****************************************
implementation
{$R *.dfm}
Uses
Modulo1, FraPaginaHome, FraPaginaDitte, FraPaginaProtocolli;
procedure TfrmA.ApriPagina(ATipoPagina: TPaginaFrame;
ANomeScheda: string; ATitoloTab: string);
var
z: Integer;
NewTab: TTabSheet;
NewPan: TPanel;
xPagina: TPaginaModello;
begin
// verifico che la pagina chiamata non sia gia aperta
for z := 0 to ContenitorePagine.PageCount - 1 do begin
if ContenitorePagine.Pages[z].Name = ANomeScheda then begin
// se gia aperta la attivo
ContenitorePagine.ActivePageIndex := z;
// ed attivo anche la relativa rkTab
rkTab.ActiveTab := z;
exit;
end;
end;
// creo la nuova pagina
NewTab := TTabSheet.Create(ContenitorePagine);
With NewTab do Begin
PageControl := ContenitorePagine;
Name := ANomeScheda;
TabVisible := False;
End;
// Aggiungo una rkTab alla Form principale
// e le assegno il nome passato alla procedura
frmA.rkTab.AddTab(ANomeScheda);
// poi le assegno il titolo passato alla procedura
frmA.rkTab.Tabs[frmA.rkTab.ActiveTab] := '';
frmA.rkTab.Tabs[frmA.rkTab.ActiveTab] := ATitoloTab;
NewPan := TPanel.Create(NewTab);
With NewPan do Begin
Parent := NewTab;
Name := 'Pannello' + ANomeScheda;
Align := alClient;
Caption := '';
End;
xPagina := ATipoPagina.Create(nil);
xPagina.Name := 'Pagina' + ANomeScheda;
try
// Dispone la pagina all'interno del pannello contenitore
xPagina.Parent := NewPan;
// Forza la pagina ad occupare lo spazio disponibile
xPagina.Align := alClient;
ContenitorePagine.ActivePage := NewTab;
except
raise;
end;
end;
procedure TfrmA.ChiudiPagina;
var
i: Integer;
begin
// chiudo la Pagina attiva
i := frmA.rkTab.ActiveTab;
frmA.ContenitorePagine.Pages[i].Free;
frmA.rkTab.DeleteTab(i);
frmA.ContenitorePagine.ActivePageIndex := frmA.rkTab.ActiveTab;
end;
****************************************
Resto a disposizione per eventuali chiarimenti.
---
Giovanni Fantuzzi