2010-07-01 6 views

risposta

70

Sono totalmente diversi.

WM_CLOSE viene inviato alla finestra quando si preme "X" o si seleziona "Chiudi" dal menu della finestra. Se rilevi questo messaggio, questo è il tuo invito a trattarlo: ignoralo o chiudi davvero la finestra. Per impostazione predefinita, WM_CLOSE passato a DefWindowProc causa la distruzione della finestra. Quando viene distrutta la finestra viene inviato il messaggio WM_DESTROY. In questa fase, in opposizione a WM_CLOSE, non è possibile interrompere il processo, è possibile solo effettuare una pulizia necessaria. Ma ricorda che quando prendi lo WM_DESTROY appena prima che tutte le finestre figlio siano già state distrutte. WM_NCDESTROY viene inviato subito dopo che tutte le finestre figlio sono state distrutte.

WM_QUIT messaggio non è correlato a nessuna finestra (il numero hwnd ottenuto da GetMessage è NULL e non viene richiamata alcuna procedura di finestra). Questo messaggio indica che il ciclo del messaggio deve essere interrotto e l'applicazione deve essere chiusa. Quando GetMessage legge WM_QUIT, restituisce 0 per indicare quello. Dai un'occhiata a typical message loop snippet - il ciclo continua mentre GetMessage restituisce un valore diverso da zero. WM_QUIT può essere inviato tramite la funzione PostQuitMessage. Questa funzione viene solitamente chiamata quando la finestra principale riceve WM_DESTROY (vedere typical window procedure snippet).

+2

Ottima risposta, ma guardando il codice del ciclo del messaggio, il ciclo continua mentre "GetMessage" restituisce un valore diverso da zero, non prima, a meno che manchi qualcosa. –

+0

Sì, naturalmente, corretto. – adf88

+0

@ ad88 sarebbe fantastico per aggiungere cosa succede quando arriva Logout utente/'WM_ENDSESSION'. Questo fa scattare automaticamente WM_CLOSE/QUIT/DESTROY? – Basj

3

Inizialmente discutiamo di WM_QUIT, la differenza rispetto a un altro messaggio che non è associato alla finestra. È usato dall'applicazione. Ad esempio, questo può essere gestito dal server OLE standalone non visibile (.exe, ma non in-proc come .dll)

WM_CLOSE - per msdn: "Un'applicazione può richiedere all'utente conferma, prima di distruggere un window "- è usato come notifica sull'intenzione di chiudere (puoi rifiutare questa intenzione).

WM_DESTROY - è un fatto che la finestra si sta chiudendo e tutte le risorse devono (!) Essere deallocate.

+4

WM_QUIT è in realtà per-thread, non per applicazione. – atzz

+0

@ atzz sì, hai ragione. Parlando in generale, questo messaggio notifica al ciclo eventi di interrompere la gestione, indipendentemente dal thread a livello di applicazione o standalone. – Dewfy

9

Prima di tutto, i messaggi WM_CLOSE e WM_DESTROY sono associati a particolari finestre, mentre il messaggio WM_QUIT è applicabile l'intera applicazione (ben filo) e il messaggio non viene mai ricevuto attraverso una procedura di finestra (WndProc di routine), ma solo attraverso le funzioni GetMessage o PeekMessage.

Nella routine WndProc la funzione DefWindowProc si occupa del comportamento predefinito di questi messaggi. I messaggi WM_CLOSE richiedono che l'applicazione si chiuda e il comportamento predefinito per questo è chiamare la funzione DestroyWindow. Quando viene chiamata questa funzione DestroyWindow viene inviato il messaggio WM_DESTROY. Si noti che il WM_CLOSE è solo un messaggio che richiede di essere chiuso (come WM_QUIT) - in realtà non è necessario uscire/uscire. Ma il messaggio WM_DESTROY vi dice che la vostra finestra IS essere chiusi e distrutti in modo si deve la pulizia tutte le risorse, gestisce ecc

+0

Non per l'intera applicazione, ma per un particolare ciclo di messaggi. Ogni thread può avere il proprio ciclo di messaggi, quindi un'applicazione può avere diversi loop di messaggi. – 0xC0000022L

3

Proprio in modo che non si perde nei commenti ... non dimenticare WM_CANCEL . Quando si fa clic sul pulsante di chiusura (x) in una finestra di dialogo MFC, verrà inviato sicuramente WM_CLOSE.La funzione predefinita OnClose() chiamerà quindi la funzione predefinita (classe base) OnCancel().

Tuttavia, se è sufficiente digitare la chiave ESC, questo porterà alla chiusura della finestra di dialogo, ma (per quanto posso dire) senza generare l'evento WM_CLOSE - si va direttamente al meccanismo WM_CANCEL/OnCancel().

Con la presente invito la comunità a elaborare questo ... o modificare tale elaborazione nella risposta accettata.