Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Form all'interno di un panel

232 views
Skip to first unread message

Stark

unread,
Oct 14, 2013, 12:44:21 PM10/14/13
to
Ispirato da qualcosa letto da qualche parte, ho sperimentato una struttura
dell'applicazione (di una parte di essa) dove un form ospita un treeView che
fa da menu e un pannello a fianco dove, in funzione della scelta effettuata
nel menu, viene visualizzato un form o l'altro.
Concettualmente è molto simile all' "Applicazione a pagine" di Marco B. Solo
che lui usa dei frames.
Io le applicazioni le avevo già funzionanti, solo che ognuna apriva una
diversa finestra, mentre con questa tecnica mi pare ci sia meno confusione
per l'utente, perchè per lui c'è un'unica finestra che ospita l'applicazione
da lui scelta nel menu, che è il panel all'interno del quale il form viene
mostrato.
Non ho scelto la soluzione di Marco B.perchè non volevo pensare a come
trasformare dei forms in frames, etc. e mi sembrava che così non ci fosse
niente da fare. In effetti, qualche problemino c'è lo stesso,.
Ma vorrei sapere se qualcun altro ha sperimentato questa cosa, se trovate
che ha un senso o no, sia dal punto di vista utente che della
programmazione. Vorrei qualche commento insomma. Aspetto..

Marco Breveglieri

unread,
Oct 15, 2013, 4:55:09 AM10/15/13
to
Il giorno lunedì 14 ottobre 2013 18:44:21 UTC+2, Stark ha scritto:
> Non ho scelto la soluzione di Marco B.perchè non volevo pensare a come
> trasformare dei forms in frames, etc. e mi sembrava che così non ci fosse
> niente da fare. In effetti, qualche problemino c'è lo stesso,.

Non so se la soluzione è ancora applicabile, ma un tempo - quando ancora non c'erano i Frame - lo stesso effetto si otteneva usando dei comuni Form: in pratica, assegnando un pannello come Parent di un Form, la finestra veniva mostrata al suo interno come se fosse un Frame.

Non è una scelta ideale, anche perché le risorse allocate per un Form non sono le stesse di un Frame, e non è detto che gli aggiornamenti al sistema Windows in quanto tale non vadano a introdurre difetti di visualizzazione, poi andrebbe verificato anche il supporto ai temi della VCL recentemente introdotto.

Nonostante ciò, potresti provare comunque questa soluzione, altrimenti - operazione delicata con backup preventivo - potresti tentare la modifica diretta dei file PAS/DFM andando a sostituire i riferimenti ai Form con i Frame, ma richiede chiaramente una certa precisione e il saper dove mettere le mani per evitare che l'apertura del progetto vada in errore.

> Ma vorrei sapere se qualcun altro ha sperimentato questa cosa, se trovate
> che ha un senso o no, sia dal punto di vista utente che della
> programmazione. Vorrei qualche commento insomma. Aspetto..

A cosa ti riferisci di preciso? Alla scelta di aprire Form usando un TreeView?
Alla fine io non ho capito bene come è fatta la tua soluzione di preciso. :|

Ciao,
Marco.

--
MARCO BREVEGLIERI
#Home: http://www.marco.breveglieri.name
#Blog: http://www.compilaquindiva.net

Giacomo Degli Esposti

unread,
Oct 15, 2013, 5:31:34 AM10/15/13
to
Il giorno lunedì 14 ottobre 2013 18:44:21 UTC+2, Stark ha scritto:
> Ispirato da qualcosa letto da qualche parte, ho sperimentato una struttura
> dell'applicazione (di una parte di essa) dove un form ospita un treeView che
> fa da menu e un pannello a fianco dove, in funzione della scelta effettuata
> nel menu, viene visualizzato un form o l'altro.

Qualcosa tipo la form delle opzioni di delphi?

> Io le applicazioni le avevo già funzionanti, solo che ognuna apriva una
> diversa finestra, mentre con questa tecnica mi pare ci sia meno confusione
> per l'utente, perchè per lui c'è un'unica finestra che ospita l'applicazione
> da lui scelta nel menu, che è il panel all'interno del quale il form viene
> mostrato.
[...]
> Ma vorrei sapere se qualcun altro ha sperimentato questa cosa, se trovate
> che ha un senso o no, sia dal punto di vista utente che della
> programmazione. Vorrei qualche commento insomma. Aspetto..

Non so se ho capito bene, ma stai cercando di aprire le applicazioni
in modo che la loro form venga inserita all'interno di
un'altra applicazione "principale" che e' poi quella con l'albero
che ti consente poi di attivare una o l'altra applicazione?

Tempo fa ho sperimentato qualcosa del genere: si riesce a combinare
qualcosa. Si tratta di lanciare l'eseguibile esterno con il solito
CreateProcess, poi bisogna identificare la form principale del processo
(e li e' la parte piu' difficile) e poi "riparentarla" sulla tua
form principale.
Un problema che ho incontrato e non sono riuscito a risolvere e' che le
applicazioni che lanci rimangono indipendenti, quindi mantengono
il focus e quando vuoi cliccare su una parte edlla tua form principale
(nel mio caso era una toolbar, nel tuo caso potrebbe essere l'albero)
serviva un click per spostare il focus da un'applicazione all'altra
e poi un secondo click per cliccare effettivamente sulla toolbar.

ciao
Giacomo

Alberto Salvati

unread,
Oct 15, 2013, 6:13:54 AM10/15/13
to
>
> Tempo fa ho sperimentato qualcosa del genere: si riesce a combinare
> qualcosa. Si tratta di lanciare l'eseguibile esterno con il solito
> CreateProcess, poi bisogna identificare la form principale del processo
> (e li e' la parte piu' difficile) e poi "riparentarla" sulla tua
> form principale.

Scusate: a cosa serve?

A.

Andromeda

unread,
Oct 15, 2013, 6:17:10 AM10/15/13
to
Il 14/10/2013 18:44, Stark ha scritto:
> Concettualmente è molto simile all' "Applicazione a pagine" di Marco B.
> Solo che lui usa dei frames.

Chiedo scusa, ma dove si può trovare qualcosa in più relativamente all'
"Applicazione a pagine" ?

Grazie





--
Mai mettersi a discutere con un idiota:
- prima ti porta al suo livello e poi ti batte con l'esperienza;
- chi ascolta potrebbe non capire la differenza.

Marco Breveglieri

unread,
Oct 15, 2013, 6:20:59 AM10/15/13
to
Il giorno martedì 15 ottobre 2013 12:17:10 UTC+2, Andromeda ha scritto:
> Chiedo scusa, ma dove si può trovare qualcosa in più relativamente all'
> "Applicazione a pagine" ?

Bisogna cercare nei thread un po' vecchi... molto vecchi (penso 2005), altrimenti ripesco l'esempio quando sono a casa e lo rimetto sul mio blog a buon rendere. :)

Andromeda

unread,
Oct 15, 2013, 6:31:19 AM10/15/13
to
Il 15/10/2013 12:20, Marco Breveglieri ha scritto:
> Il giorno martedì 15 ottobre 2013 12:17:10 UTC+2, Andromeda ha scritto:
>> Chiedo scusa, ma dove si può trovare qualcosa in più relativamente all'
>> "Applicazione a pagine" ?
>
> Bisogna cercare nei thread un po' vecchi... molto vecchi (penso 2005), altrimenti ripesco l'esempio quando sono a casa e lo rimetto sul mio blog a buon rendere. :)

Se potessi dedicarci qualche minuto te ne sarei grato, intanto
sguinzaglio google groups ;-)

Grazie.

Giacomo Degli Esposti

unread,
Oct 15, 2013, 6:48:24 AM10/15/13
to
Nel nostro caso l'idea era di dare al cliente un'interfaccia piu'
omogenea, in modo che fosse indifferente se una certa funzionalita'
era implementata nell'eseguibile principale o in un exe esterno,
alla fine lui vede sempre una form dentro ad un tab.

ciao
Giacomo

Stark

unread,
Oct 15, 2013, 5:57:19 PM10/15/13
to
Qualcuno mi ha chiesto a cosa serve. Per me serve a facilitare la vita
all'utente, un pò come tentava di fare il concetto dell'applicazione MDI,
che però non mi piaceva.
Grossolanamente, la cosa mi funziona. Tento di spiegarvi cosa ho fatto:
Il funzionamento per l’utente è il seguente:

C'è un Main che gestisce le scelte che si fanno nel menu (Treeview) che
consistono nel lancio di un programma o l'altro. All’avvio viene
visualizzato per default, nel panel, uno dei programmi.
Il clic su un nodo del TreeView ha come effetto che il form visualizzato
viene sostituito da quello scelto con il clic.
Da ciascun form si esce solo facendo una diversa scelta nel menu. Non
vengono utilizzati i bottoni di uscita forniti dai vari programmi, che anzi
devono essere disabilitati (vedi 1), ma il passaggio ad un altro programma
non deve avvenire senza aver utilizzato le procedure di chiusura previste
dal programma da cui si esce (vedi 2).

// 1 - Libera la istanza del form creato in precedenza (quindi l’unico
Assigned) prima di creare il nuovo form che va lanciato
if Assigned(FormGestConti) then
begin
FormGestConti.BtnCloseClick(FormGestConti); // (2)
FreeAndNil(FormGestConti);
end;
// 2 - Carica la pagina corrispondente al nodo selezionato (Lancia il
programma)
if Node.Text = 'Estratto Conto' then
begin
FormEstratti := TFormEstratti.Create(Self);
DisplayFormInsideContainer(FormEstratti);
end;
// Come si inserisce il Form all’interno del Panel
procedure TFormContiMain.DisplayFormInsideContainer(aForm: TForm);
begin
aForm.Parent:= PagePanel;
aForm.BorderStyle:= bsNone;
aForm.Align:= alClient;
aForm.Show;
end;

Non sono un bravo programmatore e quindi sono sicuro che si può fare di
molto meglio.. ma questa è l'idea.
Cosa ne dite ?

Andromeda

unread,
Oct 18, 2013, 4:09:57 AM10/18/13
to
Il 15/10/2013 12:20, Marco Breveglieri ha scritto:
> Il giorno martedì 15 ottobre 2013 12:17:10 UTC+2, Andromeda ha scritto:
>> Chiedo scusa, ma dove si può trovare qualcosa in più relativamente all'
>> "Applicazione a pagine" ?
>
> Bisogna cercare nei thread un po' vecchi... molto vecchi (penso 2005), altrimenti ripesco l'esempio quando sono a casa e lo rimetto sul mio blog a buon rendere. :)

Ho cercato (forse male) ma non ho trovato niente.
Non voglio sembrarti scortese, ma se potessi - quando hai tempo -
ritrovare la tua documentazione...

Grazie molte.

Marco Breveglieri

unread,
Oct 18, 2013, 6:20:22 AM10/18/13
to
Il giorno venerdì 18 ottobre 2013 10:09:57 UTC+2, Andromeda ha scritto:
> Non voglio sembrarti scortese, ma se potessi - quando hai tempo -
> ritrovare la tua documentazione...

Purtroppo non ho molto tempo al momento. :|
Appena riesco aggiornerò il thread.

Ciao!

Andromeda

unread,
Oct 18, 2013, 6:35:54 AM10/18/13
to
Il 18/10/2013 12:20, Marco Breveglieri ha scritto:
> Il giorno venerdì 18 ottobre 2013 10:09:57 UTC+2, Andromeda ha scritto:
>> Non voglio sembrarti scortese, ma se potessi - quando hai tempo -
>> ritrovare la tua documentazione...
>
> Purtroppo non ho molto tempo al momento. :|
> Appena riesco aggiornerò il thread.

Nessuna fretta, l'importante è che non lo dimentichi ;-)

gfantuzzi

unread,
Jan 18, 2014, 7:17:59 AM1/18/14
to
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

Alberto Salvati

unread,
Jan 18, 2014, 8:34:47 AM1/18/14
to
xche hai le uses in implementation?

A.

gfantuzzi

unread,
Jan 18, 2014, 9:30:13 AM1/18/14
to
Onestamente non c'è motivo.
In passato mi trovavo a combattere con i riferimenti circolari, così ho preso l'abitudine di lasciare mettere a Delphi i suoi rif. nella interface, i miei li mettevo nella implementation.. e buona notte.
--
Giovanni

Giovanni Fantuzzi

unread,
Feb 22, 2014, 9:53:19 AM2/22/14
to
Segnalo un sistema alternativo per mettere delle Form all'interno di un PageControl (o di un panel), decisamente meno caotico di quello da me descritto sopra.

risultato:
http://codegearguru.com/video/033/FormDocking2.html

prima parte della lezione:
http://codegearguru.com/video/032/FormDocking.html

Giovanni



0 new messages