Maison / l'Internet / Impossible de créer un objet par conteneur ActiveX. Créez des conteneurs pour les contrôles ActiveX. Fonctions de base du conteneur

Impossible de créer un objet par conteneur ActiveX. Créez des conteneurs pour les contrôles ActiveX. Fonctions de base du conteneur

Les systèmes et étaient disponibles tous liés. Cette erreur a les causes et solutions suivantes :

    La classe n'est pas enregistrée. Par exemple, il n'y a aucune mention d'une classe dans le registre système, ou une classe est mentionnée mais pointe vers un fichier du mauvais type, ou vers un fichier introuvable. Si possible, démarrez l'application objet. Si les informations du registre sont incorrectes ou obsolètes, l'application vérifiera le registre et corrigera les informations. Si l'exécution de l'application ne résout pas le problème, relancez le programme d'installation de l'application ;

    Ne peut pas utiliser DLL Requis par l'objet car il n'a pas été trouvé ou a été trouvé corrompu. Assurez-vous que toutes les DLL associées sont disponibles. Par exemple, un objet d'accès aux données (DAO) nécessite la prise en charge de DLL qui varient selon la plate-forme. S'il s'agit de la cause de l'erreur, vous devez relancer le programme d'installation de cet élément ;

    L'objet est disponible sur la machine, mais est sous licence, et il ne peut pas vérifier si la licence requise pour instancier l'objet est disponible.

    Certains objets ne peuvent être instanciés qu'après que le composant a trouvé clé de licence A qui confirme que cet objet est enregistré pour l'instanciation sur cet ordinateur. S'il existe une référence à un objet dans une clé correctement définie ou correcte, celle-ci est fournie automatiquement.

    Si la tentative de création d'une instance est le résultat d'un appel de fonction CréerObjet ou ObtenirObjet, l'objet doit trouver la clé. Dans ce cas, il peut effectuer une recherche dans le registre système ou rechercher fichier spécial, qu'il crée lors de l'installation (par exemple, avec une extension .LIC). Si la clé est introuvable, l'objet ne peut pas être instancié. Si l'utilisateur final a mal configuré l'application d'objet, supprimé définitivement fichier souhaité ou modifié le registre système, l'objet ne pourra pas trouver sa clé. Si la clé est introuvable, l'objet ne peut pas être instancié. Dans ce cas, l'instanciation peut fonctionner sur le système du développeur, mais pas sur le système de l'utilisateur. L'utilisateur doit réinstaller l'élément sous licence ;

    Vous essayez d'utiliser la fonction get object ObtenirObjet pour obtenir une référence à une classe créée avec Visual Basic. ObtenirObjet ne peut pas être utilisé pour obtenir une référence à une classe créée avec Visual Basic ;

    L'accès à l'objet est explicitement refusé. Par exemple, vous essayez d'accéder à un objet de données actuellement utilisé et verrouillé pour éviter un blocage. Dans ce cas, vous pourrez peut-être accéder à l'objet à un autre moment.

Pour obtenir Informations Complémentaires sélectionnez l'élément sur lequel vous avez une question et appuyez sur F1 (Windows) ou AIDE (Macintosh).

Alexandre Kostarev
Programmeur du département technologique R-Style Software Lab.

La création de contrôles ActiveX est largement couverte dans la littérature spécialisée. Cependant, il traite des techniques d'écriture de conteneurs ActiveX beaucoup moins fréquemment, principalement uniquement dans le cadre de leur interaction avec les objets ActiveX. Encore moins de publications sont consacrées aux procédures de développement de conteneurs prenant en charge leur propre interface de programmation (API), ce qui permet de travailler avec eux et les objets qu'ils contiennent à partir d'autres applications ou langages de script. Des exemples de tels conteneurs sont des produits logiciels tels que Microsoft Visual Basic, Borland Delphi, etc.

Néanmoins, un certain nombre de tâches ne peuvent pas être résolues sur la base des conteneurs existants - cela nécessite des conteneurs de contrôles spécialisés. L'un de ces défis consiste à créer une application extensible qui vous permet d'automatiser des opérations courantes qui n'auraient pas pu être prévues lors du développement. L'automatisation nécessite que l'application expose ses objets en externe et soit intégrée à l'outil de développement d'extension. La construction d'une interface utilisateur est basée dans la plupart des cas sur l'insertion de divers contrôles dans un formulaire - un conteneur d'objets ActiveX. Ainsi la création outil nécessite la création d'un conteneur ActiveX.

Nous examinerons certains problèmes qui surviennent lors de l'introduction d'une architecture de composants dans un complexe d'outils, ainsi que des méthodes pour les résoudre. Cela peut intéresser à la fois les développeurs de conteneurs de contrôle et les développeurs d'objets ActiveX eux-mêmes, car cet article montre le but et les utilisations de diverses méthodes interfaces standard pour les contrôles côté conteneur.

Les solutions proposées sont basées sur l'expérience du développement du complexe d'outils RS-Forms - un nouveau produit logiciel Laboratoire de logiciels R-Style. RS-Forms inclut un outil de développement interface graphique utilisateur sur Plate-forme Windows, un environnement d'exécution pour les programmes créés avec les langages RSL*, C et C++, ainsi qu'un système de débogage pour les programmes RSL.

*Object RSL - langage de programmation haut niveau, créé par R-Style Software Lab. Voir http://www.softlab.ru/products/rsl/ pour plus de détails. - Noter. éd.

Dans le cadre du projet, la première version du concepteur de formulaires a été implémentée (Fig. 1), qui vous permet de créer des formulaires, d'y intégrer à la fois des contrôles standard et des objets ActiveX arbitraires, d'enregistrer formulaires prêts à l'emploi stockées sur un support de stockage permanent et chargez-les à partir de celui-ci. Avec l'aide du concepteur, vous pouvez afficher les propriétés, les méthodes et les événements de tout élément de contrôle intégré dans le formulaire, modifier les valeurs des propriétés.

Le concepteur est basé sur un conteneur de contrôle ActiveX (formulaire) qui fournit la fonctionnalité décrite ci-dessus. De plus, le formulaire prend en charge diverses possibilités paramètres pour sa présentation, y compris le pourcentage de liaison des éléments intégrés aux bordures, le contrôle de la séquence de leur contournement par le clavier, leur visibilité, la police et la taille de la police, la couleur de fond, le texte, etc.

En plus de développer une interface utilisateur graphique, le concepteur dispose d'un mécanisme pour générer automatiquement du code en C++ et RSL. Il est important de noter que toutes les opérations effectuées sur le formulaire dans le concepteur sont également disponibles en mode exécution à partir du code du programme.

Riz. 1. Concepteur de formulaires.

Créé dans le designer formes graphiques peut être utilisé dans n'importe quelle application C/C++, ainsi qu'à partir de n'importe quel langage de script tel que Visual Basic ou RSL. Lors de l'utilisation de formulaires dans des applications C++ développées avec la bibliothèque MFC, le concepteur peut être utilisé comme éditeur de ressources de boîte de dialogue.

Abordons maintenant le concept de création d'un conteneur et les principes d'utilisation des contrôles ActiveX.

Fonctions de base du conteneur

Tout conteneur de contrôles doit avoir une fonctionnalité qui vous permettrait de créer des objets ActiveX, d'assurer leur bon fonctionnement, de les supprimer de mémoire vive, ainsi que stocker des éléments dans le magasin d'objets sur un support de stockage permanent et les charger à partir de celui-ci*. Le conteneur comprend un certain nombre de composants (Fig. 2) qui fournissent la norme (selon Technologie Microsoft ActiveX) nécessaire au bon fonctionnement des contrôles.

* Les problèmes généraux de construction de conteneurs et de serveurs d'objets COM sont abordés dans le livre de D. Chappel "ActiveX and OLE Technologies" - M.: "Russian Edition", 1997.

Le conteneur gère une collection (par exemple, une liste) d'objets de connexion avec des contrôles ActiveX, un objet de connexion par contrôle. De plus, un conteneur programmable doit fournir un mécanisme standard pour manipuler les éléments de cette collection.

L'objet du site de contrôle est responsable de la bonne interaction de l'élément correspondant avec le conteneur. Chaque objet de connexion contient un sous-objet qui étend le contrôle avec un ensemble de propriétés, de méthodes et d'événements spécifiques au conteneur. Un tel sous-objet est appelé un contrôle étendu. Un exemple de propriétés étendues est un nom (Name), un emplacement dans un conteneur (Width, Left), etc. Les ensembles spécifiés sont des propriétés du conteneur, et non d'un contrôle individuel, bien que ce soit à cela qu'il ressemble pour l'utilisateur du système. Il existe plusieurs options pour mettre en œuvre un contrôle étendu. Par exemple, il peut s'agir d'un sous-objet de l'objet de communication (voir Figure 2) ou d'un véritable objet COM qui agrège le contrôle d'origine. Chacune des options a ses propres avantages et inconvénients. Dans cet article, nous considérons uniquement la première méthode.

Chaque contrôle étendu contient en tant que sous-objet un objet récepteur d'événements de son contrôle associé (Figure 2). Ses tâches incluent l'identification principale des événements reçus (que le traitement des événements personnalisés soit requis ou non) et, si nécessaire, leur transmission à son objet propriétaire (contrôle étendu), qui assure le routage des événements le long de la hiérarchie des objets conteneurs.

Script de création de contrôle

L'injection d'un contrôle dans un conteneur comporte trois phases : créer un objet ActiveX, l'initialiser et l'activer.

Les contrôles sont créés dans l'espace d'adressage du conteneur à l'aide de fonctions COM standard telles que CoCreateInstance. Le CLSID globalement unique correspondant est transmis à la fonction en tant qu'ID du contrôle. Il convient de noter que le conteneur doit prendre en charge diverses options d'identification des objets COM dans le système - telles que l'identifiant de programme ProgID, un identifiant de classe unique sous la forme d'une chaîne, etc.

Le but principal de la phase d'initialisation est de passer un pointeur vers l'interface IOleClientSite de l'objet de connexion au contrôle via la fonction IOleObject::SetClientSite et d'appeler la fonction IPersistStreamInit::InitNew ou IPersistStreamInit::Load (selon que l'objet est chargé ou non du stockage). Le passage d'un objet à un pointeur vers l'interface IOleClientSite peut se produire avant le chargement/l'initialisation ou après ; le moment de transmission est déterminé par la présence de l'attribut OLEMISC_SETCLIENTSITEFIRST (IOleObject::GetMiscStatus). Ceci est important, car le passage du pointeur détermine à quel moment le contrôle recevra les valeurs des propriétés ambiantes du conteneur. Si cette fonctionnalité est ignorée, le fonctionnement ultérieur de l'objet ActiveX peut être incorrect.

Ensuite, dans le cadre de la phase considérée, vous devez procéder à la première initialisation des propriétés du contrôle étendu qui complète l'objet ActiveX créé. Par exemple, vous devez définir correctement le nom de l'objet (initialiser la propriété Name, qui fournit l'identification des contrôles dans le conteneur). Tout contrôle intégré dans un conteneur programmable doit prendre en charge cette propriété, mais il s'agit toujours d'une propriété du conteneur. Souvent, par défaut, les objets reçoivent le nom abrégé de la classe à laquelle ils appartiennent (ce nom est renvoyé par la méthode IOleObject::GetUserType pour le paramètre USERCLASSTYPE_SHORT), avec un index numérique ajouté pour garantir que les noms de contrôle du conteneur sont uniques . Si recevoir nom spécifiééchoue, ou s'il ne satisfait pas la logique du conteneur, un nom prédéfini peut être donné avec l'index approprié.

L'activation d'un contrôle implique une certaine séquence d'actions. La première étape consiste à établir un backlink d'objet ActiveX vers l'objet lien dans le conteneur (site de contrôle). Pour cela, la méthode IOleObject::Advise est appelée en passant en paramètre un pointeur vers l'interface standard de l'objet de connexion IAdviseSink. Ensuite, vous devez demander correctement l'interface de la famille IViewObject (selon la spécification, un objet ActiveX peut prendre en charge les interfaces IViewObject, IViewObject2, IViewObjectEx qui sont dans la hiérarchie d'héritage) et établir un retour pour celle-ci en appelant IViewObject :: Méthode SetAdvise passant un pointeur vers IAdviseSink. De plus, vous devez indiquer au contrôle le nom de son conteneur (ceci est implémenté en appelant la méthode IOleObject::SetHostName), demander et enregistrer toutes les interfaces nécessaires au bon fonctionnement de l'objet ActiveX (au moins IOleInPlaceObject et IOleControl). La dernière chose à faire pour restituer visuellement le contrôle consiste à appeler la fonction IOleObject::DoVerb* avec le paramètre OLEIVERB_INPLACEACTIVATE.

*Dans l'implémentation ATL, cette fonction est responsable, entre autres, de la création d'une fenêtre pour les contrôles normaux (fenêtrés).

Contrôler le script de suppression

Pour supprimer de la mémoire un contrôle embarqué dans un conteneur, il faut exclure de la collection l'objet d'association avec le contrôle qui lui correspond, puis effectuer successivement deux opérations : break retour d'information et libérer des pointeurs stockés vers des interfaces de l'objet ActiveX.

Pour rompre les backlinks, vous devez d'abord informer l'élément à supprimer de la nécessité de libérer (en appelant la méthode IUnknown::Release) les pointeurs qu'il contient vers l'interface IAdviseSink de l'objet lien. Pour cela, les méthodes IViewObject::SetAdvise sont appelées (en passant NULL en argument) et IOleObject::Unadvise, qui doit être muni de l'identifiant de relation enregistré lors de la phase d'activation. Il faut ensuite activer la procédure de désinitialisation de l'objet ActiveX (en appelant la fonction IOleObject::Close). L'étape suivante consiste à indiquer au contrôle de libérer le pointeur d'interface IOleClientSite en appelant IOleObject::SetClientSite avec un paramètre NULL.

La phase de libération des pointeurs stockés vers les interfaces de contrôle consiste à appeler la méthode Release sur ceux-ci un par un. Dès que le dernier pointeur sera libéré, l'objet (conformément à la technologie COM) sera supprimé de la RAM.

Enregistrer et charger le script

L'enregistrement d'un objet conteneur dans le stockage, quel que soit le type de ce dernier, consiste à enregistrer les propriétés du conteneur (telles que les propriétés d'environnement) et la collection de contrôles intégrés, c'est-à-dire les identifiants et les propriétés (y compris celles étendues) de chaque objet qui appartient à la collection. L'identifiant du contrôle peut être l'identifiant global unique de la classe CLSID. Cela permettra à l'étape d'initialisation de créer l'objet ActiveX requis et de le charger avec les données contenues dans le magasin après l'identifiant spécifié. Pour enregistrer les propriétés d'un contrôle, par exemple dans un flux, la méthode Save de l'interface d'objet ActiveX standard IPersistStreamInit est appelée. Pour charger, la méthode Load de la même interface est appelée.

Cette procédure de sauvegarde garantit que l'objet conteneur est ultérieurement restauré à partir du stockage. La méthode décrite fonctionne bien, à condition qu'aucun changement de version ou suppression de tout contrôle du système ne se produise entre le moment de l'enregistrement et le moment du chargement. De telles situations surviennent souvent lors de la migration d'un magasin de données d'un ordinateur à un autre où les contrôles ActiveX enregistrés n'ont pas été installés ou enregistrés. Dans ce cas, le chargement de l'objet conteneur à partir du stockage entraînera soit un arrêt fatal du programme, soit une erreur lors du chargement de l'ensemble du conteneur dans son ensemble. Pour éviter les erreurs, il est nécessaire d'établir clairement la frontière entre les données des différents contrôles en écrivant dans le stockage après l'identifiant de l'objet la taille des informations stockées par celui-ci. Cela permettra à la phase de chargement de se positionner avec précision au début des données de chaque objet ActiveX, ainsi que d'ignorer les contrôles qui ne sont pas enregistrés dans le système, mais chargent l'objet conteneur dans son ensemble.

Interfaces de collecte d'objets ActiveX

Selon la norme, le conteneur de contrôle doit fournir une interaction entre les objets ActiveX qui y sont intégrés. Pour ce faire, vous devez prendre en charge l'interface IOleContainer, qui vous permet d'énumérer tous les contrôles qui y sont insérés. S'il existe un contrôle étendu, l'énumération doit traverser ses interfaces IUnknown, et non les interfaces de l'objet sous-jacent.

Pour fournir l'accès à une collection aux clients d'automatisation, utilisez l'interface de collection d'objets standard. La collection standard comprend les méthodes Add, Remove, Clear, Item et les propriétés _NewEnum et Count, qui fournissent une itération complète des éléments. Par exemple, la construction Visual Basic de chaque construction utilise la propriété _NewEnum pour énumérer les éléments, tandis que la construction for next utilise la propriété Count et la méthode Item. Dans Object RSL, la propriété _NewEnum est utilisée lors de l'appel de la méthode CreateEnum de l'objet ActiveX standard. Ceci est illustré, par exemple, par un programme RSL qui imprime les noms des fichiers ouverts dans l'application en utilisant la méthode spécifiée. Microsoft Excel(son texte est donné ci-dessous).

importer rslx ; ob = ActiveX("Excel.Application", null, true); en = ob.Workbooks.CreateEnum; while (en.next) println(en.item.Name) end ;

Les scénarios ci-dessus vous permettent de développer des fonctions pour ajouter un contrôle à un conteneur et le supprimer de celui-ci. Dans la plupart des cas, la fonction add crée un objet d'association avec le contrôle (qui stocke tous les pointeurs vers les interfaces de l'objet ActiveX dont il a besoin pour fonctionner) et appelle une fonction similaire dessus. Ce dernier, à son tour, met en œuvre le scénario de mise en œuvre décrit ci-dessus (éventuellement sans la phase d'activation). Si la création de l'objet ActiveX dans la RAM a réussi, la fonction conteneur ajoute l'objet lien correspondant à la collection. Souvent, en raison de leur similitude, les procédures d'intégration et de chargement d'un contrôle depuis le magasin sont combinées.

* * *

Nous avons abordé ici les principaux problèmes liés à la construction de conteneurs de contrôle : injection, affichage visuel, sauvegarde et chargement d'un objet ActiveX, ainsi que sa suppression correcte de la RAM. Cependant, dans le processus de création d'un environnement de travail graphique, nous devions implémenter plusieurs conteneurs qui différaient les uns des autres dans les interfaces d'automatisation fournies, des sous-ensembles d'objets ActiveX pouvant être injectés, des ensembles de propriétés, de méthodes et d'événements de contrôles étendus, etc. Pour cela, un modèle a été proposé qui permet de créer divers éléments de conteneur et s'intègre bien avec la bibliothèque ATL. Indépendance de interfaces spécifiques est réalisé grâce à l'utilisation de classes de modèles, dont les paramètres sont ces interfaces.

*Par exemple, le contrôle Tab est un conteneur pour les pages de propriétés, qui sont des conteneurs à usage général.

Ce modèle vous permet de créer rapidement des variantes de base de divers objets ActiveX qui ont une "logique de conteneur" inhérente. De plus, l'infrastructure mise en place permet de créer des conteneurs qui ne sont pas des contrôles. Un tel conteneur peut être placé comme Fenêtres fenêtresà n'importe quelle partie de l'application en cours de développement, puis, en envoyant des messages appropriés, y implémenter divers contrôles.

Le résultat est une architecture assez flexible pour la construction de conteneurs, avec laquelle vous pouvez créer un Assistant (Wizard) qui étend Fonctionnalité Environnement Microsoft Visual Studio au mécanisme de génération de squelette de conteneur.


La modification manuelle du registre Windows pour supprimer les clés invalides L'erreur 800A01AD n'est pas recommandée, sauf si vous êtes un professionnel du service informatique. Les erreurs commises lors de la modification du registre peuvent rendre votre PC inutilisable et causer des dommages irréparables à votre système opérateur. En fait, même une simple virgule au mauvais endroit peut empêcher votre ordinateur de démarrer !

En raison de ce risque, nous vous recommandons fortement d'utiliser un nettoyeur de registre de confiance tel que WinThruster [Télécharger] (développé par Microsoft Gold Certified Partner) pour analyser et réparer toute erreur 800A01AD. En utilisant [Télécharger] Registry Cleaner, vous pouvez automatiser le processus de recherche des entrées de registre brisées, des références de fichiers manquantes (comme celle qui cause votre erreur %%error_name%%) et des liens brisés dans le registre. Avant chaque numérisation, une création automatique copie de sauvegarde, qui vous permet d'annuler toute modification d'un simple clic et vous protège contre d'éventuels dommages à votre ordinateur. La meilleure partie est que la correction des erreurs de registre [Télécharger] peut considérablement améliorer la vitesse et les performances du système.


Avertissement:À moins que vous ne soyez un utilisateur avancé de PC, nous vous déconseillons de modifier manuellement le registre Windows. Une utilisation incorrecte de l'Éditeur du Registre peut entraîner de graves problèmes et nécessiter réinstaller windows. Nous ne garantissons pas que les problèmes résultant d'une mauvaise utilisation de l'Éditeur du Registre puissent être résolus. Vous utilisez l'Éditeur du Registre à vos risques et périls.

Avant de restaurer manuellement Registre Windows, vous devez créer une sauvegarde en exportant la partie du registre associée à l'erreur 800A01AD (par exemple, ActiveX) :

  1. Cliquez sur le bouton Pour commencer.
  2. Entrer " commande" dans barre de recherche... N'APPUYEZ PAS ENCORE ENTRER!
  3. Tenir les clés CTRL-Maj sur le clavier, appuyez sur ENTRER.
  4. Une boîte de dialogue d'accès s'affiche.
  5. Cliquez sur Oui.
  6. La boîte noire s'ouvre avec un curseur clignotant.
  7. Entrer " regedit" et appuyez sur ENTRER.
  8. Dans l'Éditeur du registre, sélectionnez la clé associée à Erreur 800A01AD que vous voulez sauvegarder (p ex. ActiveX).
  9. au menu Dossier sélectionner Exporter.
  10. Listé Enregistrer dans sélectionnez le dossier dans lequel vous souhaitez enregistrer la copie de sauvegarde de la clé ActiveX.
  11. Dans le champ Nom de fichier entrez un nom pour le fichier de sauvegarde, tel que "Sauvegarde ActiveX".
  12. Assurez-vous que le champ Gamme d'exportation valeur sélectionnée Branche sélectionnée.
  13. Cliquez sur sauvegarder.
  14. Le fichier sera enregistré avec extension .reg.
  15. Vous avez maintenant une sauvegarde de votre entrée de registre associée à ActiveX.

Les prochaines étapes de modification manuelle du registre ne seront pas couvertes dans cet article, car elles risquent d'endommager votre système. Si vous souhaitez plus d'informations sur la modification manuelle du registre, veuillez consulter les liens ci-dessous.