web-dev-qa-db-fra.com

Quelle est la différence entre WM_QUIT, WM_CLOSE et WM_DESTROY dans un programme Windows?

Je me demandais quelle était la différence entre les messages WM_QUIT, WM_CLOSE et WM_DESTROY dans un programme Windows, essentiellement: quand sont-ils envoyés et ont-ils des effets automatiques en plus de ce qui est défini par le programme?

62
user98188

Ils sont totalement différents.

WM_CLOSE est envoyé à la fenêtre lorsque "X" est pressé ou "Fermer" est choisi dans le menu de la fenêtre. Si vous entendez ce message, c'est à vous d'appeler comment le traiter - ignorez-le ou fermez vraiment la fenêtre. Par défaut, WM_CLOSE passé à DefWindowProc provoque la destruction de la fenêtre. Lorsque la fenêtre est détruite WM_DESTROY un message est envoyé. À ce stade, par opposition àWM_CLOSE, vous ne pouvez pas arrêter le processus, vous pouvez uniquement effectuer un nettoyage nécessaire. Mais rappelez-vous que lorsque vous attrapez WM_DESTROY juste avant que toutes les fenêtres enfants ne soient déjà détruites. WM_NCDESTROY est envoyé juste après que toutes les fenêtres enfants ont été détruites.

WM_QUIT le message n'est lié à aucune fenêtre (le hwnd obtenu de GetMessage est NULL et aucune procédure de fenêtre n'est appelée). Ce message indique que la boucle de message doit être arrêtée et que l'application doit être fermée. Lorsque GetMessage lit WM_QUIT il renvoie 0 pour indiquer cela. Jetez un oeil à extrait de boucle de message typique - la boucle se poursuit pendant que GetMessage renvoie non nul. WM_QUIT peut être envoyé par la fonction PostQuitMessage. Cette fonction est généralement appelée lorsque la fenêtre principale reçoit WM_DESTROY (voir extrait de procédure de fenêtre typique ).

80
adf88

Tout d'abord, les messages WM_CLOSE et WM_DESTROY sont associés à des fenêtres particulières tandis que le message WM_QUIT est applicable à l'ensemble de l'application (puits de thread) et le message n'est jamais reçu via une procédure de fenêtre (routine WndProc), mais uniquement via les fonctions GetMessage ou PeekMessage.

Dans votre routine WndProc, la fonction DefWindowProc prend en charge le comportement par défaut de ces messages. Le WM_CLOSE messages demande que l'application se ferme et le comportement par défaut pour cela est d'appeler la fonction DestroyWindow. C'est lorsque cette fonction DestroyWindow est appelée que le message WM_DESTROY est envoyé. Notez que WM_CLOSE n'est qu'un message vous demandant de fermer (comme WM_QUIT ) - vous n'avez pas réellement à quitter/quitter. Mais le message WM_DESTROY vous indique que votre fenêtre [~ # ~] est [~ # ~] fermée et détruite donc vous devez nettoyer toutes les ressources, les poignées, etc.

10
user353297

Juste pour ne pas se perdre dans les commentaires ... n'oubliez pas WM_CANCEL. Lorsque vous cliquez sur le bouton Fermer (x) dans une boîte de dialogue MFC, il enverra certainement WM_CLOSE. La fonction par défaut OnClose() appellera alors la fonction par défaut (classe de base) OnCancel().

Cependant, si vous tapez simplement la touche ESC, cela conduira à la fermeture de la boîte de dialogue, mais (pour autant que je sache) sans générer l'événement WM_CLOSE - cela va directement à la WM_CANCEL/OnCancel() mécanisme.

J'invite par la présente la communauté à développer cela ... ou à éditer cette élaboration dans la réponse acceptée.

4
omatai

Dans un premier temps, discutons de WM_QUIT - la différence avec d'autres messages que cela n'est pas associé à la fenêtre. Il est utilisé par application. Par exemple, cela peut être géré par un serveur autonome non visible OLE (.exe, mais pas in-proc comme .dll)

WM_CLOSE - par msdn: "ne application peut inviter l'utilisateur à confirmer, avant de détruire une fenêtre" - elle est utilisée comme notification sur l'intention de fermer (vous pouvez rejeter cette intention).

WM_DESTROY - est un fait que la fenêtre se ferme et toutes les ressources doivent (!) Être désallouées.

2
Dewfy