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 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
Cargue el proyecto del control.
En la Vista de clases, expanda el nodo biblioteca del control.
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.
En el menú contextual, haga clic en Agregar y, a continuación, haga clic en Agregar propiedad.
En el cuadro Nombre de propiedad , escriba
Array.En el cuadro Tipo de propiedad , seleccione
short.En Tipo de implementación , haga clic en Obtener o establecer métodos.
En los cuadros Obtener función y Establecer función , escriba nombres únicos para las funciones Get y Set o acepte los nombres predeterminados.
Agregue un parámetro, denominado fila (tipo short), mediante los controles Nombre de parámetro y Tipo de parámetro .
Agregue un segundo parámetro denominado column (type short).
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 (
CMyCtrles la clase contenedora, IDC_MYCTRL1 es el identificador del control):CCirc myCirc; myCirc.SubclassDlgItem(IDC_CIRCCTRL2, this); // ... use myCirc ... myCirc.UnsubclassWindow();