2009-11-16 13 views
7

He estado acostumbrado a pensar que WM_CREATE es el primer mensaje que recibe una ventana. Sin embargo, cuando se prueba esta suposición en una ventana de nivel superior, resulta ser falsa. En mi prueba, WM_MINMAXINFO apareció como el primer mensaje.Windows API: ¿Cuál es el primer mensaje que se garantiza que recibirá una ventana?

Entonces, ¿cuál es el primer mensaje que una ventana está garantizada para recibir?

+1

Esta pregunta no tiene sentido. Como ha notado, los primeros mensajes no son siempre lo mismo. Dependiendo de si la ventana se crea visible o no, una gran cantidad de mensajes pueden llegar a WindowPRoc antes de que CreateWindow vuelva a aparecer. qué mensajes y su orden ha cambiado entre las versiones de Windows. Todo lo que tienes garantizado es que WM_CREATE - y ahora WM_NCREATE - se enviará antes de que CreateWindow regrese (suponiendo que la creación de una ventana sea exitosa). –

+3

Chris, ¿por qué un comentario en lugar de una respuesta? Además, ¿no tiene ningún sentido? Apuesto a que el 90% de los desarrolladores de Win32 juraría que WM_CREATE es el primer msg recibido (y yo fui uno de ellos hasta hace 30 segundos). Después de todo, eso es lo que todos leemos en nuestros libros de texto. –

+0

De acuerdo Serge Wautier, pensé esto también hasta que hice una pequeña prueba. Este es el orden de todos mis mensajes WM hasta WM_CREATE: WM_GETMINMAXINFO, WM_NCCREATE, WM_NCCALCSIZE, WM_CREATE. – Kit10

Respuesta

6

Respondió su propia pregunta. También veo WM_GETMINMAXINFO, en Windows XP SP3, seguido de WM_NCCREATE, WM_NCCALCSIZE y finalmente WM_CREATE antes de que CreateWindowEx() haya devuelto el identificador a la ventana que se está creando. Qué garabage '

La respuesta general es que Microsoft es incompetente cuando se trata de la creación ordenada y la destrucción de objetos. Se equivocan con Windows, con COM y con controladores de dispositivo. Siempre hay algún catch-22 donde un objeto está medio creado o medio destruido que requiere alguna solución intrincada para producir un producto confiable.

+0

WM_GETMINMAXINFO es el primer mensaje para una ventana de nivel superior. Para otras ventanas, parece WM_NCCREATE. –

13

WM_NCCREATE es en realidad el very first message your window will receive, que llegará antes de WM_CREATE. Está relacionado con la creación del área no cliente (por ejemplo, barra de título, menú del sistema, etc.), de ahí el prefijo NC.

WM_GETMINMAXINFO se envía before the window size/position is changed, y puede llegar antes de WM_CREATE (consulte a continuación para obtener más información).

El mensaje WM_CREATE se envía antes de CreateWindow() devuelve, por lo que puede garantizar que la inicialización por ventana se haya realizado en ese punto. Su proceso de ventana recibirá WM_CREATE después de que se cree la ventana, pero antes de que la ventana se vuelva visible (WM_SHOWWINDOW).

En realidad, hay una inconsistencia interesante en la documentación de MSDN: los mensajes de creación parecen depender de si llama a CreateWindow() o CreateWindowEx(), sin embargo, no especifica que los mensajes se enumeran necesariamente en orden de envío.

  • CreateWindow(): WM_CREATE, WM_GETMINMAXINFO y WM_NCCREATE
  • CreateWindowEx(): WM_NCCREATE, WM_NCCALCSIZE y WM_CREATE

sospecho fuertemente que el orden de los mensajes se describe en CreateWindow() debe tener WM_NCCREATE primero, y la regularidad WM_CREATE última , que es coherente con la documentación de notificación y la referencia CreateWindowEx() (y también de acuerdo con lo que describir).

Raymond Chen también tiene algunos interesantes information on window creation/destruction.

Todo parece indicar que incluso las cosas aparentemente simples pueden volverse más complejas cuanto más las mires.

+0

Es interesante que WM_NCCREATE se introdujo en Win95, lo que explica por qué no estaba documentado en "Programación de Windows" de Petzold cuando lo leí por primera vez en 1997. –

+2

WM_NCCREATE ha existido desde Windows 1.0. Hay muchas cosas que Petzold nunca intentó cubrir. –

+1

Mucha información útil aquí y siento devolver el voto. Sin embargo, WM_NCCREATE es el primer mensaje solo para ventanas de nivel superior. –

1

Puede usar spy ++ que viene con Visual Studio para ver qué mensajes se generan cuando se inicia la aplicación o la ventana.

2

Los resultados por experimentación son mejores que simplemente confiar en la fuente, especialmente porque la fuente está compuesta por una legión de programadores, y ninguno conoce todo el código.Dicho esto:

El primer mensaje que recibo es 0x24 (WM_GETMINMAXINFO).

¿Puedo asumir que siempre será el primer mensaje? No, ya que el cambio de código entre las versiones de Windows y Microsoft no ha documentado un mensaje que garantiza que será el primero recibido.

Conclusión: No asuma que se llamó a WM_CREATE antes de otro mensaje.

+1

No, la experimentación nunca es una buena idea. Estas cosas no están documentadas por una razón. No hay garantía de que 'WM_GETMINMAXINFO' sea * siempre * el primer mensaje enviado, sin importar la versión de Windows y la configuración de la máquina del usuario. Cualquier aplicación que dependa de recibir mensajes en un orden determinado como este está fundamentalmente rota. La documentación le dice que asuma que 'WM_NCCREATE' es el primer mensaje recibido. Debería hacer allí toda su inicialización: funcionará siempre, sin importar en qué sistema se ejecute su aplicación. No aplique ingeniería inversa a Windows. –

Cuestiones relacionadas