2012-02-13 15 views
6

Attualmente nel mio programma ho un modulo di avvio e un modulo principale. Il modulo di avvio mostra per un secondo o due.Modo corretto per distruggere un modulo e mostrarne un altro in Delphi

In questo momento, ho il seguente codice all'interno di un timer:

frmStartup.Destroy; 

    frmMain := TfrmMain.Create(Self); 
    frmMain.Show; 

In questo momento, non sono sicuro se questo è il modo corretto per farlo .. Funziona, ma quando si chiama application.Terminate(); Ricevo un messaggio di violazione dell'accesso, che porta a credere di aver fatto qualcosa di sbagliato nella distruzione del modulo di avvio ..

Se qualcuno può mostrare la procedura corretta per fare quello che voglio (non modamente) Sarebbe essere molto apprezzato

Grazie in anticipo,

EDIT:

Grazie per tutti i feedback, ho fissato il mio violazioni di accesso, semplicemente aggiungendo il codice:

Action := caFree; 

nel metodo frmStartup.formClose.

+2

frmStartup.Destroy dovrebbe essere frmStartup.Free o addirittura frmStartup.Release FWIW –

+1

è auto = frmStartup? –

risposta

8

Non creare frmStartup utilizzando Application.CreateForm. Il primo modulo creato lì diventa il modulo principale dell'applicazione, e se questo è frmStartup lo stai distruggendo al di fuori della conoscenza dello Application.

Al contrario, utilizzare un normale Form.Create nell'origine file di progetto (.dpr):

var 
    frmStartup: TfrmStartup; 

begin 
    Application.Initialize; 
    Application.MainFormOnTaskBar := True; 
    frmStartup := TfrmStartup.Create(nil); // No owner assigned here! 
    frmStartup.Show; 
    frmStartup.Update; 

    Application.CreateForm(TfrmMain, frmMain); // Let Application have this for main form 
    // Delay here if needed 
    frmfrmStartup.Free; 
    Application.Run; 
end. 
+4

Per rendere il processo il più stretto possibile, definire un messaggio di Windows e inserire un gestore di messaggi nel modulo di avvio che lo libererà quando il messaggio viene ricevuto. Quindi invia questo messaggio dal metodo OnShow del tuo modulo principale. – SourceMaid

+1

Lo faccio nelle mie app con una schermata iniziale. Ciò sembrava andare oltre lo scopo di questa domanda, comunque. –

1

TFrmMain.Create (Self) ??? Cos'è il "Sé"? Lo stai facendo da dentro frmStartup? In tal caso, non. Usa TFrmMain.Create (NIL).

Usa frmStartup.Release per rilasciare frmStartup, se tutto il codice inviato è all'interno di un metodo di frmStartup, è necessario mettere quella linea in fondo del metodo.

+0

Con la mia attuale soluzione, TFrmMain.Create (nil) mi dà una violazione di accesso alla chiusura dell'applicazione ..: / – James

4

Si consiglia di visualizzare il proprio Splash Screen il prima possibile, quindi idealmente dovrebbe essere fatto durante la fase di inizializzazione, quindi dovrebbe scomparire solo quando MainForm è pronto per essere sostituito.

Questo è esattamente quello che facciamo nella nostra applicazione in cui riutilizziamo il proposito di dialogo come schermata iniziale quindi rilasciarlo quando la MainForm ruba la messa a fuoco.

dal DPR, più in alto possibile nella clausola usi dopo le unità VCL/RTL necessari:

f_adtDlgAbout in 'f_adtDlgAbout.pas' {frmDlgAbout}, // ASAP to be used as a Splash screen 

About unità (A proposito, FormStyle è fsStayOnTop e Position è poScreenCenter):

unit f_adtDlgAbout; 

[...] 

type 
    TfrmDlgAbout = class(TForm) 

[...] 

procedure TfrmDlgAbout.SplashFormDeactivate(Sender: TObject); 
begin 
    Release; 
end; 

initialization 
    // Use it as a Splash screen 
    with TfrmDlgAbout.Create(nil) do begin 
    AlphaBlend := True; 
    AlphaBlendValue := 208; 
    BorderStyle := bsNone; 
    btnOK.Visible := False; 
    OnDeactivate := SplashFormDeactivate; 
    Show; 
    Update; 
    end; 
end. 
0

Set frmMain come modulo principale

Su frmMain.FormCreate

frmStartup := TfrmStartup.Create(nil); 
try 
    frmStartup.ShowModal; 
finally 
    frmStartup.Free; 
end;