2011-09-26 20 views
15

Utilizzo di Windows MFC C++. Ho un'app di terze parti che chiama un metodo definito dall'utente nella mia classe derivata CWinApp. Questo metodo viene chiamato dopo InitInstance(). Se c'è un errore in questo metodo, tale che un'eccezione viene lanciata e catturata in un blocco try/catch, vorrei uscire dall'applicazione dal blocco catch. Qual è il modo canonico e corretto per uscire?Qual è il modo corretto per chiudere a livello di programmazione un'applicazione MFC?

UPDATE:

Serge credo sia giusto che in InitInstance() restituendo falso è il modo corretto di chiudere l'applicazione. Tuttavia, ora supponiamo di voler uscire dal gestore OnInitDialog() di una classe derivata da CDialog, qual è il modo corretto per farlo.

UPDATE 2

Per quanto mi riguarda, ho trovato chiamando PostMessage (WM_CLOSE) per essere il modo migliore dal mio non modale classe derivata CDialog. Tutti gli altri metodi di smettere ho cercato di sollevare qualche eccezione o altro in alcune circostanze.

Ecco un esempio di come lo uso:

BOOL SomeDialog::OnInitDialog() 
{ 
    CDialog::OnInitDialog(); 

    ::OleInitialize(nullptr); 

    try 
    { 
     // ...load settings file here 
    } 
    catch(...) 
    { 
     PostMessage(WM_CLOSE); 
     return TRUE; 
    } 

    // return TRUE unless you set the focus to a control 
    return TRUE; 
} 
+0

Ah! È un'app basata su Dialog. Vedi la mia risposta modificata. –

risposta

23

In InitInstance()

Uscendo l'applicazione mentre si è ancora in InitInstance(): semplicemente restituire FALSE da InitInstance().

Nel messaggio ciclo principale

E 'un'altra storia se se sei già nel ciclo di messaggi: Il metodo standard per chiudere un app è quello di uscire dal ciclo di messaggi:

PostQuitMessage(0), come il suo nome implica, pubblica un messaggio WM_QUIT. Il ciclo dei messaggi reagisce uscendo dal ciclo e chiudendo il programma.

Ma non dovresti semplicemente farlo: dovresti chiudere le finestre aperte nella tua app. Supponendo di avere solo la vostra finestra principale, si dovrebbe distruggerlo chiamando

m_pMainWindow->DestroyWindow(); 

MFC reagirà PostQuitMessage() per voi, quindi uscire dal ciclo di messaggi principale e chiudere la vostra applicazione.

Meglio ancora, è necessario inviare un WM_CLOSE per consentire la chiusura della finestra principale con grazia. Ad esempio, può decidere di salvare il documento corrente. Attenzione però: il gestore standard OnClose() può richiedere all'utente di salvare documenti sporchi. L'utente può anche annullare l'azione di chiusura usando questo prompt (Salva documento? Sì, No, Annulla).

Distruggere la finestra principale pubblicherà un messaggio WM_DESTROY. L'MFC reagisce chiamando lo PostQuitMessage(0) per uscire dalla pompa dei messaggi.(In realtà, MFC fa la chiamata in OnNcDestroy() dal WM_NCDESTROY che è l'ultima mesage assoluta ricevuta da una finestra)

Dialog-based app

chiamata EndDialog(-1); // O sostituire -1 dal IDCANCEL, qualunque

Questa chiamata, come probabilmente sapete, chiuderà la finestra di dialogo.

Si noti che la finestra di dialogo principale dell'applicazione basata su finestra di dialogo viene eseguita in InitInstance(). La chiusura della finestra di dialogo verrà semplicemente terminata con InitInstance(), che restituisce sempre FALSE in tali progetti.

+0

zadane ti ha appena lasciato un commento sotto forma di risposta. Penso davvero che la politica di StackOverflow per impedirti di lasciare un commento fino a quando non ottieni 50 rappresentanti è ossea. –

+0

@ Mark, grazie per avermelo fatto notare. –

+0

Divertente storia su WM_DESTROY: http://blogs.msdn.com/b/oldnewthing/archive/2011/09/26/10216420.aspx –

7

utilizzare semplicemente:

PostQuitMessage(0); 

Tenete a mente il vostro programma non si chiuderà istantaneamente da questa chiamata, la finestra/programma riceverà un messaggio WM_QUIT e quindi il programma si chiuderà.

+1

È il contrario: WM_CLOSE, distrugge la finestra. Dopo la distruzione della finestra principale, MFC invierà PostQuitMessage (0), che, come il nome stesso, invierà un WM_QUIT, il che si tradurrà nell'uscita dal ciclo dei messaggi. –

1

Serge - la tua risposta purtroppo non è il modo migliore per farlo. PostQuitMessage (0) è la strada da percorrere e MFC distruggerà le finestre per te. Dovresti evitare di chiamare m_pMainWindow-> DestroyWindow() direttamente.

+0

Leggi i [documenti su PostQuitMessage()] (http://msdn.microsoft. com/it-it/library/windows/desktop/ms644945 (v = vs.85) aspx). –

+1

Il documento non dice dovunque io sia errato. DestroyWindow() è una funzione virtuale che viene chiamata da MFC per te quando gli dici di chiudere la finestra pubblicando il messaggio. È meglio lasciarlo a MFC per farlo per te che chiamarlo direttamente perché di solito c'è una sequenza di eventi che si verifica quando si distrugge una finestra e MFC lo gestisce. In alcuni casi possiamo chiamarlo direttamente se sappiamo cosa stiamo facendo. – zar

+0

Dove hai visto che chiamare PostQuitMessage() chiuderà o distruggerà la tua finestra? –