Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    Errore nel chiudere un Form (Delphi7)

    Nel chiedere il Form2 sulla X mi da questo errore:
    "Access Violation"
    il codice per aprire la Form2 è:
    codice:
    procedure TForm1.Button1Click(Sender: TObject);
    Var Form2 : TForm2;
    begin
     Form2 := TForm2.Create(TForm2);
     Form2.Show;
     end;
    Come posso procedere? -Thanks

  2. #2
    Utente di HTML.it
    Registrato dal
    May 2009
    Messaggi
    225
    codice:
    Form2 := TForm2.Create(nil);

  3. #3
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,333
    Originariamente inviato da sebaldar
    codice:
    Form2 := TForm2.Create(nil);
    In questo modo però, il Form non viene mai distrutto, tranne quando l'applicazione viene chiusa, a meno di prendere provvedimenti specifici in un'altra parte del codice.

    Occorre fare attenzione a non generare memory leak, cioè a garantire che ogni oggetto creato venga in qualche modo distrutto al termine del suo utilizzo.

    In riferimento alla domanda originale, pubblico la medesima risposta che ho dato altrove, in un altro forum.

    Originariamente inviato da camaleonteplus
    Nel chiedere il Form2 sulla X mi da questo errore:
    "Access Violation"
    [...]
    Come posso procedere? -Thanks
    Il metodo costruttore Create della classe TForm (e discendenti) si aspetta come parametro un cosiddetto owner, cioè il riferimento a un componente che - quando viene distrutto - si occupi automaticamente di distruggere e rilasciare quindi la memoria relativa a tutti gli oggetti "posseduti".

    Non è chiaro perché tu abbia specificato come parametro addirittura un tipo (TForm2), che ha ancora meno senso.

    Le finestre secondarie si possono creare senza owner qualora si tratti di finestre di dialogo modali, con un codice simile a questo:
    codice:
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Frm: TForm2;
    begin
      Frm := TForm2.Create(nil);
      try
        if Frm.ShowModal = mrOk then
          Caption := 'Yes'
        else
          Caption := 'No';
      finally
          Frm.Free;
      end;
    end;
    oppure si assegna come owner l'applicazione se si vuole aprire una finestra senza memorizzarsi il suo riferimento e consentendo che venga chiusa al termine dell'applicazione:

    codice:
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Frm: TForm2;
    begin
      Frm := TForm2.Create(Application);
      Frm.Show;
    end;
    o in alternativa si lega la distruzione della finestra ad un'altra finestra già istanziata:

    codice:
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Frm: TForm2;
    begin
      Frm := TForm2.Create(Self); // "Self" rappresenta qui l'istanza di TForm1
      Frm.Show;
    end;
    In ogni caso, è sufficiente leggere la documentazione di Delphi o ricercare articoli che trattano i concetti di ownership dei componenti per capire il meccanismo e conoscere qual è il parametro corretto da passare in base al contesto e il comportamento che ne consegue. In occasioni come questa, andare invece a mettere un parametro del tutto casuale o ipotetico, si ottengono solo guai (come ampiamente dimostrato dall'errore di Access Violation riscontrato).
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  4. #4
    continua a darmi errore di memoria. ho dimenticato di dire io ho un form3 che è un about lo apro con showmodal ma si chiude bene. non da errori di memoria, se applico un showmodal anche al form2 dice che non può applicare questa modalità, questo perchè come dicevi tu la form3 è sempre aperta?

  5. #5
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,333
    Originariamente inviato da camaleonteplus
    continua a darmi errore di memoria. ho dimenticato di dire io ho un form3 che è un about lo apro con showmodal ma si chiude bene. non da errori di memoria, se applico un showmodal anche al form2 dice che non può applicare questa modalità, questo perchè come dicevi tu la form3 è sempre aperta?
    Senza il codice è difficile fare supposizioni. Dalla descrizione che fai, sembra che tu stia aprendo un Form non modale da una finestra modale, e questo non è consentito (per ovvi motivi legati al principio di funzionamento e comportamento delle due tipologie di finestra).
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  6. #6
    In Form1 ho inserito questo codice:
    codice:
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Frm: TForm2;
    begin
      Frm := TForm2.Create(Self); // "Self" rappresenta qui l'istanza di TForm1
      Frm.Show;
    end;
    e ho modificato anche il buttonclick del form3 che era in showmodal gli ho dato il tipo di codice descritto sopra.
    PS il form3 non da problemi.

  7. #7
    Trovato l'errore, nel Form2 avevo inserito un codice preso da un mio sorgente appartenente ad un altro programma che stavo sviluppando dimenticando di modificare i dati:
    codice:
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
         Form2.hide;
    with TForm2.Create(Self) do
    try
         ShowModal;
    finally
         Free;
    end;
         Application.Terminate;
    end;
    Adesso va tutto bene, mi sono distratto come al solito.

  8. #8
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,333
    Trovato l'errore, nel Form2 avevo inserito un codice preso da un mio sorgente appartenente ad un altro programma che stavo sviluppando dimenticando di modificare i dati:
    codice:
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
         Form2.hide;
    with TForm2.Create(Self) do
    try
         ShowModal;
    finally
         Free;
    end;
         Application.Terminate;
    end;
    Adesso va tutto bene, mi sono distratto come al solito.
    Scusa per la franchezza, ma nel tuo codice noto una infinita di incongruenze e di errori.

    Innanzitutto, se usi ShowModal, in generale puoi benissimo fare a meno della variabile creata da Delphi nella unit del Form modale, poiché questo può essere creato quando serve, visualizzato e distrutto al termine dell'utilizzo, memorizzando il riferimento del Form in una variabile locale oppure usando il with come nel tuo esempio di codice ed evitando (come ti ha suggerito cyberlaundry) la creazione automatica del Form all'avvio.

    Se la finestra è modale, generalmente non viene impiegata in altri modi, quindi non si spiega a cosa serva il Form2.Hide che hai inserito nel codice, che probabilmente si riferisce ad un'altra istanza della finestra che viene creata parallelamente a quella che utilizzi come finestra di dialogo (quindi ce ne sono di fatto due).

    Inoltre, non è chiaro l'utilizzo che fai delle finestre, creandone una nuova (Form2) nel momento in cui ne chiudi un'altra (Form1), andando però a specificare quest'ultima come "owner" della prima quando ne potresti fare a meno.

    Deprecabilissimo è invece l'uso di Application.Terminate che non andrebbe mai invocato all'interno di eventi o comunque nel codice dell'applicazione: il metodo corretto di arrestare un'applicazione Delphi è chiudere la finestra principale del programma, quella impostata come "MainForm".

    Secondo me, non hai ben chiari i meccanismi di creazione delle finestre e della loro gestione che dovresti approfondire in qualche guida o in un manuale altrimenti rischi di creare delle architetture formalmente errate che possono presentarti problemi nei momenti meno opportuni.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.