Mi chiedevo quale sia la differenza tra i messaggi WM_QUIT, WM_CLOSE e WM_DESTROY in un programma Windows, in sostanza: quando vengono inviati e hanno effetti automatici oltre a quelli definiti dal programma?Qual è la differenza tra WM_QUIT, WM_CLOSE e WM_DESTROY in un programma Windows?
risposta
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).
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.
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
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
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.
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. –
Sì, naturalmente, corretto. – adf88
@ ad88 sarebbe fantastico per aggiungere cosa succede quando arriva Logout utente/'WM_ENDSESSION'. Questo fa scattare automaticamente WM_CLOSE/QUIT/DESTROY? – Basj