Compartir a través de


Controles ActiveX de MFC: Pintar un control ActiveX

En este artículo se describe el proceso de pintura de controles ActiveX y cómo se puede modificar el código de pintura para optimizar el proceso. (Consulte Optimización del dibujo de controles para obtener técnicas sobre cómo optimizar el dibujo al no tener controles que restauren individualmente objetos GDI seleccionados previamente. Una vez dibujados todos los controles, el contenedor puede restaurar automáticamente los objetos originales).

Importante

ActiveX es una tecnología heredada que no se debe usar para el desarrollo nuevo. Para obtener más información sobre las tecnologías modernas que sustituyen a ActiveX, consulte Controles ActiveX.

Los ejemplos de este artículo proceden de un control creado por el Asistente para controles ActiveX de MFC con la configuración predeterminada. Para obtener más información sobre cómo crear una aplicación de control de esqueleto mediante el Asistente para controles ActiveX de MFC, consulte el artículo Asistente para controles ActiveX de MFC.

Se tratan los temas siguientes:

Proceso de dibujo de un control ActiveX

Cuando los controles ActiveX se muestran inicialmente o se vuelven a dibujar, siguen un proceso de pintura similar a otras aplicaciones desarrolladas mediante MFC, con una distinción importante: los controles ActiveX pueden estar en un estado activo o inactivo.

Un control activo se representa en un contenedor de controles ActiveX mediante una ventana secundaria. Al igual que otras ventanas, es responsable de pintarse cuando se recibe un mensaje de WM_PAINT. La clase base del control, COleControl, controla este mensaje en su OnPaint función. Esta implementación predeterminada llama a la OnDraw función del control.

Un control inactivo se pinta de forma diferente. Cuando el control está inactivo, su ventana es invisible o inexistente, por lo que no puede recibir un mensaje de pintura. En su lugar, el contenedor de controles llama directamente a la OnDraw función del control. Esto difiere del proceso de dibujo de un control activo en que nunca se llama a la OnPaint función miembro.

Como se describe en los párrafos anteriores, la forma en que se actualiza un control ActiveX depende del estado del control. Sin embargo, dado que el marco llama a la OnDraw función miembro en ambos casos, agrega la mayoría del código de pintura en esta función miembro.

La OnDraw función miembro controla la pintura del control. Cuando un control está inactivo, el contenedor de controles llama a OnDraw, pasando el contexto del dispositivo del contenedor de control y las coordenadas del área rectangular ocupada por el control.

El rectángulo pasado por el marco a la OnDraw función miembro contiene el área ocupada por el control. Si el control está activo, la esquina superior izquierda es (0, 0) y el contexto del dispositivo pasado es para la ventana secundaria que contiene el control. Si el control está inactivo, la coordenada superior izquierda no es necesariamente (0, 0) y el contexto del dispositivo pasado es para el contenedor de control que contiene el control.

Nota:

Es importante que las modificaciones OnDraw no dependan de que el punto superior izquierdo del rectángulo sea igual a (0, 0) y que dibuje solo dentro del rectángulo pasado a OnDraw. Se pueden producir resultados inesperados si se dibuja más allá del área del rectángulo.

La implementación predeterminada proporcionada por el Asistente para controles ActiveX de MFC en el archivo de implementación de control (. CPP), que se muestra a continuación, pinta el rectángulo con un pincel blanco y rellena la elipse con el color de fondo actual.

void CMyAxUICtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
   if (!pdc)
      return;

   // TODO: Replace the following code with your own drawing code.
   pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
   pdc->Ellipse(rcBounds);
}

Nota:

Al pintar un control, no debe realizar suposiciones sobre el estado del contexto del dispositivo que se pasa como parámetro pdc a la OnDraw función. En ocasiones, la aplicación contenedora proporciona el contexto del dispositivo y no se inicializará necesariamente en el estado predeterminado. En concreto, seleccione explícitamente los lápices, pinceles, colores, fuentes y otros recursos de los que depende el código de dibujo.

Optimización del código de pintura

Una vez que el control se pinta correctamente, el siguiente paso es optimizar la OnDraw función.

La implementación predeterminada de la pintura de controles ActiveX pinta todo el área de control. Esto es suficiente para controles simples, pero en muchos casos volver a dibujar el control sería más rápido si solo se reintiera la parte que necesitaba actualizar, en lugar de todo el control.

La OnDraw función proporciona un método sencillo de optimización pasando rcInvalid, el área rectangular del control que necesita volver a dibujar. Use esta área, normalmente menor que todo el área de control, para acelerar el proceso de pintura.

Pintar el control mediante metarchivos

En la mayoría de los casos, el parámetro pdc de la OnDraw función apunta a un contexto de dispositivo de pantalla (DC). Sin embargo, al imprimir imágenes del control o durante una sesión de vista previa de impresión, el controlador de dominio recibido para la representación es un tipo especial denominado "DC de metarchivo". A diferencia de un controlador de dominio de pantalla, que controla inmediatamente las solicitudes enviadas, un controlador de dominio de metarchivo almacena las solicitudes que se reproducirán más adelante. Algunas aplicaciones de contenedor también pueden optar por representar la imagen de control mediante un controlador de dominio de metarchivo cuando están en modo de diseño.

El contenedor puede realizar solicitudes de dibujo de metarchivo a través de dos funciones de interfaz: IViewObject::Draw (también se puede llamar a esta función para el dibujo que no es de metarchivo) y IDataObject::GetData. Cuando se pasa un controlador de dominio de metarchivo como uno de los parámetros, el marco MFC realiza una llamada a COleControl::OnDrawMetafile. Dado que se trata de una función miembro virtual, invalide esta función en la clase de control para realizar cualquier procesamiento especial. El comportamiento predeterminado llama a COleControl::OnDraw.

Para asegurarse de que el control se puede dibujar en contextos de dispositivo de metarchivo y de pantalla, solo debe usar funciones miembro compatibles tanto en una pantalla como en un controlador de dominio de metarchivo. Tenga en cuenta que es posible que el sistema de coordenadas no se mida en píxeles.

Dado que la implementación predeterminada de OnDrawMetafile llama a la función del OnDraw control, use solo las funciones miembro adecuadas para un metarchivo y un contexto de dispositivo de pantalla, a menos que invalide OnDrawMetafile. A continuación se muestra el subconjunto de CDC funciones miembro que se pueden usar en un metarchivo y en un contexto de dispositivo de pantalla. Para obtener más información sobre estas funciones, vea cdc de clase en la referencia de MFC.

arco BibBlt Acorde
Ellipse Escape ExcludeClipRect
ExtTextOut FloodFill IntersectClipRect
LineTo MoveTo OffsetClipRgn
OffsetViewportOrg OffsetWindowOrg PatBlt
Pie Polygon Polyline
PolyPolygon RealizePalette RestoreDC
RoundRect SaveDC ScaleViewportExt
ScaleWindowExt SelectClipRgn SelectObject
SelectPalette SetBkColor SetBkMode
SetMapMode SetMapperFlags SetPixel
SetPolyFillMode SetROP2 SetStretchBltMode
SetTextColor SetTextJustification SetViewportExt
SetViewportOrg SetWindowExt SetWindowORg
StretchBlt TextOut

Además de las CDC funciones miembro, hay otras funciones que son compatibles con un controlador de dominio de metarchivo. Estos incluyen CPalette::AnimatePalette, CFont::CreateFontIndirect y tres funciones miembro de CBrush: CreateBrushIndirect, CreateDIBPatternBrush y CreatePatternBrush.

Las funciones que no se registran en un metarchivo son: DrawFocusRect, DrawIcon, DrawText, ExcludeUpdateRgn, FillRect, FrameRect, GrayString, InvertRect, ScrollDC y TabbedTextOut. Dado que un controlador de dominio de metarchivo no está asociado realmente a un dispositivo, no puede usar SetDIBits, GetDIBits y CreateDIBitmap con un controlador de dominio de metarchivo. Puede usar SetDIBitsToDevice y StretchDIBits con un controlador de dominio de metarchivo como destino. CreateCompatibleDC, CreateCompatibleBitmap y CreateDiscardableBitmap no son significativos con un controlador de dominio de metarchivo.

Otro punto que se debe tener en cuenta al usar un controlador de dominio de metarchivo es que es posible que el sistema de coordenadas no se mida en píxeles. Por este motivo, todo el código de dibujo debe ajustarse para que se ajuste al rectángulo pasado al OnDraw parámetro rcBounds . Esto evita la pintura accidental fuera del control porque rcBounds representa el tamaño de la ventana del control.

Después de implementar la representación del metarchivo para el control, use Contenedor de pruebas para probar el metarchivo. Consulte Probar propiedades y eventos con un contenedor de prueba para obtener información acerca de cómo acceder al contenedor de prueba.

Para probar el metarchivo del control mediante el contenedor de pruebas

  1. En el menú Edición del contenedor de pruebas, haga clic en Insertar nuevo control.

  2. En el cuadro Insertar nuevo control , seleccione el control y haga clic en Aceptar.

    El control aparecerá en el contenedor De prueba.

  3. En el menú Control , haga clic en Dibujar metarchivo.

    Aparece una ventana independiente en la que se muestra el metarchivo. Puede cambiar el tamaño de esta ventana para ver cómo afecta el escalado al metarchivo del control. Puede cerrar esta ventana en cualquier momento.

Consulte también

Controles ActiveX de MFC