Compartir a través de


Controles ActiveX de MFC: Temas avanzados

En este artículo se tratan temas avanzados relacionados con el desarrollo de controles ActiveX. Estos incluyen:

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.

Uso de clases de base de datos en controles ActiveX

Dado que las clases de control ActiveX forman parte de la biblioteca de clases, puede aplicar los mismos procedimientos y reglas para usar clases de base de datos en una aplicación MFC estándar para desarrollar controles ActiveX que usan las clases de base de datos MFC.

Para obtener información general sobre las clases de base de datos MFC, consulte Clases de base de datos de MFC (DAO y ODBC). En el artículo se presentan las clases ODBC de MFC y las clases DAO de MFC y se le dirige a más detalles sobre cualquiera de ellas.

Nota:

DAO se admite mediante Office 2013. DAO 3.6 es la versión final y se considera obsoleta. El entorno y los asistentes de Visual C++ no admiten DAO (aunque se incluyen las clases DAO y todavía se pueden usar). Microsoft recomienda usar plantillas OLE DB o ODBC y MFC para nuevos proyectos. Solo debe usar DAO para mantener las aplicaciones existentes.

Implementación de una propiedad parametrizada

Una propiedad parametrizada (a veces denominada matriz de propiedades) es un método para exponer una colección homogénea de valores como una sola propiedad del control. Por ejemplo, puede usar una propiedad parametrizada para exponer una matriz o un diccionario como una propiedad. En Visual Basic, se accede a esta propiedad mediante la notación de matriz:

x = o.Array(2, 3) ' gets element of 2D array
o.Array(2, 3) = 7 ' sets element of 2D array

Use el Asistente para agregar propiedades para implementar una propiedad parametrizada. El Asistente para agregar propiedades implementa la propiedad agregando un par de funciones Get/Set que permiten al usuario de control acceder a la propiedad mediante la notación anterior o de forma estándar.

De forma similar a los métodos y propiedades, las propiedades parametrizadas también tienen un límite para el número de parámetros permitidos. En el caso de las propiedades parametrizadas, el límite es 15 parámetros (con un parámetro reservado para almacenar el valor de la propiedad).

El procedimiento siguiente agrega una propiedad parametrizada, denominada Array, a la que se puede tener acceso como una matriz bidimensional de enteros.

Para agregar una propiedad parametrizada mediante el Asistente para agregar propiedades

  1. Cargue el proyecto del control.

  2. En la Vista de clases, expanda el nodo biblioteca del control.

  3. Haga clic con el botón derecho en el nodo de interfaz del control (el segundo nodo del nodo de biblioteca) para abrir el menú contextual.

  4. En el menú contextual, haga clic en Agregar y, a continuación, haga clic en Agregar propiedad.

  5. En el cuadro Nombre de propiedad , escriba Array.

  6. En el cuadro Tipo de propiedad , seleccione short.

  7. En Tipo de implementación , haga clic en Obtener o establecer métodos.

  8. En los cuadros Obtener función y Establecer función , escriba nombres únicos para las funciones Get y Set o acepte los nombres predeterminados.

  9. Agregue un parámetro, denominado fila (tipo short), mediante los controles Nombre de parámetro y Tipo de parámetro .

  10. Agregue un segundo parámetro denominado column (type short).

  11. Haga clic en Finalizar

Cambios realizados por el Asistente para agregar propiedades

Al agregar una propiedad personalizada, el Asistente para agregar propiedades realiza cambios en el encabezado de la clase de control (. H) y la implementación (. Archivos CPP).

Las líneas siguientes se agregan a la clase de control . Archivo H:

SHORT GetArray(SHORT row, SHORT column);
void SetArray(SHORT row, SHORT column, SHORT newVal);

Este código declara dos funciones llamadas GetArray y SetArray que permiten al usuario solicitar una fila y una columna específicas al acceder a la propiedad .

Además, el Asistente para agregar propiedades agrega las siguientes líneas al mapa de distribución de controles, ubicado en la implementación de la clase de control (. Archivo CPP):

DISP_PROPERTY_PARAM_ID(CMyAxUICtrl, "Array", dispidArray, GetArray, SetArray, VT_I2, VTS_I2 VTS_I2)

Por último, las implementaciones de las GetArray funciones y SetArray se agregan al final de . Archivo CPP. En la mayoría de los casos, modificará la función Get para devolver el valor de la propiedad . La función Set normalmente contendrá código que se debe ejecutar, ya sea antes o después de que cambie la propiedad.

Para que esta propiedad sea útil, podría declarar una variable de miembro de matriz bidimensional en la clase de control, de tipo short, para almacenar valores para la propiedad parametrizada. A continuación, podría modificar la función Get para devolver el valor almacenado en la fila y columna adecuadas, como se indica en los parámetros, y modificar la función Set para actualizar el valor al que hacen referencia los parámetros de fila y columna.

Control de errores en el control ActiveX

Si se producen condiciones de error en el control, es posible que tenga que notificar el error al contenedor de control. Hay dos métodos para notificar errores, en función de la situación en la que se produzca el error. Si el error se produce dentro de la función Get o Set de una propiedad, o dentro de la implementación de un método de automatización OLE, el control debe llamar a COleControl::ThrowError, que indica al usuario de control que se ha producido un error. Si el error se produce en cualquier otro momento, el control debe llamar a COleControl::FireError, que desencadena un evento error de existencias.

Para indicar el tipo de error que se ha producido, el control debe pasar un código de error a ThrowError o FireError. Un código de error es un código de estado OLE, que tiene un valor de 32 bits. Cuando sea posible, elija un código de error del conjunto estándar de códigos definidos en OLECTL. Archivo de encabezado H. En la tabla siguiente se resumen estos códigos.

Códigos de error del control ActiveX

Error Descripción
CTL_E_ILLEGALFUNCTIONCALL Llamada a función no válida
CTL_E_OVERFLOW Desbordamiento
CTL_E_OUTOFMEMORY No hay memoria suficiente
CTL_E_DIVISIONBYZERO División por cero
CTL_E_OUTOFSTRINGSPACE Espacio fuera de cadena
CTL_E_OUTOFSTACKSPACE Espacio fuera de la pila
CTL_E_BADFILENAMEORNUMBER Nombre o número de archivo incorrecto
CTL_E_FILENOTFOUND Archivo no encontrado
CTL_E_BADFILEMODE Modo de archivo incorrecto
CTL_E_FILEALREADYOPEN El archivo ya está abierto
CTL_E_DEVICEIOERROR Error de E/S del dispositivo
CTL_E_FILEALREADYEXISTS El archivo ya existe
CTL_E_BADRECORDLENGTH Longitud incorrecta del registro
CTL_E_DISKFULL Disco lleno
CTL_E_BADRECORDNUMBER Número de registro incorrecto
CTL_E_BADFILENAME Nombre de archivo incorrecto
CTL_E_TOOMANYFILES Demasiados archivos
CTL_E_DEVICEUNAVAILABLE Dispositivo no disponible
CTL_E_PERMISSIONDENIED Permiso denegado
CTL_E_DISKNOTREADY Disco no listo
CTL_E_PATHFILEACCESSERROR Error de acceso a archivos o ruta de acceso
CTL_E_PATHNOTFOUND No se encuentra la ruta de acceso
CTL_E_INVALIDPATTERNSTRING Cadena de patrón no válida
CTL_E_INVALIDUSEOFNULL Uso no válido de NULL
CTL_E_INVALIDFILEFORMAT Formato de archivo no válido
CTL_E_INVALIDPROPERTYVALUE Valor de propiedad no válido
CTL_E_INVALIDPROPERTYARRAYINDEX Índice de matriz de propiedades no válido
CTL_E_SETNOTSUPPORTEDATRUNTIME No se admite en tiempo de ejecución
CTL_E_SETNOTSUPPORTED No se admite (propiedad de solo lectura)
CTL_E_NEEDPROPERTYARRAYINDEX Necesidad del índice de matriz de propiedades
CTL_E_SETNOTPERMITTED No se permite establecer
CTL_E_GETNOTSUPPORTEDATRUNTIME No se admite en tiempo de ejecución
CTL_E_GETNOTSUPPORTED No se admite Get (propiedad de solo escritura)
CTL_E_PROPERTYNOTFOUND No se encontró la propiedad
CTL_E_INVALIDCLIPBOARDFORMAT Formato de Portapapeles no válido
CTL_E_INVALIDPICTURE Imagen no válida
CTL_E_PRINTERERROR Error de impresora
CTL_E_CANTSAVEFILETOTEMP No se puede guardar el archivo en TEMP
CTL_E_SEARCHTEXTNOTFOUND Texto de búsqueda no encontrado
CTL_E_REPLACEMENTSTOOLONG Los reemplazos son demasiado largos

Si es necesario, use la macro CUSTOM_CTL_SCODE para definir un código de error personalizado para una condición que no esté cubierta por uno de los códigos estándar. El parámetro de esta macro debe ser un entero entre 1000 y 32767, ambos incluidos. Por ejemplo:

#define MYCTL_E_SPECIALERROR CUSTOM_CTL_SCODE(1000)

Si va a crear un control ActiveX para reemplazar un control VBX existente, defina los códigos de error del control ActiveX con los mismos valores numéricos que usa el control VBX para asegurarse de que los códigos de error son compatibles.

Control de claves especiales en el control

En algunos casos, es posible que desee controlar determinadas combinaciones de pulsaciones de teclas de una manera especial; Por ejemplo, inserte una nueva línea cuando se presione la tecla ENTRAR en un control de cuadro de texto de varias líneas o mueva entre un grupo de controles de edición cuando se presiona un identificador de tecla direccional.

Si la clase base del control ActiveX es COleControl, puede invalidar CWnd::P reTranslateMessage para controlar los mensajes antes de que el contenedor los procese. Al usar esta técnica, siempre devuelve TRUE si controla el mensaje en la invalidación de PreTranslateMessage.

En el ejemplo de código siguiente se muestra una manera posible de controlar los mensajes relacionados con las claves direccionales.

BOOL CMyAxUICtrl::PreTranslateMessage(MSG* pMsg)
{
   BOOL bHandleNow = FALSE;

   switch (pMsg->message)
   {
   case WM_KEYDOWN:
      switch (pMsg->wParam)
      {
      case VK_UP:
      case VK_DOWN:
      case VK_LEFT:
      case VK_RIGHT:
         bHandleNow = TRUE;
         break;
      }
      if (bHandleNow)
      {
         OnKeyDown((UINT)pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam));
      }
      break;
   }
   return bHandleNow;
}

Para obtener más información sobre el control de interfaces de teclado para un control ActiveX, consulte la documentación del SDK de ActiveX.

Acceso a controles de diálogo que son invisibles en tiempo de ejecución

Puede crear controles de diálogo que no tengan ninguna interfaz de usuario y que no sean invisibles en tiempo de ejecución. Si agrega un control ActiveX en tiempo de ejecución invisible a un cuadro de diálogo y usa CWnd::GetDlgItem para acceder al control, el control no funcionará correctamente. En su lugar, debe usar una de las técnicas siguientes para obtener un objeto que represente el control :

  • Con el Asistente para agregar variables miembro, seleccione Variable de control y, a continuación, seleccione el identificador del control. Escriba un nombre de variable miembro y seleccione la clase contenedora del control como Tipo de control.

    -o-

  • Declare una variable local y una subclase como elemento de diálogo. Inserte código similar al siguiente (CMyCtrl es la clase contenedora, IDC_MYCTRL1 es el identificador del control):

    CCirc myCirc;
    myCirc.SubclassDlgItem(IDC_CIRCCTRL2, this);
    // ... use myCirc ...
    myCirc.UnsubclassWindow();
    

Consulte también

Controles ActiveX de MFC