Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En esta nota se describe la compatibilidad de MFC con controles personalizados y de autorretrato. También se describen las subclases dinámicas y se describe la relación entre objetos CWnd y HWNDs.
La aplicación de ejemplo MFC CTRLTEST muestra cómo usar muchos controles personalizados. Consulte el código fuente del ejemplo general de MFC CTRLTEST y la ayuda en línea.
controles y menús de Owner-Draw
Windows proporciona soporte para controles de dibujo personalizado y menús mediante mensajes de Windows. La ventana primaria de cualquier control o menú recibe estos mensajes y llama a funciones en respuesta. Puede invalidar estas funciones para personalizar la apariencia visual y el comportamiento del control o menú de dibujo del propietario.
MFC admite directamente el dibujado por el propietario con las siguientes funciones:
Puedes sobrescribir estas funciones en tu CWnd clase derivada para implementar un comportamiento de dibujo personalizado.
Este enfoque no conduce a código reutilizable. Si tiene dos controles similares en dos clases diferentes CWnd , debe implementar el comportamiento de control personalizado en dos ubicaciones. La arquitectura de control de dibujo automática compatible con MFC resuelve este problema.
Controles y menús de Self-Draw
MFC proporciona una implementación predeterminada (en las CWnd clases y CMenu ) para los mensajes de dibujo del propietario estándar. Esta implementación predeterminada descodificará los parámetros de dibujo del propietario y delegará los mensajes de dibujo del propietario en los controles o menús. Esto se denomina autotrabaje porque el código de dibujo está en la clase del control o menú, no en la ventana del propietario.
Mediante el uso de controles autodibujados, puede crear clases de control reutilizables que usen semánticas de dibujo personalizadas para mostrar el control. El código para dibujar el control está en la clase del control, no en su elemento primario. Se trata de un enfoque orientado a objetos para la programación de controles personalizados. Agregue la siguiente lista de funciones a las clases de auto-dibujo:
Para los botones de dibujo automático:
CButton::DrawItem(LPDRAWITEMSTRUCT); // insert code to draw this buttonPara menús autodibujables:
CMenu::MeasureItem(LPMEASUREITEMSTRUCT); // insert code to measure the size of an item in this menu CMenu::DrawItem(LPDRAWITEMSTRUCT); // insert code to draw an item in this menuPara los cuadros de lista autodibujables:
CListBox::MeasureItem(LPMEASUREITEMSTRUCT); // insert code to measure the size of an item in this list box CListBox::DrawItem(LPDRAWITEMSTRUCT); // insert code to draw an item in this list box CListBox::CompareItem(LPCOMPAREITEMSTRUCT); // insert code to compare two items in this list box if LBS_SORT CListBox::DeleteItem(LPDELETEITEMSTRUCT); // insert code to delete an item from this list boxPara cuadros combinados personalizados:
CComboBox::MeasureItem(LPMEASUREITEMSTRUCT); // insert code to measure the size of an item in this combo box CComboBox::DrawItem(LPDRAWITEMSTRUCT); // insert code to draw an item in this combo box CComboBox::CompareItem(LPCOMPAREITEMSTRUCT); // insert code to compare two items in this combo box if CBS_SORT CComboBox::DeleteItem(LPDELETEITEMSTRUCT); // insert code to delete an item from this combo box
Para obtener más información sobre las estructuras de dibujo del propietario (DRAWITEMSTRUCT, MEASUREITEMSTRUCT, COMPAREITEMSTRUCT y DELETEITEMSTRUCT), consulte la documentación de MFC para CWnd::OnDrawItem, CWnd::OnMeasureItem, CWnd::OnCompareItemy CWnd::OnDeleteItem respectivamente.
Uso de controles y menús auto-diseñados
Para los menús autodibujados, debe sobrescribir tanto los métodos OnMeasureItem como OnDrawItem.
En el caso de los cuadros de lista auto dibujados y los cuadros combinados, debe invalidar OnMeasureItem y OnDrawItem. Debe especificar el estilo de LBS_OWNERDRAWVARIABLE para los cuadros de lista o el estilo CBS_OWNERDRAWVARIABLE para los cuadros combinados de la plantilla de diálogo. El estilo OWNERDRAWFIXED no funcionará con elementos auto-dibujados porque la altura fija del elemento se determina antes de que los controles auto-dibujados se adjunten al cuadro de lista. (Puede usar los métodos CListBox::SetItemHeight y CComboBox::SetItemHeight para superar esta limitación).
Cambiar a un estilo OWNERDRAWVARIABLE obligará al sistema a aplicar el estilo NOINTEGRALHEIGHT al control. Dado que el control no puede calcular una altura integral con elementos de tamaño variable, se ignora el estilo predeterminado "INTEGRALHEIGHT" y el control siempre se establece en "NOINTEGRALHEIGHT". Si los elementos son de altura fija, puede evitar que se dibujen elementos parciales especificando el tamaño del control para que sea un multiplicador entero del tamaño del elemento.
En el caso de los cuadros de lista autodibujo y los cuadros combinados con el estilo LBS_SORT o CBS_SORT, debe reemplazar el método OnCompareItem.
En el caso de los cuadros de lista de dibujo automático y los cuadros combinados, OnDeleteItem normalmente no se invalida. Puede invalidar OnDeleteItem si desea realizar cualquier procesamiento especial. Un caso en el que esto sería aplicable es cuando se almacenan memoria adicional u otros recursos con cada cuadro de lista o elemento de cuadro combinado.
Ejemplos de controles y menús de Self-Drawing
El ejemplo general de MFC CTRLTEST proporciona muestras de un menú de auto-dibujo y un cuadro de lista de auto-dibujo.
El ejemplo más típico de un botón de auto dibujo es un botón de mapa de bits. Un botón de mapa de bits es un botón que muestra una, dos o tres imágenes de mapa de bits para los distintos estados. Se proporciona un ejemplo de esto en la clase CBitmapButton de MFC.
Subclases dinámicos
En ocasiones, querrá cambiar la funcionalidad de un objeto que ya existe. Los ejemplos anteriores requerían personalizar los controles antes de crearlos. La subclases dinámica permite personalizar un control que ya se ha creado.
La subclasificación es el término de Windows para reemplazar el WndProc de una ventana por un personalizado WndProc y llamar al antiguo WndProc para la funcionalidad predeterminada.
Esto no debe confundirse con la derivación de clases de C++. Para aclararlo, la clase base de términos de C++ y la clase derivada son análogas a superclases y subclases en el modelo de objetos de Windows. La derivación de C++ con MFC y subclases de Windows es funcionalmente similar, excepto que C++ no admite la subclases dinámica.
La CWnd clase proporciona la conexión entre un objeto de C++ (derivado de CWnd) y un objeto de ventana de Windows (conocido como HWND).
Hay tres formas comunes de relacionarse:
CWndcrea elHWND. Puede modificar el comportamiento en una clase derivada mediante la creación de una clase derivada deCWnd.HWNDse crea cuando la aplicación llama a CWnd::Create.La aplicación adjunta un
CWnda unHWNDexistente. El comportamiento de la ventana existente no se modifica. Este es un caso de delegación y se hace posible mediante la llamada a CWnd::Attach para convertir unHWNDexistente en un objetoCWnd.CWndestá asociado a un existenteHWNDy puede modificar el comportamiento en una clase derivada. Esto se denomina subclases dinámico porque estamos cambiando el comportamiento y, por tanto, la clase de un objeto de Windows en tiempo de ejecución.
Puede lograr subclases dinámicas mediante los métodos CWnd::SubclassWindow y CWnd::SubclassDlgItem.
Ambas rutinas asocian un CWnd objeto a un existente HWND.
SubclassWindow toma el HWND directamente.
SubclassDlgItem es una función auxiliar que toma un identificador de control y la ventana primaria.
SubclassDlgItem está diseñado para adjuntar objetos de C++ a controles de diálogo creados a partir de una plantilla de diálogo.
Vea el ejemplo CTRLTEST para obtener varios ejemplos de cuándo usar SubclassWindow y SubclassDlgItem.