Préface
Au cours des dernières semaines de travail, j'ai été troublé par un problème de mal de tête, c'est-à-dire que le contrôle ActiveX écrit en VB6 a de nombreux problèmes étranges dans l'environnement Delphi. Après de nombreux rebondissements, j'ai finalement cherché presque tous les forums et informations. , a trouvé des solutions aux problèmes qui surviennent dans différentes versions de Delphi.
L'une des exceptions fatales inexplicables dans Delphi5
Tout d'abord, jetons un œil au comportement étrange des contrôles ActiveX écrits en VB sous Delphi5.
Par exemple : nous avons utilisé VB pour écrire un contrôle UserTest (pour plus de simplicité, nous n'exportons qu'une seule classe, le contrôle utilisateur), une propriété TestName et une méthode TestMethod. Ensuite, compilez-le dans un contrôle ActiveX, enregistrez-le et importez-le dans l'environnement de développement Delphi5 (si quelque chose n'est pas clair sur les étapes ci-dessus, veuillez vérifier divers documents de référence, il doit y avoir des réponses standard), jusqu'à présent, tout semble être normal.
Ensuite, nous avons l'habitude de glisser-déposer des contrôles sur le formulaire, de les redimensionner et d'attribuer des valeurs aux propriétés dans la fenêtre des propriétés, ou la même chose dans le code. C'est tout à fait normal et simple à utiliser. Cependant, voici le problème. Si vous appelez cette TestMethod avec enthousiasme, vous obtiendrez une exception étrange "OleError800a01a9", puis le programme se fermera. Malheureusement, vous ne pourrez pas suivre cette exception en Delphi. en VB Bien sûr, si vous êtes doué en assemblage, vous pouvez suivre la fenêtre de débogage Delphi étape par étape...
Lorsque j'ai rencontré ce problème pour la première fois, j'étais presque en colère car ni Microsoft ni Borland n'avaient d'explication sur l'erreur, ni d'informations à trouver. J'ai dû me rendre sur plusieurs forums que j'ai fréquentés, bien sûr le plus important était CSDN, et j'ai recherché des questions similaires dans la version VB et Delphi. Malheureusement, il n'y avait que des questions similaires mais aucune réponse. Un gros client utilisant ce développement. outil, après avoir testé presque tous les outils et environnements de développement sous Windows (y compris le bureau et le WEB), j'ai oublié Delphi.
Au cours des deux jours restants, j'ai presque parcouru le monde, appelant tous mes amis et leur demandant si les experts Delphi étaient au courant de cette situation. Finalement, j'ai trouvé un lien de Google. Malheureusement, je l'ai oublié maintenant. , mais j'ai une méthode presque magique (c'est ainsi que l'appelle le découvreur) :
Une méthode de modification manuelle du fichier de bibliothèque de types de proxy XXX_TLB.PAS (où XXX fait référence au nom de classe du contrôle) généré par Delphi après l'importation du contrôle VBActiveX peut résoudre ce problème. Exemple:
Il existe un contrôle UserControl1 écrit en VB. Après l'avoir importé dans Delphi, deux fichiers sont générés. L'un d'eux, UserControl1_TLB.PAS, est le fichier que nous souhaitons modifier.
Trouver quelque chose comme ça dans un fichier
FintF:_UserControl1;
FunctionGetControlInterface:_UserControl1;
et
PRertyControlInterface:_UserControl1readGetControlInterface;
GetControlInterface ;
ainsi que
procédureTUserControl1.CreateControl ;
procédureDoCreate ;
commencer
Finf:=IUnknown(OleObject)as_UserControl1;
Fin;
Commencer
IfFinf=nilthenDoCreate;
Fin;
FunctionTUserControl1.GetControl1Interface:_UserControl1;
Commencer
CréerContrôle ;
Résultat :=Finfl ;
Fin;
Veuillez noter : tous les _UserControl1 marqués en rouge ici doivent être remplacés par _UserControl1Disp. Si la compilation échoue, veuillez remplacer tous les _UserControl1 signalés dans l'avertissement de compilation par _UserControl1Disp et compiler de cette façon lors de l'appel de la méthode de contrôle. se produire.
Merci pour cette belle découverte, je ne peux que la décrire ainsi, sinon je pourrais toujours être coincé dans ce cercle, ou je devrais utiliser un autre outil pour re-développer ce contrôle (je ne peux pas imaginer combien de travail cela demandera , et ou il peut y avoir d'autres problèmes de compatibilité).
Exception fatale inexplicable Delphi5 2
Cependant, Delphi ne m'a pas laissé partir après avoir contourné cette restriction. Bientôt, le client a découvert un autre problème gênant, dans l'environnement de développement, une exception apparaissait à chaque fois que le formulaire contenant le contrôle était fermé au moment de l'exécution, mais ce serait le cas. Cela ne se produit pas dans l'application compilée. Bien que cela n'affecte pas l'utilisation des utilisateurs finaux, c'est un gros problème pour les développeurs. Ensuite, je l'ai essayé en utilisant l'exemple ci-dessus et j'ai constaté que cela ne s'était pas produit. (Je suis devenu fou à l'époque. Cela était probablement dû à une utilisation incompatible dans le code. C'était extrêmement effrayant de savoir si des dizaines de milliers de lignes de code étaient régulières en une journée.) Je me suis mis en colère et j'ai bloqué le contrôle dans mon contrôle. Tout le code, ne laissant que l'interface utilisateur elle-même, et puis quelque chose d'étrange s'est produit, je n'ai écrit aucun code, mais Cette erreur se produit toujours lors du chargement de mon contrôle, ce qui me rend heureux et surpris, c'est que ce problème n'a rien à voir avec mon code, il sera donc beaucoup plus facile à trouver. la suppression de quelques normes dans les contrôles VB peut en fait provoquer de telles erreurs horribles. Le conflit entre Delphi5 et VB6 n'est vraiment pas si profond. Au cours des 2 heures suivantes, j'ai continué à supprimer les contrôles de l'interface pour tester qui avait causé cette exception fatale.
Après 2 heures, j'ai poussé un soupir de soulagement et j'ai trouvé le problème. Le problème fondamental est le suivant :
Si vous utilisez des contrôles conteneur tels que Frame et PictureBox (qui peuvent contenir d'autres contrôles) dans les contrôles utilisateur VB, vous ne pourrez pas ajouter de contrôles windowLess tels que Label, Line et Image à ces contrôles (c'est-à-dire aucun contrôle Window, ils sont dessinés par VB en temps réel pendant l'exécution), sinon vous obtiendrez le rapport d'erreur comme ci-dessus.
Contrôles ActiveX masqués dans Delphi6 et 7
Justement à cause de l'horrible expérience sous Delphi 5, j'ai trouvé encore nécessaire de tester si le même problème existe sous Delphi 6 et 7 (les versions précédentes ne sont plus nécessaires car il y a très peu d'utilisateurs, et Delphi 8 n'est pas officiellement sorti mais ils ne sont donc pas disponibles pour le moment et ne sont pas pris en compte). Le résultat est : ... peu importe le nombre de fois que je le charge, je ne trouve jamais cette petite icône tant attendue sur la barre ActiveX. Ce résultat est bien sûr très drôle, je n'arrive même pas à le charger, encore moins si le test est normal ou non.
De même, j'ai cherché sur divers forums et sites Web et j'ai trouvé plus de personnes posant des questions similaires dans CSDN, mais la réponse était toujours nulle. En désespoir de cause, j'ai dû ajuster les options dans chaque Delphi6 et 7...
Après 3 heures, 15 minutes et 54 secondes, j'ai trouvé la cause, ou la solution, de ce foutu problème (pardonnez-moi de l'appeler ainsi, je ne pouvais tout simplement pas le supporter), qui est en fait très simple.
Maintenant, suivez-moi : cliquez sur le menu Outils->EnvironmentOptions->TypeLibrary, nous devrions trouver un élément : IgnorespecialCoClassFlagsWhenImporting, sélectionnez-le, puis sélectionnez l'élément CanCreate, alors maintenant, essayons d'importer ce mauvais contrôle ActiveX (il devrait être notez ici que si vous l'avez importé une fois, veuillez supprimer les deux fichiers générés, les fichiers .dcr et .pas, sinon il ne sera pas actualisé). Si vous ne trouvez toujours pas le contrôle dans la colonne ActiveX cette fois, alors vous devez appeler Microsoft ou Borland et leur demander quand ils pourront se marier, haha !
(De plus, les erreurs ci-dessus apparues dans Delphi5 n'ont pas été trouvées dans Delphi6 et 7)
Mon environnement de test est :
Win2K
Delphi5Mise à jour1
Delphi6Mise à jour2
Delphes7