Compartir a través de


Controles ActiveX en Internet

Los controles ActiveX son la versión actualizada de la especificación de control OLE.

Importante

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

Los controles son una arquitectura principal para desarrollar componentes de software programables que se pueden usar en una variedad de contenedores diferentes, incluidos los exploradores web compatibles con COM en Internet. Cualquier control ActiveX puede ser un control de Internet y puede agregar su funcionalidad a un documento activo o formar parte de una página web. Los controles de una página web se pueden comunicar entre sí mediante scripting.

Los controles ActiveX no se limitan a Internet. Un control ActiveX también se puede usar en cualquier contenedor, siempre y cuando el control admita las interfaces requeridas por ese contenedor.

Los controles ActiveX tienen varias ventajas, entre las que se incluyen:

  • Se necesitan menos interfaces que con los controles OLE anteriores.

  • La capacidad de no tener ventanas y estar siempre activos en contexto.

Para ser un control ActiveX, debe:

  • Ser compatible con la interfaz IUnknown.

  • Ser un objeto COM.

  • Exportar DLLRegisterServer y DLLUnRegisterServer.

  • Admitir interfaces adicionales según sea necesario para la funcionalidad.

Hacer que los controles existentes sean fáciles de usar en Internet

El diseño de un control que funcione bien en un entorno de Internet requiere tener en cuenta tasas de transmisión relativamente bajas en Internet. Puede usar los controles existentes; sin embargo, hay pasos que debe seguir para que el tamaño del código sea menor y para que las propiedades de control se descarguen de forma asincrónica.

Para mejorar el rendimiento de los controles, siga estas sugerencias sobre consideraciones de eficiencia:

  • Implemente las técnicas descritas en el artículo Controles ActiveX: optimización.

  • Tenga en cuenta cómo se crea una instancia de un control.

  • Ser asincrónico; no retener otros programas.

  • Descargar datos en bloques pequeños.

    Al descargar secuencias de gran tamaño, como mapas de bits o datos de vídeo, accede a los datos de un control de forma asincrónica en cooperación con el contenedor. Recupere los datos de forma incremental o progresiva, trabajando de forma cooperativa con otros controles que también puedan estar recuperando datos. El código también se puede descargar de forma asincrónica.

  • Descargue el código y las propiedades en segundo plano.

  • Conviértase en la interfaz de usuario activa lo más rápido posible.

  • Tenga en cuenta cómo se almacenan los datos persistentes, tanto las propiedades como los blobs de datos grandes (como una imagen de mapa de bits o datos de vídeo).

    Los controles con grandes cantidades de datos persistentes, como mapas de bits grandes o archivos AVI, requieren mucha atención del método de descarga. Un documento o página puede visualizarse lo antes posible y permitir que el usuario interactúe con la página mientras los controles recuperan datos en segundo plano.

  • Escriba rutinas eficaces para mantener bajos el tamaño del código y el tiempo de ejecución.

    Los controles pequeños de botón y etiqueta, con solo unos pocos bytes de datos persistentes, son adecuados para su uso en el entorno de Internet y funcionan bien dentro de los exploradores.

  • Considere la posibilidad de que se comunique el progreso al contenedor.

    Notifique al contenedor el progreso de la descarga asincrónica, incluido el momento en que el usuario puede empezar a interactuar con una página y cuando se completa la descarga. El contenedor puede mostrar el progreso (por ejemplo, el porcentaje completado) al usuario.

  • Tenga en cuenta cómo se registran los controles en el equipo cliente.

Creación de un nuevo control ActiveX

Al crear un nuevo control mediante el Asistente para aplicaciones, puede optar por habilitar la compatibilidad con monikers asincrónicos, así como otras optimizaciones. Para agregar compatibilidad para descargar las propiedades de control de forma asincrónica, siga estos pasos:

Para crear un proyecto mediante el Asistente para controles ActiveX de MFC.

  1. Haga clic en Nuevo en el menú Archivo.

  2. Seleccione Asistente para controles ActiveX de MFC en los proyectos de Visual Studio C++ y asigne un nombre al proyecto.

  3. En la página Configuración del control, seleccione Cargar propiedades de forma asincrónica. Al seleccionar esta opción, se configura la propiedad de estado listo y el evento de cambio de estado listo.

    También puede seleccionar otras optimizaciones, como la activación sin ventana, que se describe en Controles ActiveX: optimización.

  4. Haga clic en Finalizar para crear el proyecto.

Para crear una clase derivada de CDataPathProperty

  1. Cree una nueva clase derivada de CDataPathProperty.

  2. En cada uno de los archivos de código fuente que se incluyen en el archivo de encabezado del control, agregue el archivo de encabezado para esta clase antes de ella.

  3. En esta clase, invalide OnDataAvailable. Se llama a esta función cada vez que los datos están disponibles para mostrarse. A medida que los datos están disponibles, puede controlarlos de cualquier manera que elija, por ejemplo, mediante su representación progresiva.

    El fragmento de código siguiente es un ejemplo sencillo de mostrar progresivamente los datos en un control de edición. Observe el uso de la marca BSCF_FIRSTDATANOTIFICATION para borrar el control de edición.

    void CMyDataPathProperty::OnDataAvailable(DWORD dwSize, DWORD bscfFlag)
    {
       CListCtrl list_ctrl;
       CEdit *edit = list_ctrl.GetEditControl();
       if ((bscfFlag & BSCF_FIRSTDATANOTIFICATION) && edit->m_hWnd)
       {
          edit->SetSel(0, -1);
          edit->Clear();
       }
    
       if (dwSize > 0)
       {
          CString string;
          LPTSTR str = string.GetBuffer(dwSize);
          UINT nBytesRead = Read(str, dwSize);
          if (nBytesRead > 0)
          {
             string.ReleaseBuffer(nBytesRead);
             edit->SetSel(-1, -1);
             edit->ReplaceSel(string);
          }
       }
    }
    

    Tenga en cuenta que debe incluir AFXCMN.H para usar la clase CListCtrl.

  4. Cuando cambie el estado general del control (por ejemplo, de cargando a inicializado o usuario interactivo), llame a COleControl::InternalSetReadyState. Si el control tiene solo una propiedad de ruta de acceso de datos, puede agregar código en BSCF_LASTDATANOTIFICATION para notificar al contenedor que se ha completado la descarga. Por ejemplo:

    if (bscfFlag & BSCF_LASTDATANOTIFICATION)
    {
       GetControl()->InternalSetReadyState(READYSTATE_COMPLETE);
    }
    
  5. Reemplace OnProgress. En OnProgress, se pasa un número que muestra el intervalo máximo y un número que muestra lo que ha avanzado la descarga actual. Puede usar estos números para mostrar el estado, como el porcentaje completado, al usuario.

En el siguiente procedimiento se agrega una propiedad al control para usar la clase que se acaba de derivar.

Para agregar una propiedad

  1. En la Vista de clases, haga clic con el botón derecho en la interfaz debajo del nodo de biblioteca y seleccione Agregar y, después, Agregar propiedad. Se iniciará el Asistente para agregar propiedades.

  2. En el Asistente para agregar propiedades, seleccione el botón de radio Establecer u obtener métodos, escriba el Nombre de propiedad, por ejemplo, EditControlText, y seleccione BSTR como Tipo de propiedad.

  3. Haga clic en Finalizar

  4. Declare una variable miembro de la clase derivada de CDataPathProperty en la clase de control ActiveX.

    CMyDataPathProperty EditControlText;
    
  5. Implemente los métodos Get/Set. Para Get, devuelve la cadena. Para Set, carga la propiedad y llama a SetModifiedFlag.

    BSTR CMFCActiveXControlCtrl::GetEditControlText(void)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
       CString strResult;
       strResult = EditControlText.GetPath();
       return strResult.AllocSysString();
    }
    
    void CMFCActiveXControlCtrl::SetEditControlText(LPCTSTR newVal)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
       Load(newVal, EditControlText);
       SetModifiedFlag();
    }
    
  6. En DoPropExchange, agregue la línea siguiente:

    PX_DataPath(pPX, _T("DataPath"), EditControlText);
    
  7. Invalide ResetData para notificar a la propiedad que restablezca su control agregando esta línea:

    EditControlText.ResetData();
    

Decisión de si se va a derivar de CDataPathProperty o de CCachedDataPathProperty

En el ejemplo anterior se describen los pasos para derivar la propiedad del control de CDataPathProperty. Esta es una buena opción si descarga datos en tiempo real que cambian con frecuencia y para los que no es necesario mantener todos los datos, sino solo el valor actual. Un ejemplo es un control de tablero de cotizaciones.

También se puede derivar de CCachedDataPathProperty. En este caso, los datos descargados se almacenan en caché en un archivo de memoria. Es una buena opción si necesita conservar todos los datos descargados, por ejemplo, un control que representa progresivamente un mapa de bits. En este caso, la clase tiene una variable miembro que contiene los datos:

CMemFile m_Cache;

En la clase de control ActiveX, puede usar este archivo asignado a memoria en OnDraw para mostrar los datos. En la clase derivada de CCachedDataPathProperty del control ActiveX, invalide la función miembro OnDataAvailable e invalide el control, después de llamar a la implementación de la clase base.

void CMyCachedDataPathProperty::OnDataAvailable(DWORD dwSize, DWORD bscfFlag)
{
   CCachedDataPathProperty::OnDataAvailable(dwSize, bscfFlag);
   GetControl()->InvalidateControl();
}

Descarga de datos de forma asincrónica mediante controles ActiveX

La descarga de datos a través de una red debe realizarse de forma asincrónica. La ventaja de hacerlo es que si se transfiere una gran cantidad de datos o si la conexión es lenta, el proceso de descarga no bloqueará otros procesos en el cliente.

Los monikers asincrónicos proporcionan una manera de descargar datos de forma asincrónica a través de una red. Una operación de lectura en un moniker asincrónico se devuelve inmediatamente, incluso si la operación no se ha completado.

Por ejemplo, si solo hay 10 bytes disponibles y la lectura se llama de forma asincrónica en un archivo de 1 K, la lectura no se bloquea, sino que devuelve los 10 bytes disponibles actualmente.

Los monikers asincrónicos se implementan mediante la clase CAsyncMonikerFile. Sin embargo, los controles ActiveX pueden usar la clase CDataPathProperty, que se deriva de CAsyncMonikerFile, para ayudar a implementar propiedades de control asincrónicas.

Visualización de un control en una página web

Este es un ejemplo de una etiqueta de objeto y atributos para insertar un control en una página web.

<OBJECT
  CLASSID="clsid:FC25B780-75BE-11CF-8B01-444553540000"
  CODEBASE="/ie/download/activex/iechart.ocx"
  ID=chart1
  WIDTH=400
  HEIGHT=200
  ALIGN=center
  HSPACE=0
  VSPACE=0>
  <PARAM NAME="BackColor" value="#ffffff"/>
  <PARAM NAME="ForeColor" value="#0000ff"/>
  <PARAM NAME="url" VALUE="/ie/controls/chart/mychart.txt"/>
</OBJECT>

Actualización de un control OLE existente para usar nuevas características de control ActiveX

Si el control OLE se creó con una versión de Visual C++ anterior a 4.2, hay pasos que puede seguir para mejorar su rendimiento y mejorar su funcionalidad. Para obtener una explicación detallada de estos cambios, consulte Controles ActiveX: optimización.

Si va a agregar compatibilidad con propiedades asincrónicas a un control existente, deberá agregar la propiedad de estado listo y el evento ReadyStateChange usted mismo. En el constructor del control, agregue:

m_lReadyState = READYSTATE_LOADING;

Actualizará el estado listo a medida que se descargue el código llamando a COleControl::InternalSetReadyState. Un lugar en el que se puede llamar a InternalSetReadyState es en la invalidación de OnProgress de la clase derivada de CDataPathProperty.

Consulte también

Tareas de programación para Internet de MFC
Fundamentos de programación para Internet de MFC