TN017: Destruir objetos de ventana

Esta nota describe el uso de la función de miembro CWnd::PostNcDestroy . Utilice esta función si desea hacer una asignación personalizada de CWnd-objetos derivados.

Esta nota también explica algunas de las razones para la regla Cardenal:

Para destruir un objeto de C++ Windows, utilice DestroyWindow no "eliminar".

Esto es importante. Si sigue las pautas a continuación, tendrá pocos problemas de limpieza (como olvidar a liberar y eliminar el memoria de C++, olvidando liberar recursos del sistema como HWNDs o liberar objetos demasiadas veces).

El problema

Windows objetos (objetos de clases derivadas de CWnd) representan un objeto de C++ (asignada en el montículo de la aplicación) y un HWND (asignada en los recursos del sistema por el administrador de ventanas). Ya que hay varias maneras de destruir un objeto window, debemos ofrecer un conjunto de normas que impiden los recursos de sistema o pérdidas de memoria de la aplicación y que impedir que objetos y controladores de Windows se destruyeron más de una vez.

Esto es más que un problema de administración de memoria. La presencia de una ventana de Windows tiene impacto de interfaz de usuario: una ventana en la pantalla; una vez que se destruya también es un impacto sobre los recursos del sistema. Perdiendo memoria de C++ en el espacio de dirección de su aplicación no es tan mala como la fuga de recursos del sistema.

Destrucción de Windows

Son las dos formas permitidas para destruir un objeto de Windows:

El primer caso es el más común. Este caso se aplica incluso si no se llama a DestroyWindow directamente por el código. El es el caso cuando el usuario cierra directamente una ventana de marco (el comportamiento predeterminado de WM_CLOSE es llamada DestroyWindow), y cuando se destruye una ventana padre, Windows llama a DestroyWindow para todos los niños.

El segundo caso, el uso del operador Eliminar objetos de Windows, debe ser muy raro y sólo en los casos en que se describe a continuación.

Limpieza automática con CWnd::PostNcDestroy

Al destruir una ventana de Windows, el último mensaje de Windows enviado a la ventana es WM_NCDESTROY. El controlador de CWnd predeterminado para ese mensaje (CWnd::OnNcDestroy) será separar el HWND del objeto C++ y llamada que la virtual funciona PostNcDestroy. Algunas clases de reemplazan esta función para eliminar el objeto de C++.

La implementación predeterminada de CWnd::PostNcDestroy no hace nada que sea adecuado para la objetos de ventana asignados en el marco de pila o integrados en otros objetos. Esto no es adecuado para objetos window que están diseñados para ser asignados por sí mismos en el montón (no incrustado en otro objeto de C++).

Las clases que están diseñadas para ser asignados por ellos mismos en el montón reemplazan la función de miembro de PostNcDestroy para realizar un "Borrar esto". Esta declaración será libre de cualquier memoria de C++ asociado con el objeto de C++. A pesar de que el destructor de CWnd predeterminada llama DestroyWindow si antes no es NULL, esto no conduce a una recursión infinita ya que el identificador será nulo y destacado durante la fase de limpieza.

&Notanbsp;  Normalmente se llama CWnd::PostNcDestroy tras las ventanas WM_NCDESTROY mensaje es procesado, como parte de la destrucción de la ventana, y ya no están conectados al HWND y el objeto de ventana de C++. CWnd::PostNcDestroy también se llamará en la ejecución de llamadas a crear más si falla (ver más abajo para las reglas de limpieza automática).

Clases de limpieza automática

Las clases siguientes no están diseñadas para limpieza automática. Normalmente están integrados en otros objetos de C++ o en la pila:

Las siguientes clases están diseñadas para limpieza automática. Normalmente se asignan por sí mismos en el montón:

Si usted desea romper cualquiera de estas reglas, debe reemplazar la función de miembro de PostNcDestroy en la clase derivada. Para agregar auto-limpieza a su clase, simplemente llame a su clase base y realice una Eliminar esto. Para quitar auto-limpieza de su clase, llame a CWnd::PostNcDestroy directamente en lugar del miembro PostNcDestroy de su clase base directa.

El uso más común de lo que antecede es crear un cuadro de diálogo no modal que puede distribuirse en el montón.

A la llamada 'eliminar'

La forma recomendada para destruir un objeto de Windows es llamar a DestroyWindow, o bien la función de miembro de C++ o el Mundial :: DestroyWindow API.

No llame a la global :: DestroyWindow API para destruir una ventana MDI secundarios, utilice la función miembro virtual CWnd::DestroyWindow.

Para objetos de ventana de C++ que no realizan limpieza automática, utilizando DestroyWindow en lugar de Eliminar evita los problemas de tener que llamar a DestroyWindow el CWnd:: ~ CWnd destructor donde la VTBL no está apuntando a la clase derivada correctamente. Esto puede conducir a errores sutiles, por lo que la versión de diagnóstico (depuración) de MFC le avisará con

Advertencia: llamar a DestroyWindow en CWnd:: ~ CWnd
 nbsp; OnDestroy o Post&NcDestroy en la clase derivada no se llamará

En el caso de objetos de C++ Windows que realizan limpieza automática, debe llamar a DestroyWindow. Si usas operador Eliminar directamente, el asignador de memoria diagnóstico MFC le avisará que están liberando memoria dos veces (la primera llamada a Eliminar ), así como la llamada indirecta para "Eliminar este" en la aplicación de auto-limpieza de PostNcDestroy.

Después de llamar a DestroyWindow en un objeto no-auto-limpieza, seguirán siendo el objeto de C++ alrededor, pero antes será NULL. Después de llamar a DestroyWindow en un objeto de limpieza automática, el objeto de C++ será desaparecido, liberado por el operador delete de C++ en la aplicación de auto-limpieza de PostNcDestroy..

&Notas técnicas por número |nbsp; Notas técnicas por categoría

Index