Dégradation normale en l’absence d’une interface
Comme un contrôle peut ne pas prendre en charge une interface autre que IUnknown, un conteneur doit se dégrader correctement lorsqu’il rencontre l’absence d’une interface particulière.
Il peut être question de l’utilité d’un contrôle avec une valeur autre que IUnknown. toutefois, tenez compte des avantages qu’un contrôle reçoit de l’environnement de programmation visuel d’un conteneur (par exemple VB) lorsque le conteneur reconnaît l’objet comme un contrôle :
- Un bouton pour l’objet s’affiche dans une boîte à outils.
- Vous pouvez créer un objet en le faisant glisser de la boîte à outils vers un formulaire.
- L’un peut attribuer à l’objet un nom qui est reconnu dans l’environnement de programmation visuel.
- Le même nom dans (3) ci-dessus peut être utilisé immédiatement dans l’écriture de tout autre code pour les contrôles du même formulaire (ou même un autre formulaire).
- Le conteneur peut fournir automatiquement des points d’entrée de code pour tous les événements disponibles à partir de cet objet.
- Le conteneur fournit sa propre interface utilisateur de navigation des propriétés pour toutes les propriétés disponibles.
Lorsqu’un objet n’est pas reconnu comme un contrôle, il perd potentiellement toutes ces fonctionnalités d’intégration très puissantes et bénéfiques. par exemple, dans Visual Basic 4,0, il est très difficile d’intégrer vraiment un objet aléatoire qui n’est pas un contrôle dans le sens complet, mais peut toujours avoir des propriétés et des événements. étant donné que l’idée de Visual Basic 4 d’un contrôle est très restrictive, l’objet n’obtient aucune des fonctionnalités d’intégration ci-dessus. Mais même un contrôle avec IUnknown, où la simple durée de vie du contrôle détermine l’existence d’une ressource, doit être en mesure d’obtenir les fonctionnalités d’intégration décrites ci-dessus.
Comme les outils actuels requièrent un grand nombre d’interfaces de contrôle pour tirer parti de tout avantage, les contrôles sont généralement dirigés vers une implémentation excessive, de sorte qu’ils contiennent plus de code que nécessaire. Les contrôles qui pourraient être 7K peuvent finir par dépasser 25 Ko, ce qui constitue un problème de performances considérable dans des domaines tels qu’Internet. Cela a également conduit à la perception qu’il est possible d’implémenter un contrôle avec un seul outil comme le CDK, en raison de la complexité de l’implémentation de toutes les interfaces, et cela a des implications quand une grande DLL comme OC30.DLL est requise pour un tel contrôle, ce qui augmente la plage de travail. Si toutes les interfaces ne sont pas requises, cela ouvre de nombreux développeurs pour écrire des contrôles très petits et légers avec OLE direct ou avec d’autres outils, ce qui réduit la surcharge de chaque contrôle.
C’est pourquoi cette annexe reconnaît un contrôle comme n’importe quel objet avec un CLSID et une interface IUnknown . Même si vous n’avez rien de plus que IUnknown, un conteneur avec un environnement de programmation doit pouvoir fournir au moins # les fonctionnalités 3 et) de l’entrée de Registre, il gagne # 1 et # 2. Si l’objet fournit IConnectionPointContainer (et IProvideClassInfo en général) pour un jeu d’événements, il gagne # 5, et s’il prend en charge IDispatch pour les propriétés et les méthodes, il gagne # 6, ainsi qu’une meilleure intégration du code dans le conteneur.
En bref, un objet doit pouvoir implémenter aussi peu que IDispatch et un jeu d’événements exposé via IConnectionPointContainer pour obtenir toutes les fonctionnalités visuelles ci-dessus.
En tenant compte de cela, le tableau suivant décrit ce qu’un conteneur peut faire en l’absence d’une interface possible. Notez que seules ces interfaces sont répertoriées que le conteneur peut obtenir directement via QueryInterface. D’autres interfaces, telles que IOleInPlaceActiveObject, sont obtenues par d’autres moyens.
| Interface | Signification de l’absence d’interface |
|---|---|
| IViewObject2 |
Le contrôle n’a aucun visuel qu’il se dessine lui-même et n’a donc aucune étendue définie à fournir. Au moment de l’exécution, le conteneur ne tente tout simplement pas de dessiner lorsque cette interface est absente. Au moment du design, le conteneur doit au moins dessiner un type de rectangle par défaut avec un nom pour ce contrôle, de sorte qu’un utilisateur dans un environnement de programmation visuel peut sélectionner l’objet et consulter ses propriétés, méthodes et événements qui existent. La gestion de l’absence de IViewObject2 est essentielle pour une bonne prise en charge de la programmation visuelle. |
| IOleObject |
Le contrôle n’a pas besoin du site et ne participe à aucune négociation de disposition d’objet incorporée. Toutes les informations (telles que les extensions de contrôle) qu’un conteneur peut attendre de cette interface doivent être renseignées avec les valeurs par défaut fournies par le conteneur. |
| IOleInPlaceObject |
Le contrôle n’est pas actif sur place (comme une étiquette) et ne tente donc jamais de l’activer de cette manière. Sa seule activation peut être ses pages de propriétés. |
| IOleControl |
Le contrôle n’a pas de mnémoniques et n’utilise pas de propriétés ambiantes, et ne se soucie pas du fait que le conteneur ignore les événements. En l’absence de cette interface, le conteneur n’appelle pas simplement ses méthodes. |
| IDataObject |
Le contrôle ne fournit aucun jeu de propriétés, ni aucun rendu visuel pouvant être mis en cache. par conséquent, le conteneur choisirait de mettre en cache une présentation par défaut en l’absence de cette interface (prise en charge de CF _ MetaFilePict, en particulier) et désactivez toutes les fonctionnalités associées à un jeu de propriétés. |
| IDispatch |
Le contrôle n’a pas de propriétés ou de méthodes personnalisées. Le conteneur n’a pas besoin d’essayer d’afficher des propriétés de contrôle dans ce cas, et doit interdire les appels de méthode personnalisés que le conteneur ne reconnaît pas comme appartenant à ses propres contrôles étendus (qui peuvent prendre en charge des méthodes et des propriétés). Comme les contrôles étendus délèguent généralement certains appels IDispatch au contrôle, un contrôle étendu ne doit pas s’attendre à ce que le contrôle ait du tout IDispatch . |
| Interfaces |
Le contrôle n’a pas d’événement, donc le conteneur n’a pas à se soucier de la gestion des. |
| IProvideClassInfo IProvideClassInfo2 |
Le contrôle n’a pas d’informations de type ou d’événements, ou le conteneur doit accéder aux informations de type du contrôle par le biais des entrées de Registre du contrôle. L’existence de cette interface est une optimisation. |
| ISpecifyPropertyPages |
Le contrôle n’a aucune page de propriétés. par conséquent, si le conteneur a une interface utilisateur qui les appelle, le conteneur doit désactiver cette interface utilisateur. |
| IPerPropertyBrowsing |
Le contrôle n’a pas de nom d’affichage lui-même, aucune chaîne ni aucune valeur prédéterminées et aucune propriété n’est mappée à la page. Cette interface est presque toujours utilisée pour générer l’interface utilisateur d’un conteneur, ce qui signifie que ces éléments d’interface utilisateur seraient désactivés en l’absence de cette interface. |
| IPersist* |
Le contrôle n’a pas d’état persistant à parler, donc le conteneur n’a pas à se soucier de l’enregistrement des données spécifiques au contrôle. Bien sûr, le conteneur enregistre ses propres informations sur le contrôle dans son propre formulaire ou document, mais le contrôle lui-même n’a rien à contribuer à ces informations. |
| IOleCache IOleCache2 |
L’objet ne prend pas en charge la mise en cache. Un conteneur peut toujours prendre en charge la mise en cache en créant simplement un cache de données lui-même à l’aide de CreateDataCache. |