Newsgroup: it.comp.lang.delphi
Titolo: Questa ragazzi è davvero bella.....

Allora, creo un form a run-time che contiene 2 etichette, un oggetto di tipo
edit e due bitbtn, uno per l'OK e l'altro per l'Annulla.... semplissimo no?
behh
- quando clicco sul bottone di annulla faccio la free del form e tutto va
bene
- quando mi porto con la tastiera e premo (sempre da testiera il bottone ok)
tutto bene come prima, fa le operazioni che gli dico di  fare e poi faccio
la free senza problemi
- quando clicco sul bottone OK con il mouse fa le operazioni che deve fare e
poi mi da Access Violation?
Ma vi pare una cosa normale?
Vi posto il codice, magari qualcuno si prende la briga di guardarlo e mi
dice se sbaglio qualcosa.
PS:le procedure closepassa, okclick, annullaclick e edit_numerochange sono
dichiarate come private nel form1 (il form principale del programma mentre
le farie formpassa, etichetta, etichetta2, edit_numero, ok e annulla sono
globali ma nella parte public....
procedure TForm1.Passaalrecordn1Click(Sender: TObject);
begin
  form1.Enabled:=false;
  formpassa:=tform.Create(nil);
  formpassa.Parent:=nil;
  formpassa.Top:=trunc((screen.Height/2)-75);
  formpassa.Left:=trunc((screen.Width/2)-200);
  formpassa.Height:=140;
  formpassa.Width:=240;
  formpassa.BorderStyle:=bsdialog;
  formpassa.Enabled:=true;
  formpassa.Ctl3D:=true;
  formpassa.Caption:='Passa al record n°';
  formpassa.OnClose:=closepassa;
  formpassa.Position:=poDesktopCenter;
  etichetta2:=tlabel.create(formpassa);
  etichetta2.parent:=formpassa;
  etichetta2.left:=trunc((formpassa.Width/2)-75);
  etichetta2.Top:=5;
  etichetta2.Font.Size:=14;
  etichetta2.Caption:='Record totali: ';
  etichetta2.Enabled:=true;
  etichetta2.Visible:=true;
  etichetta:=tlabel.Create(formpassa);
  etichetta.Parent:=formpassa;
  etichetta.Left:=trunc((formpassa.Width/2)-110);
  etichetta.Top:=35;
  etichetta.Font.Size:=14;
  etichetta.Caption:='Passa al record n°';
  etichetta.enabled:=true;
  etichetta.visible:=true;
  edit_numero:=tedit.Create(formpassa);
  edit_numero.Parent:=formpassa;
  edit_numero.Left:=trunc((formpassa.Width/2)+50);
  edit_numero.Top:=35;
  edit_numero.Width:=40;
  edit_numero.MaxLength:=4;
  edit_numero.OnChange:=edit_numerochange;
  edit_numero.enabled:=true;
  edit_numero.visible:=true;
  ok:=Tbitbtn.Create(formpassa);
  ok.Parent:=formpassa;
  ok.Top:=75;
  ok.left:=25;
  ok.Glyph.LoadFromFile('.\icons\ok_small.bmp');
  ok.Caption:='Ok';
  ok.OnClick:=okclick;
  ok.Cursor:=crhandpoint;
  ok.enabled:=true;
  ok.visible:=true;
  annulla:=tbitbtn.Create(formpassa);
  annulla.Parent:=formpassa;
  annulla.top:=75;
  annulla.Left:=130;
  annulla.Glyph.LoadFromFile('.\icons\Cancel_small.bmp');
  annulla.Caption:='Annulla';
  annulla.onclick:=annullaclick;
  annulla.Cursor:=crhandpoint;
  annulla.enabled:=true;
  annulla.visible:=true;
  formpassa.enabled:=true;
  formpassa.visible:=true;
end;
//Questa procedura termina correttamente con la free
procedure tform1.annullaclick(Sender: TObject);
begin
  form1.visible:=true;
  form1.Enabled:=true;
  formpassa.Free;
end;
//questa procedura crasha
procedure tform1.okclick(Sender: TObject);
begin
[CUT]
      form1.Enabled:=true;
      formpassa.free;
end;   //sulla free non mi da problemi, ma va in access violation appena
esegue l'end!!!!!
        //dopo però non ho altre istruziuoni
procedure tform1.Edit_numerochange(Sender: TObject);
begin
[CUT]
   // altro codice
end;
procedure tform1.closepassa(Sender: TObject; var Action: TCloseAction);
begin
    form1.Enabled:=true;
    formpassa.Free;
end;
Grazie a tutti

 end;
non devi fare il free sul close della finestra altrimenti gli togli il 
terreno da sotto i piedi, usa al limite la variabile action.
hai fatto confusione con i free, prova a lasciare
   formpassa.showmodal;
   annulla.free;
   ok.free;
   formpassa.free;
al posto di
    formpassa.enabled:=true;
    formpassa.visible:=true;
La liberazione della memoria č meglio se la fai in un punto solo e non 
in varie funzioni.
ciao
-- 
---------------------------------------
Per rispondere in privato togliere 1975

in varie funzioni.
Mi chiedo perche' leggo sempre piu' messaggi di gente che vuole fare free a
tutti i costi... quando io lascio fare tutto al compilatore. Boh...
sara' perche' realizzo programmi gestionali in forma classica, senza accrocchi
particolari che necessitano di liberare memoria dai bottoni, componenti,
ecc... Mah....
-- 
Morde. 
morde[at]programmer[.]net

 ecc... Mah....
qualsiasi oggetto che crei poi devi distruggerlo altrimenti la memoria non
viene più liberata e dopo ore di utilizzo del programma.... beh poi si da
colpa alla microsoft hehehe
ciauz

 tutti i costi...
e' una forma di programmazione barocca, ancorata alla vecchia tradizione del
turbo ;) e' uno stile che adoro anche io, se e' per questo, gestire gli
oggetti in modo manuale :) ma lo faccio in modo molto razionale e che non da
adito a problemi di sorta. Ad esempio per le form:
with TMiaForm.create(nil) do begin
 showmodal; free;
end;
il free solo alla fine della visualizzazione, e' chiarissimo che viene
liberata la memoria e il punto dove viene fatto, e niente robaccia sugli
eventi onclose (es. il famigerato caFree) e simili.
Ciao, Sandro

turbo ;)
^__^ !!!!!!
aha haha!!!
Mi ricordo di flame spaventosi riguardo l'opportunita' o meno di mettere una
free "pleonastica"... l'amico laforgia sfioro' l'omicidio virtuale per questo!
eh ehe eh... (Andrea va che scherzo!)
Ciao


 qualsiasi oggetto che crei poi devi distruggerlo
cioč mi stai dicendo che se io ho una form con 101 componenti ...
mi devo preoccupare di distruggerli tutti alla chiusura
della form e ricrearli tutti all'apertura della form...
ragazzi ... qui saremmo tutti bravi a dire come si fa ad usare
solo 100K di memoria ma ...
vallo a dire a chi, programmando, porta il pane a casa il cui capo ufficio
gli dice ...
"In due mesi l'applicazione deve uscire se no, non ha piů mercato" (leggete
come "non hai lo stipendio",
anche se alla fine non č vero, se vuoi l'umento glela "devi dare" in 1 mese
e 1/2)
(al capo ufficio non gli frega niente se la tua applicazione poi gira solo
se il Calcolatore
 ha 256MB di ram anzi meglio cosě gli vendiamo anche il PC ... )
oppure vallo a dire a chi ha speso un pacco di milioni per Delphi perchč
gli avevano detto che era una RAD (Dove R sta per Rapid)
... allora ;) lasciamo fare anche al compilatore la sua parte come
dice anche Morde ... ci chiede solo un caFree alla chiusura del form
 se vogliamo liberare la memoria e
distruggere tutti i componenti che lo hanno come Owner ...
poi non credo che i programmatori della Borlad
siano stati cosě fessi a fare del lavoro in piů per mettere l'Owner
quando invece non serve ;) oppure l'Action sul formClose,
allora se le hanno messe perchč non sfruttarle ...
Scusate l'irruenza del post ... non era diretta a nessuno se non
alla fretta che ci costringe a delle violenze sulle nostre stesse
applicazioni.
  ciao a tutti
  Mak

edit e due bitbtn, uno per l'OK e l'altro per l'Annulla.... semplissimo no?
Cioe', viene creato runtime un form che contiene oggetti.
Ora, se io creo un form runtime, non me ne frega nulla degli oggetti in esso
contenuti, perche' di default verranno distrutti alla destroy del form.
Questo e' il succo del mio precedente post.
l'amico tymba invece riteneva che gli oggetti fossero creati anch'essi
dinamicamente, alemno cosi' credo.
Ciao!


> se vuoi l'umento glela "devi dare" in 1 mese e 1/2)
ecco, questo puo' essere davvero un problema, soprattutto se a programmare
e' una donna ;D
Ciao, Sandro

 eh ehe eh... (Andrea va che scherzo!)
l' "amico" laforgia mi ha fatto 2 O-O cosi' di recente per un "6" al posto
di un "5" in un ciclo for, considerato da lui come un errore gravissimo per
evitare il quale secondo lui sarebbe stato giustificato l'uso di un pesante
sistema di log interno ai fini di debug :DDD lasciamo perdere vah.. visto
il personaggio, prossimamente immagino gia' discussioni furiose sull'uso
(omissibile) del punto e virgola sull'ultima istruzione prima dell'end :DDD
Ciao, Sandro

 
quel "CaFree" risulta molto comodo in caso di finestre MDI oppuire che 
non apri non in modale.



Scusa, non ho ben capito dove sbaglio. In quale funzione tra le 4
intenderesti mettere la free del formpassa? e nelle altre funzioni cosa
dovrei fare? Togliere la free e poi?
Scusami ma ho capito + o - dove vuoi arrivare ma non saprei metterlo in
pratica
Davide

 dinamicamente, alemno cosi' credo.
d'accordo :) la mia entrata nel thread non è stata delle più felici
e, nel mio precedente post, me ne sono andato subito
alle divagazioni personali ;)
comunque torniamo al thread e precisamente alla root di Benna
(spero almeno questa volta di azzeccare :p)
forse sono troppo abituato a come scrive delphi il codice
o a chi mi ha detto che è meglio istanziare classi ereditate da Tform
e quindi una unit per form
o mi piace che le classi che creo facciano tutto quello che devono fare
e non che delighino alcuni compiti "intimi" a metodi di altre Form o classi
facendo strani giri ...
o ancora sono un "principiante" e ha paura del runtime ;)
la mia idea è che più codice scrivi a mano
più possibilità hai di fare errori ...
e perdere tempo a correggerli
ovviamente ogni "problema" ha la sua quantità di codice da scrivere
ma in generale io avrei scritto questo nella unit di un nuovo formPassa
posto il codice dopo i saluti
in questa maniera faccio fare tutte le distruzioni al compilatore
e il formPassa gestisce i fatti suoi
anche se non so se risponde alle esigenze di Benna
se ho commesso degli errori di concetto spero
in una vostra correzzione ...
  ciao
  Mak
-----------------------------------------------------Unit
Passa-----------------------------------------------------------------------
---------------
unit UnitPassa;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,  StdCtrls, Buttons;
type
  TFormPassa = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCloseAndFree(Sender: TObject; var Action: TCloseAction);
    procedure BitBtn1Click(Sender: TObject);
  Public
    Label1: TLabel;
    Edit1: TEdit;
    Bitbtn1: TBitBtn;
  end;
implementation
{$R *.dfm}
{ TFormPassa }
procedure TFormPassa.FormCreate(Sender: TObject);
begin
       Label1 := TLabel.Create(Self);
       With Label1 Do
       Begin
         Parent := Self;
         Caption := 'tizio e caio';
         //[cut]
       End;
       Edit1 := TEdit.Create(Self);
       With Edit1 Do
       Begin
         Parent := Self;
         Text := 'tizio e caio';
         //[cut]
       End;
       BitBtn1 := TBitBtn.Create(Self);
       With BitBtn1 Do
       Begin
         Parent := Self;
         Caption := 'OK';
         ModalResult := mrOk;
         OnClick := Self.BitBtn1Click;
         //[cut]
       End;
end;
procedure TFormPassa.FormCloseAndFree(Sender: TObject; var Action:
TCloseAction);
begin
        //lo distrugge
        Action := caFree;
end;
procedure TFormPassa.FormClose(Sender: TObject; var Action: TCloseAction);
begin
        //non lo distrugge
        Action := caHide; //Default
end;
procedure TFormPassa.BitBtn1Click(Sender: TObject);
begin
        //fa ciò che deve fare sull'OK, prima della chiusura
end;
end.
----------------------------------------------------------------------------
------------------------------------------------------
e una cosa del genere per la form che crea form Passa
----------------------------------------------------------------------------
-------------------------------------------------------
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
Type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
  FormPassa: TFormPassa
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
  //crea il form se lo distruggo ogni volta
  FormPassa := TFormPassa.Create(application);
  //distrugge il form
  FormPassa.OnClose := FormPassa.FormCloseAndFree;
  //non distrugge il form delega
  //delega la distruzione all'Owner
  //FormPassa.OnClose := FormPassa.FormClose;
  If FormPassa.ShowModal = mrOk Then
  begin
   //fa ciò che deve fare se la risposta è OK
   ShowMessage('OK');
  end else
  begin
   //fa ciò che deve fare se la risposta è KO
   ShowMessage('KO');
  end;
 //riga che testa se il form è stato distrutto o no ...
 //FormPassa.Show;
 //genera una eccezione se il form è stato distrutto
end;
----------------------------------------------------------------------------
---------------------------------------

Benna ha scritto:

procedure TForm1.Passaalrecordn1Click(Sender: TObject);
begin
   form1.Enabled:=false;
   formpassa.enabled:=true;
   formpassa.visible:=true;
end;
da quanto ho capito disabiliti la form1 e abilita la formpassa per 
rendere imnattiva la prima, puoi in tal caso fare un semplice showmodal 
della seconda per bloccare anche la prima
formpassa.showmodal;
e ti togli anche i vari enbaled := ....
//Questa procedura termina correttamente con la free
procedure tform1.annullaclick(Sender: TObject);
begin
   form1.visible:=true;
   form1.Enabled:=true;
   formpassa.Free;
end;
stai eseguendo del codice che viene chiamato da un evento generato da un 
"figlio" dell'oggetto formpassa, l'evento nel caso particolare č un 
"click" del mouse
durante questo evento tu cancelli l'oggetto, pero' finita la tua 
funzione il controllo torna all'oggeto che tu hai cancellato che quindi 
puo' aver perso delle informazioni ed andare a scrivere il locazioni di 
memoria sbagliate.
dentro il codice del bottone (codice VCL) puo' esserci una cosa del tipo 
(codice inventato e semplificato).
.....
WM_Click:
    if (Assigned(onclick)) then onclick(Sender);
......
nel tuo on click tu gli cancelli l'oggetto mentre č ancora in uso
procedure tform1.closepassa(Sender: TObject; var Action: TCloseAction);
begin
     form1.Enabled:=true;
     formpassa.Free;
end;
idem per questa, cancelli un oggetto che č ancora in uso, per fare una 
cosa giusta puoi usare la "action" ed assegnarle "caFree".
Stginendo, prima liberi la memoria nel codice dei bottoni e poi la 
liberi un'altra volta nel codice di "onclose".
Io farei una cosa del tipo
procedure TForm1.Passaalrecordn1Click(Sender: TObject);
begin
   formpassa:=tform.Create(nil);
   ............
   annulla.visible:=true;
   formpassa.showmodal;
   etichetta2.free;
   etichetta.free;
   edit_numero.free;
   ok.free;
   annulla.free;
   formpassa.free;
end;
teoricamente basterebbe solo l'ultimo free dato che gli altri sono di 
suo "possesso", ma non sono sicuro.
procedure tform1.okclick(Sender: TObject);
begin
       Close;
end;


 wrote in message
news:b7jd5g$tnp$1...@le.cs.unibo.it...
A parte i buoni consigli di ca75 sulla poca chiarezza e cattiva
sequenzialita' delle operazioni nel codice che hai postato, se usi Release
al posto di Free il problema si dovrebbe risolvere...
Ciao,
Stefano