2010-07-01 6 views

Respuesta

70

Son totalmente diferentes.

WM_CLOSE se envía a la ventana cuando se presiona "X" o se elige "Cerrar" en el menú de la ventana. Si captas este mensaje, esta es tu decisión sobre cómo tratarlo: ignóralo o cierra la ventana. De forma predeterminada, WM_CLOSE pasó a DefWindowProc provoca la destrucción de la ventana. Cuando se destruye la ventana, se envía el mensaje WM_DESTROY. En esta etapa, en oposición al WM_CLOSE, no puede detener el proceso; solo puede realizar una limpieza necesaria. Pero recuerde que cuando detecta WM_DESTROY justo antes de que todas las ventanas secundarias ya estén destruidas. WM_NCDESTROY se envía justo después de que se hayan destruido todas las ventanas hijas.

WM_QUIT mensaje no está relacionado con ninguna ventana (el hwnd obtenido de GetMessage es NULL y no se llama a ningún procedimiento de ventana). Este mensaje indica que el ciclo de mensajes debe detenerse y la aplicación debe cerrarse. Cuando GetMessage lee WM_QUIT, devuelve 0 para indicar eso. Eche un vistazo a typical message loop snippet - el ciclo continúa mientras GetMessage devuelve un valor distinto de cero. WM_QUIT se puede enviar por la función PostQuitMessage. Esta función se suele llamar cuando la ventana principal recibe WM_DESTROY (consulte typical window procedure snippet).

+2

Gran respuesta, pero mirando el código del bucle de mensajes, el bucle continúa mientras 'GetMessage' devuelve un valor distinto de cero, no hasta, a menos que me falta algo. –

+0

Sí, por supuesto, corregido. – adf88

+0

@ ad88 sería genial agregar lo que sucede cuando llega el inicio de sesión de usuario/'WM_ENDSESSION'. ¿Esto activa automáticamente WM_CLOSE/QUIT/DESTROY? – Basj

3

Primero analicemos WM_QUIT - la diferencia de otros mensajes que esto no está asociado con la ventana. Es utilizado por la aplicación. Por ejemplo, esto puede ser manejado por un servidor OLE independiente no visible (.exe, pero no en el proceso como .dll)

WM_CLOSE - por msdn: "Una aplicación puede solicitar confirmación al usuario, antes de destruir un ventana "- se usa como notificación sobre la intención de cerrar (puede rechazar esta intención).

WM_DESTROY - es un hecho que la ventana se está cerrando y todos los recursos deben (!) Ser desasignados.

+4

WM_QUIT es en realidad por subproceso, no por aplicación. – atzz

+0

@atzz sí, tienes razón. Hablando en general, este mensaje notifica que el bucle de eventos deja de manipularse, independientemente del ancho de la aplicación o independiente. – Dewfy

9

En primer lugar, los mensajes WM_CLOSE y WM_DESTROY están asociados con las ventanas particulares mientras que el mensaje WM_QUIT es aplicable a toda la aplicación (así rosca) y el mensaje no se recibe a través de un procedimiento de ventana (WndProc rutina), pero sólo a través las funciones GetMessage o PeekMessage.

En su rutina WndProc, la función DefWindowProc se ocupa del comportamiento predeterminado de estos mensajes. Los mensajes WM_CLOSE solicitan que la aplicación se cierre y el comportamiento predeterminado para esto es llamar a la función DestroyWindow. Es cuando se llama a esta función DestroyWindow que se envía el mensaje WM_DESTROY. Tenga en cuenta que el WM_CLOSE es solo un mensaje que le solicita que cierre (como WM_QUIT); en realidad, no tiene que salir/salir. Pero el mensaje WM_DESTROY le dice que su ventana de ES estando cerrado y destruyeron por lo que debe limpiar cualquier recurso, etc maneja

+0

No para toda la aplicación, sino para un bucle de mensaje en particular. Cada subproceso puede tener su propio bucle de mensaje, por lo que una aplicación puede tener varios bucles de mensajes. – 0xC0000022L

3

Sólo por lo que no se pierde en los comentarios ... no se olvide de WM_CANCEL . Cuando hace clic en el botón Cerrar (x) en un cuadro de diálogo MFC, ciertamente enviará WM_CLOSE.La función predeterminada OnClose() llamará a la función predeterminada (clase base) OnCancel().

Sin embargo, si sólo hay que escribir la clave ESC, esto dará lugar a la clausura del diálogo, pero (por lo que puedo decir) sin generar el evento WM_CLOSE - que va directamente al mecanismo WM_CANCEL/OnCancel().

Por la presente invito a la comunidad a profundizar en esto ... o edite esa elaboración en la respuesta aceptada.

Cuestiones relacionadas