2009-02-24 3 views
21

Los componentes Delphi tienen CreateWnd y CreateWindowHandle (y DestroyWnd y DestroyWindowHandle). Ambos están destinados a ser anulados por los descendientes, ¿verdad? ¿Y no pretende ser llamado, excepto por la implementación de VCL subyacente?¿Cuál es la diferencia entre CreateWnd y CreateWindowHandle?

¿Cuál es la diferencia entre ellos; ¿Cuándo se debe anular alguno de ellos?

Respuesta

36

Hasta ahora, la mayoría de las respuestas aquí son bastante acertadas y haría bien en seguir sus consejos. Sin embargo, hay un poco más de esta historia. A su pregunta específica sobre cuándo anularía una u otra, intentaré resumir las cosas un poco.

CreateParams();

En general, la mayoría de las veces todo lo que necesita hacer es anular CreateParams(). Si todo lo que quieres hacer es crear una subclase (¿recuerdas el estilo de Windows "subclasificación"? Ver el trabajo seminal de Petzold sobre programación de Windows) una clase de control existente y envolverlo en un control de VCL, lo haces desde CreateParams. También puede controlar qué bits de estilo se establecen y otros parámetros diversos. Hemos hecho que el proceso de creación de una "subclase" sea muy fácil. Simplemente llame a CreateSubClass() desde su método CreateParams(). Consulte los controles de VCL principales para ver un ejemplo como TCheckBox o TButton.

CreateWnd();

Anularía esta si necesita hacer un poco más con el identificador de ventana una vez que se ha creado. Por ejemplo, si tiene un control que es algún tipo de lista, árbol o requiere configuración posterior a la creación, lo haría aquí. Llame al CreateWnd heredado, y cuando vuelva (usted sabe que tiene un identificador válido si regresa de CreateWnd porque generará una excepción si algo salió mal), simplemente aplique su magia extra. Un escenario común es tomar los datos que se almacenan en caché en una lista TStrings de instancia y realmente moverlos al control de ventana subyacente. El TListBox es un ejemplo clásico de esto.

CreateWindowHandle();

Tuve que actualizar mi memoria en este caso, pero parece que este es uno rara vez, si es que alguna vez, anulado. En los pocos casos dentro de VCL en sí, parece que se usa para trabajar con versiones específicas de Windows y rarezas locales con algunos controles, como TEdit y TMemo. El otro caso más claro está en TCustomForm. En este caso, está ahí para admitir el viejo modelo de MDI (interfaz de documentos múltiples). En este caso, los elementos secundarios MDI no pueden crearse utilizando la API normal CreateWindowEx(), debe enviar un mensaje al cuadro padre MDI para crear realmente el identificador. Por lo tanto, la única razón para superar este método es si el proceso real de creación del identificador se realiza a través de un medio completamente diferente del antiguo y probado CreateWindowEx().

Me di cuenta de que su pregunta era simplemente preguntando sobre el proceso de creación, pero existen métodos correspondientes que se anulan en algunos casos para la destrucción del mango y el "vudú" que a veces rodea el manejo de la recreación. Pero estos son otros temas que deberían tratarse por separado :-).

+0

Gran respuesta. Solo quería agregar un buen recurso web para completar la respuesta ya que la pregunta original menciona el VCL: http://edn.embarcadero.com/article/20569 – Ampere

4

CreateWnd llama primero a CreateParams, luego llama a CreateWindowHandle utilizando los Params creados. En general, anulará CreateWnd y CreateParams en lugar de CreateWindowHandle.

Espero que esto ayude!

0

Estoy seguro de que la respuesta final solo puede venir de las personas involucradas en la creación del VCL (¿Allen?), Pero en mi humilde opinión el método virtual con menos responsabilidad/que es el más bajo en la cadena de llamadas anulado Es por eso que siempre he anulado CreateParams() y CreateWindowHandle(). Esto parece un buen ajuste ya que ambos son llamados por CreateWnd(), y ambos solo hacen una cosa especial.

Al final es probable que sea una cuestión de preferencia.

2

¿Quién hace qué:
CreateWnd es el contratista general que crea la ventana completamente formada por un WinControl.
Primero, tiene que establecer los atributos necesarios para WindowClass llamando al CreateParams y asegurándose de que esté registrado correctamente.
Luego se crea realmente la ventana, llamando al CreateWindowHandle que devuelve el identificador resultante del sistema operativo.
Después de eso, tenemos una ventana válida capaz de procesar mensajes y CreateWnd hace la presentación final, ajustando diferentes aspectos visuales como el tamaño, la fuente, etc.

También hay paso posterior hecho por CreateHandle, después de que CreateWnd haya finalizado, para ayudar al VCL a administrar sus ventanas (identificación, parentesco, ...).

Cuestiones relacionadas