Menú
Está libre
registro
hogar  /  Educación/ No se puede crear un objeto mediante el mensaje cdo del contenedor activex. Crear contenedores para controles ActiveX

No se puede crear un objeto mediante el mensaje cdo de activex del contenedor. Crear contenedores para controles ActiveX


No se recomienda editar manualmente el registro para eliminar las claves inválidas Error 800A01AD a menos que sea un técnico de mantenimiento de PC. Los errores cometidos al editar el registro pueden hacer que su PC no funcione y causar daños irreparables a su sistema operativo... De hecho, ¡incluso una sola coma en el lugar equivocado puede evitar que su computadora se inicie!

Debido a este riesgo, recomendamos ampliamente la utilización de un liberador de registro confiable como WinThruster [download] (Desarrollado por Microsoft Gold Certified Partner) para analizar y reparar cualquier problema relacionado con el registro de Error 800A01AD. Con un limpiador de registro [Descarga], puede automatizar el proceso de búsqueda de entradas de registro no válidas, referencias a archivos faltantes (por ejemplo, causando el error%% error_name %%) y enlaces rotos dentro del registro. Antes de cada escaneo, Copia de respaldo que le permite deshacer cualquier cambio con un clic y lo protege de posibles daños a su computadora. La mejor parte es que corregir errores de registro [Descarga] puede mejorar drásticamente la velocidad y el rendimiento del sistema.


Una advertencia: Si no eres usuario experimentado PC, NO recomendamos editar el registro de Windows manualmente. El uso incorrecto del Editor del Registro puede ocasionar problemas graves y requerir reinstalar Windows... No garantizamos que los problemas resultantes del uso inadecuado del Editor del Registro puedan solucionarse. El uso del Editor del Registro es bajo su propio riesgo.

Antes de restaurar manualmente registro de windows Debe crear una copia de seguridad exportando una parte del registro relacionado con el Error 800A01AD (por ejemplo: ActiveX):

  1. Haga clic en el botón Empezar.
  2. Ingresar " mando"v barra de búsqueda ... NO PULSAR TODAVÍA INGRESAR!
  3. Sosteniendo las llaves CTRL-Mayús en el teclado, presione INGRESAR.
  4. Se mostrará un cuadro de diálogo para acceder.
  5. Haga clic en .
  6. El cuadro negro se abre con un cursor parpadeante.
  7. Ingresar " regedit"y presione INGRESAR.
  8. En el Editor del Registro, seleccione la clave relacionada con Error 800A01AD (por ejemplo: ActiveX) de la que desea hacer una copia de seguridad.
  9. En el menú Expediente escoger Exportar.
  10. En la lista Salvar a seleccione la carpeta donde quiere guardar la clave de la copia de seguridad ActiveX.
  11. En campo Nombre del archivo introduzca un nombre para su archivo de copia de seguridad, como "Copia de seguridad ActiveX".
  12. Asegúrate en la caja Rango de exportación valor seleccionado Rama seleccionada.
  13. Haga clic en Ahorrar.
  14. El archivo se guardará con la extensión .reg.
  15. Ahora tiene una copia de seguridad de su entrada de registro relacionada con ActiveX.

Los siguientes pasos para editar manualmente el registro no se describirán en este artículo, ya que lo más probable es que puedan dañar su sistema. Si desea obtener más información sobre cómo editar manualmente el registro, consulte los enlaces a continuación.

Todos los sistemas relacionados estaban disponibles. Este error tiene las siguientes causas y soluciones:

    La clase no está registrada. Por ejemplo, no se menciona una clase en el registro del sistema, o se menciona una clase pero apunta a un archivo Tipo incorrecto o un archivo que no se puede encontrar. Ejecute la aplicación de objeto si es posible. Si la información del registro es incorrecta o no está actualizada, la aplicación comprobará el registro y corregirá la información. Si al iniciar la aplicación no se soluciona el problema, vuelva a ejecutar el instalador de la aplicación;

    No puedo usar DLL requerido por el objeto porque no se encontró o se encontró dañado. Asegúrese de que todas las DLL asociadas estén disponibles. Por ejemplo, un objeto de acceso a datos (DAO) requiere compatibilidad con DLL que difiere de una plataforma a otra. Si esta es la causa del error, debe volver a ejecutar el instalador para dicho objeto;

    El objeto está disponible en la computadora, pero tiene licencia y no puede verificar la disponibilidad de la licencia requerida para crear una instancia del objeto.

    Algunos objetos solo se pueden instanciar después de que el componente haya encontrado clave de licencia confirmando el registro de este objeto para instanciar en este computador... Si hay una referencia al objeto en la configuración correcta o la clave correcta se proporciona automáticamente.

    Si el intento de instanciar es el resultado de una llamada de función Crear objeto o GetObject, el objeto debe encontrar la clave. En este caso, puede buscar en el registro del sistema o buscar un archivo especial que crea durante la instalación (por ejemplo, con la extensión .LIC). Si no se puede encontrar la clave, no se puede crear una instancia del objeto. Si el usuario final configuró incorrectamente la aplicación del objeto, se eliminará de forma irreversible archivo deseado o cambió el registro del sistema, el objeto no puede encontrar su clave. Si no se puede encontrar la clave, no se puede crear una instancia del objeto. En este caso, la creación de instancias puede funcionar en el sistema del desarrollador, pero no en el sistema del usuario. El usuario debe reinstalar el objeto con licencia;

    Estás intentando usar la función getter GetObject para obtener una referencia a una clase generada con Visual Basic. GetObject No se puede usar para obtener una referencia a una clase generada con Visual Basic.

    El acceso al objeto está explícitamente denegado. Por ejemplo, está intentando acceder a un objeto de datos que está actualmente en uso y bloqueado para evitar interbloqueos. En este caso, es posible que pueda acceder al objeto en otro momento.

Para obtener más información, seleccione el elemento sobre el que está preguntando y presione F1 (Windows) o HELP (Macintosh).

Alexander Kostarev
programador del departamento tecnológico del R-Style Software Lab.

La creación de controles ActiveX está ampliamente cubierta en la literatura. Sin embargo, analiza las técnicas para escribir contenedores ActiveX con mucha menos frecuencia, principalmente solo en el marco de su interacción con objetos ActiveX. Aún menos publicaciones se dedican a los procedimientos de desarrollo de contenedores que soportan su propia interfaz de programación (API), lo que permite trabajar con ellos y los objetos que contienen desde otras aplicaciones o lenguajes de scripting. Ejemplos de dichos contenedores son productos de software como Microsoft Visual Basic, Borland Delphi, etc.

Sin embargo, sobre la base de los contenedores existentes, no es posible resolver una serie de problemas; esto requiere contenedores de controles especializados. Uno de esos desafíos es crear una aplicación extensible que automatice operaciones comunes que no podrían haberse anticipado durante el desarrollo. La automatización requiere que una aplicación acceda externamente a sus objetos y se integre con una herramienta de desarrollo de extensiones. Edificio interfaz de usuario se basa en la mayoría de los casos en la inserción de varios controles en un formulario: un contenedor de objetos ActiveX. Entonces la creacion herramienta requiere la creación de un contenedor ActiveX.

Consideraremos algunos de los problemas que surgen durante la implementación de la arquitectura de componentes en el kit de herramientas, así como los métodos para su solución. Esto puede ser de interés tanto para los desarrolladores de contenedores de control como para los desarrolladores de objetos ActiveX, ya que este artículo demuestra el propósito y las formas de utilizar los diversos métodos de las interfaces de control del lado del contenedor estándar.

Las soluciones propuestas se basan en la experiencia de desarrollar el complejo de herramientas RS-Forms, un nuevo producto de software por R-Style Software Lab. RS-Forms incluye una herramienta de desarrollo interfaz grafica usuario en Plataforma Windows, un entorno de ejecución para programas creados con los lenguajes RSL *, C y C ++, así como un sistema para depurar programas RSL.

* Object RSL es un lenguaje de programación de alto nivel creado por R-Style Software Lab. Consulte http://www.softlab.ru/products/rsl/ para obtener más detalles. - Aprox. ed.

En el marco del proyecto, se implementó la primera versión del diseñador de formularios (Fig.1), que le permite crear formularios, incrustar controles estándar y objetos ActiveX arbitrarios en ellos, guardar formularios listos para usar en el almacenamiento de forma permanente. medio de almacenamiento y cárguelos desde él. Con la ayuda del diseñador, puede ver las propiedades, métodos y eventos de cualquier control incrustado en el formulario, cambiar los valores de las propiedades.

El diseñador se basa en un contenedor de control ActiveX (formulario) que proporciona la funcionalidad descrita anteriormente. Además, el formulario admite varias opciones para personalizar su presentación, incluido el porcentaje de elementos incrustados a los bordes, el control de la secuencia de su recorrido por el teclado, su visibilidad, tipografía y tamaño de fuente, color de fondo, texto, etc.

Además de desarrollar una interfaz gráfica de usuario, el diseñador tiene un mecanismo para la generación automática de código en lenguajes C ++ y RSL. Es importante tener en cuenta que todas las operaciones realizadas en el formulario en el diseñador también están disponibles en el modo de ejecución desde el código del programa.

Arroz. 1. Diseñador de formularios.

Las formas gráficas creadas en el diseñador se pueden utilizar en cualquier aplicación C / C ++, así como desde cualquier lenguaje de programación, como Visual Basic o RSL. Cuando se utilizan formularios en aplicaciones C ++ desarrolladas con la biblioteca MFC, el diseñador se puede utilizar como editor de recursos de diálogo.

Ahora analicemos el concepto de creación de un contenedor y cómo trabajar con controles ActiveX.

Funciones básicas del contenedor

Cualquier contenedor de controles debe tener una funcionalidad que le permita crear objetos ActiveX, asegurar su correcto funcionamiento y eliminarlos de memoria de acceso aleatorio, así como guardar elementos en el almacenamiento de objetos en un medio de almacenamiento permanente y cargarlos desde él *. El contenedor incluye una serie de componentes (Fig. 2) que proporcionan la funcionalidad estándar (de acuerdo con la tecnología Microsoft ActiveX) necesaria para el correcto funcionamiento de los controles.

* Los problemas generales de construcción de contenedores y servidores de objetos COM se consideran en el libro de D. Chappel "Tecnologías ActiveX y OLE" - M.: "Edición rusa", 1997.

El contenedor mantiene una colección (por ejemplo, una lista) de objetos de comunicación con controles ActiveX: un objeto de comunicación para cada control. Además, un contenedor programable debe proporcionar un mecanismo estándar para manipular los elementos de esta colección.

El sitio de control es responsable de la correcta interacción del elemento correspondiente con el contenedor. Cada objeto de comunicación contiene un subobjeto que amplía el control con los conjuntos de propiedades, métodos y eventos específicos del contenedor. Este subobjeto se denomina control extendido. Ejemplos de propiedades extendidas son Nombre, ubicación del contenedor (Ancho, Izquierda), etc. Estos conjuntos son propiedades del contenedor y no de ningún control en particular, aunque así es como lo ve el usuario del sistema. Hay varias opciones para implementar un control extendido. Por ejemplo, puede representar un subobjeto de un objeto de comunicación (ver Figura 2) o un objeto COM real que agrega el control original. Cada una de las opciones tiene sus propias ventajas y desventajas. En este artículo, solo consideramos el primer método.

Cada control extendido contiene como subobjeto un objeto receptor de eventos de su control asociado (Figura 2). Sus tareas incluyen la identificación primaria de los eventos recibidos (ya sea que se requiera o no el manejo de eventos del usuario) y, si es necesario, transferirlos a su objeto propietario (control extendido), que proporciona el enrutamiento de eventos a través de la jerarquía de objetos contenedores.

Script de creación de control

La inyección de un control en un contenedor consta de tres fases: crear un objeto ActiveX, inicializarlo y activarlo.

Los controles se crean en el espacio de direcciones del contenedor utilizando funciones COM estándar como CoCreateInstance. La función global correspondiente se pasa como identificador del control de función. identificador único clase CLSID. Cabe señalar que el contenedor debe admitir varias opciones para identificar objetos COM en el sistema, como el identificador de programa ProgID, un identificador de clase único en forma de cadena, etc.

El propósito principal de la fase de inicialización es pasar un puntero a la interfaz IOleClientSite del objeto de comunicación al control a través de la función IOleObject :: SetClientSite y llamar a la función IPersistStreamInit :: InitNew o IPersistStreamInit :: Load (dependiendo de si el objeto es cargado desde el almacenamiento o no). Pasar un puntero a la interfaz IOleClientSite a un objeto puede ocurrir antes de la carga / inicialización o después; el momento de la transmisión está determinado por la presencia del indicador OLEMISC_SETCLIENTSITEFIRST (IOleObject :: GetMiscStatus). Esto es significativo, ya que el momento en que se pasa el puntero depende de en qué momento el control recibe las propiedades ambientales del contenedor. Si se ignora este signo, es posible que el funcionamiento posterior del objeto ActiveX sea incorrecto.

Luego, como parte de esta fase, debe realizar la inicialización inicial de las propiedades del control extendido que complementa el objeto ActiveX creado. Por ejemplo, debe establecer correctamente el nombre del objeto (inicializar la propiedad Name, que proporciona la identificación de los controles dentro del contenedor). Cualquier control que esté incrustado en un contenedor programable debe admitir esta propiedad, pero, no obstante, es una propiedad del contenedor. A menudo, de forma predeterminada, los objetos reciben el nombre corto de la clase a la que pertenecen (este nombre es devuelto por el método IOleObject :: GetUserType para el parámetro USERCLASSTYPE_SHORT), con un índice numérico agregado para asegurar que los nombres de los controles en los contenedores son únicos. Si lo consigues nombre especificado falla o si no satisface la lógica del contenedor, entonces puede establecer algún nombre predefinido con el índice apropiado.

La activación de un control implica una determinada secuencia de acciones. El primer paso es establecer una retroalimentación entre el objeto ActiveX y el objeto de comunicación en el contenedor (sitio de control). Para hacer esto, se llama al método IOleObject :: Advise, al que un puntero a interfaz estándar Objeto de comunicación IAdviseSink. A continuación, debe solicitar correctamente la interfaz de la familia IViewObject (de acuerdo con la especificación, un objeto ActiveX puede admitir las interfaces IViewObject, IViewObject2, IViewObjectEx, que están en la jerarquía de herencia) y establecer una retroalimentación para ello llamando al IViewObject: : Método SetAdvise con pasar un puntero a IAdviseSink. Además, debe indicarle al control el nombre de su contenedor (esto se implementa llamando al método IOleObject :: SetHostName), solicitar y guardar todas las interfaces necesarias para el funcionamiento correcto con el objeto ActiveX (al menos IOleInPlaceObject e IOleControl). Lo último que debe hacer para representar visualmente el control es llamar a la función IOleObject :: DoVerb * con el parámetro OLEIVERB_INPLACEACTIVATE.

* Implementación de ATL función especificada, entre otras cosas, es responsable de crear una ventana para controles ordinarios (en ventana).

Eliminar secuencia de comandos de control

Para eliminar un control incrustado en un contenedor de la memoria, debe excluir de la colección su objeto de control asociado y luego realizar dos operaciones secuenciales: romper retroalimentación y liberar punteros almacenados a las interfaces de objetos ActiveX.

Para romper los comentarios, primero debe informar al elemento eliminado sobre la necesidad de liberar (llamando al método IUnknown :: Release) los punteros a la interfaz IAdviseSink del objeto de conexión que contiene. Para hacer esto, se llaman los métodos IViewObject :: SetAdvise (pasando NULL como argumento) e IOleObject :: Unadvise, a los que debe proporcionar el identificador de enlace guardado en la etapa de activación. A continuación, debe activar el procedimiento para desinicializar el objeto ActiveX (llamando a la función IOleObject :: Close). En el siguiente paso, se le dice al control que libere el puntero a la interfaz IOleClientSite llamando a IOleObject :: SetClientSite con el parámetro NULL.

La fase de liberar los punteros almacenados a las interfaces del control es llamar secuencialmente al método Release para ellos. Tan pronto como se libere el último puntero, el objeto (de acuerdo con la tecnología COM) se eliminará de la RAM.

Guardar y cargar script

Guardar un objeto contenedor en almacenamiento, independientemente del tipo de este último, es guardar las propiedades del contenedor (por ejemplo, propiedades del entorno) y la colección de controles incrustados, es decir, identificadores y propiedades (incluidos los extendidos) de cada objeto perteneciente a la colección. El identificador único global de la clase CLSID se puede utilizar como identificador para un control. Esto permitirá en la etapa de inicialización crear el objeto ActiveX requerido y cargarlo con los datos contenidos en el almacenamiento después del identificador especificado. Para guardar las propiedades del control, por ejemplo en una secuencia, se llama al método Save de la interfaz de objeto ActiveX estándar IPersistStreamInit. Se llama al método Load de la misma interfaz para cargar.

Este procedimiento de guardado garantiza que el objeto contenedor se restaure posteriormente del almacenamiento. El método descrito funciona bien, siempre que desde el momento del guardado hasta el momento de la carga, no haya habido ningún cambio de versión o eliminación de ningún control del sistema. Estas situaciones a menudo surgen al transferir un almacén de datos de una computadora a otra, donde los objetos ActiveX almacenados no se han instalado o registrado. En este caso, cargar el objeto contenedor desde el almacenamiento dará lugar a la finalización fatal del programa o provocará un error al cargar todo el contenedor como un todo. Para evitar errores, es necesario establecer claramente el límite entre los datos de varios controles, registrando en el almacenamiento después del identificador de objeto el tamaño de la información almacenada por él. Esto permitirá en la etapa de carga posicionar con precisión al comienzo de los datos de cada objeto ActiveX, así como omitir controles no registrados en el sistema, pero cargar el objeto contenedor como un todo.

Interfaces de colección de objetos ActiveX

Según el estándar, el contenedor de control debe proporcionar interoperabilidad para los objetos ActiveX integrados. Para hacer esto, debe admitir la interfaz IOleContainer, que le permite enumerar todos los controles insertados en ella. Si tiene un control extendido, la enumeración debe pasar por sus interfaces IUnknown y no por las interfaces del objeto base.

Se utiliza una interfaz de colección de objetos estándar para proporcionar acceso a la colección a los clientes de automatización. La colección estándar incluye los métodos Add, Remove, Clear, Item y las propiedades _NewEnum y Count, que proporcionan una iteración exhaustiva de elementos. Por ejemplo, Visual Basic para cada construcción usa la propiedad _NewEnum para enumerar elementos, mientras que la construcción for next usa la propiedad Count y el método Item. En Object RSL, la propiedad _NewEnum se usa cuando se hace referencia a método estándar Objeto ActiveX CreateEnum. Esto se ilustra, por ejemplo, por un programa RSL que imprime utilizando el método especificado los nombres de los archivos abiertos en Aplicación de Microsoft Excel (su texto se da a continuación).

import rslx; ob = ActiveX ("Excel.Application", nulo, verdadero); en = ob.Workbooks.CreateEnum; while (en.next) println (en.item.Name) end;

Estos escenarios le permiten desarrollar funciones para agregar un control a un contenedor y eliminarlo. En la mayoría de los casos, la función agregar crea un objeto de comunicación con el control (almacenando todos los punteros a las interfaces de objeto ActiveX necesarias para la operación) y llama a una función similar en él. Este último, a su vez, implementa el escenario de implementación descrito anteriormente (posiblemente sin una fase de activación). Si la formación del objeto ActiveX en RAM fue exitosa, entonces la función de contenedor agrega el objeto de comunicación correspondiente a la colección. A menudo, debido a su similitud, se combinan los procedimientos para incrustar y cargar un control desde el repositorio.

* * *

Hemos cubierto aquí los principales problemas relacionados con la construcción de contenedores de control: incrustación, visualización visual, guardar y cargar un objeto ActiveX, así como su eliminación correcta de la RAM. Sin embargo, en el proceso de creación de un entorno de desarrollo gráfico, necesitábamos implementar varios contenedores que se diferenciaran entre sí en las interfaces de automatización proporcionadas, subconjuntos de objetos ActiveX permitidos para la inyección, conjuntos de propiedades, métodos y eventos de controles extendidos, etc. . Para ello, se propuso un modelo que le permite crear varios elementos contenedores y se integra bien con la biblioteca ATL. La independencia de interfaces específicas se logra mediante el uso de clases de plantilla, cuyos parámetros son estas interfaces.

* Por ejemplo, el control Tab es un contenedor para páginas de propiedades, que son contenedores de uso general.

Este modelo le permite crear rápidamente variantes básicas de varios objetos ActiveX, que son inherentes a la "lógica del contenedor". Además, la infraestructura implementada le permite crear contenedores que no son controles. Dicho recipiente se puede colocar como ventanas ventanas en cualquier parte de la aplicación desarrollada y luego, enviando los mensajes apropiados, inyecte varios controles en ella.

Como resultado, obtuvimos una arquitectura bastante flexible para construir contenedores, con la que puede crear un asistente que amplíe funcionalidad Entorno de Microsoft Visual Studio antes del mecanismo de generación del esqueleto del contenedor.