Version imprimable       Envoyer     
Cliquez pour évaluer et commenter
MSDN
MSDN Library
Articles Techniques
Visual Studio 2005
Visual Basic
 Consommer un objet .Visual Basic 20...

  Passer à l'affichage pour faible bande passante
Consommer un objet .Visual Basic 2005 avec Visual Basic 6.0
Par Eric Vernié, Responsable relation technique développeurs - Microsoft France

Document de référence
Révision 1.0

Technologies abordées
Visual Basic 6.0
Visual Basic 2005
Framework .Net 2.0

Téléchargez l'application d'Eric

Sur cette page

Résumé Résumé
Introduction Introduction
Création automatique d’un proxy .NET pour COM Création automatique d’un proxy .NET pour COM
Conclusion Conclusion

Résumé

Dans cet article, vous découvrirez comment créer un objet .NET avec Visual Basic 2005, et le consommer avec Visual Basic 6.0.

Introduction

Il est clair que lorsque nous avons investis du temps et de l’argent dans le développement d’application, nous ne pouvons pas toujours nous permettre de tout changer ou de tout reconstruire à chaque fois qu’une nouvelle version d’un produit, ou d’un outil apparaît sur le marché.
C’est d’autant plus vrai, qu’entre Visual Basic 6.0 et Visual Basic pour la plate-forme .NET il y a eu beaucoup de changements et que la migration automatique d’un projet, ne va pas sans quelques inconvénients.
Mais il est toujours sain de se poser des questions concernant l’évolution de notre application Visual Basic 6.0.

Faut-il tout reprendre de zéro ?
Dois-je réécrire mon application entièrement ?
Dois-je migrer le code ?
Dois-je réutiliser des parties existantes, Dois-je faire du code Mixte ?

Autant de questions importantes que vous devez vous poser et que auxquels je ne peux répondre ici, car cela dépend essentiellement de votre application. Mais je vous recommande la lecture de l’article Mise en œuvre d’une stratégie de migration de Visual Basic 6.0 vers Visual Basic .NET qui pourra vous aider dans votre démarche.

Dans cet article, ce que je vous propose c’est de créer du code Mixte. C'est-à-dire, de pouvoir ajouter des fonctionnalités à votre application Visual Basic 6.0, tout en tirant profit de la plate-forme .Net 2.0.


Rendre un composant .NET visible pour COM.

Comme je le sous entendais en introduction, il existe désormais deux mondes pour les développeurs Visual Basic. Deux mondes qui doivent cohabiter sans doute pour quelques temps encore.
Il existe déjà depuis quelques années le monde COM sur lequel s’appui Visual Basic 6.0, puis très récemment le monde .NET sur lequel ont été construites les nouvelles moutures de Visual Basic. (2002/2003 et 2005)
Ces deux mondes sont totalement différent, mais quoi que vous entendiez de ci de la, la plate-forme .NET est un indéniable atout pour les développeurs Visual Basic.

Pour que ces deux mondes puissent vivre en harmonie, et que tout l’investissement fait sur COM ne soit pas remisé au placard, Microsoft a incorporé dans la plate-forme .NET, une technologie nommée « ComInterop », qui permet d’utiliser :

  • des composants COM avec .NET

  • des composants .NET avec COM

Pour notre part, nous allons nous focaliser sur la manière de construire un Composant .NET visible pour COM.

Avant d’aller plus loin je souhaiterai faire un rapide rappel sur COM (Common Object Model).et Visual Basic 6.0


Le modèle COM Visual Basic 6.0

Lorsqu’avec Visual Basic 6.0, vous créez un projet de type « DLL ActiveX », est crée une classe nommée par défaut Class1, dans laquelle vous pouvez ajouter des méthodes, des propriétés, etc…
Lors de la compilation, en définitif, est construit pour vous toute l’infrastructure COM.Par exemple, supposons que vous ayez une classe nommée AccesDonnees possédant une méthode unique TrouverClient(IDClient as integer), le compilateur de VB6, incorpore pour vous par défaut, les informations de type dans la DLL. Dans le monde COM ces informations de type sont en générale décrites dans un fichier avec extension TLB (Type Library), que vous pouvez créer en cochant la case appropriée dans l’interface de VB6 (cf. Figure 1)


Figure1

Est donc généré par le compilateur des informations que vous retrouvées dans la Figure 2

        [
        uuid(8176057F-DE8A-4013-9837-0857FFC05E7F),
        version(1.0),
        custom(50867B00-BB69-11D0-A8FF-00A0C9110059, 9782)

        ]
        library MaDLLActiveX
        {
        // TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
        importlib("stdole2.tlb");

        // Forward declare all types defined in this typelib
        interface _AccesDonnees;

        [
        odl,
        uuid(6ECAB544-0A59-4962-8743-B88A1719253C),
        version(1.0),
        hidden,
        dual,
        nonextensible,
        oleautomation
        ]
        interface _AccesDonnees : IDispatch {
        [id(0x60030000)]
        HRESULT TrouverClient(
        [in, out] short* IDClient,
        [out, retval] BSTR* );
        };

        [
        uuid(7F55DE1D-A5B7-466C-B678-DDF1FCFBC907),
        version(1.0)
        ]
        coclass AccesDonnees {
        [default] interface _AccesDonnees;
        };
        };
      

Figure 2 : Informations contenues dans la TLB


En tant que développeurs Visual Basic 6.0, vous n’avez pas besoin de connaître ses informations, par contre il est intéressant de les appréhender pour bien comprendre la suite de l’article.

La librairie ce nomme MaDLLActiveX et aura comme numéro d’identification (GUID) 8176057F-DE8A-4013-9837-0857FFC05E7F

Elle est constituée d’une interface _AccesDonnees avec comme numéro 6ECAB544-0A59-4962-8743-B88A1719253C. Cette interface possède une méthode TrouverClient et dérive de l’interface IDispatch. A noter que c’est bien le compilateur VB6 qui a crée pour nous cette interface en préfixant le nom de notre classe AccesDonnees par le caractère de soulignement « _ ».
L’interface IDispatch permet de rendre notre composant, compatible avec des langages de scripting tel que VBScript en permettant les liaisons tardives. (Vous savez l’instruction CreateObject() !!!)

Enfin nous retrouvons notre Class AccesDonnees, sous forme de CoClass avec un numéro d’identification 7F55DE1D-A5B7-466C-B678-DDF1FCFBC907 et qui dérive de l’interface _AccesDonnees.
Toute ActiveX DLL crée en Visual basic 6.0 aura cette forme.

Une remarque que je souhaiterai ajouter ici. A chaque compilation les numéros d’identifications peuvent changer si vous n’y faite pas attention, rendant ainsi votre objet incompatible avec des clients qui auraient déjà été liés à votre ActiveX et qui n’auraient pas été recompilés en même temps. Vous savez le message « Erreur 429 ne peut créer l’objet !!!!»…..
Comme il n’est pas possible de maitriser ces numéros d’identifications et donc de réutiliser les mêmes à chaque fois, il est impératif d’avoir une bonne maitrise du versionning de vos composants COM.

Résumons ce que nous venons de voir. Notre ActiveX DLL est donc constituée :

  1. D’un numéro d’identification qui l’identifie de manière unique

  2. Une interface avec son numéro qui l’identifie de manière unique

  3. Une CoClass avec son numéro d’identification

Chaque numéro d’indentification est construit sous la forme de Global Unique Indentifier (GUID) codé sur 128 bits qui permet justement de construire des numéros uniques.

Une fois que vous avez ces notions en tête, passons à la création de notre proxy .NET pour COM.


Construire le proxy .NET pour COM

Dans Visual Basic 2005 (Express ou toute autre version)

  1. Créez un nouveau projet de type « Bibliothèque de classes ». (Laissez le nom par défaut)

    Vous retrouverez dans le fichier Class1.vb le code suivant :

                Public Class Class1
                End Class
              
  2. Pour rendre Class1, visible par COM, nous allons utiliser l’attribut du Framework .NET ComClassAttribut. Comme ceci :

                <ComClass(InterfaceShadows :="False")>
                  _
                  Public Class Class1
                  Sub MaMethodeNET()
                  MsgBox(“Bonjour en VB 2005”)
                  End Sub
                  End Class
                

    Pour l’instant avec cet attribut, j’informe qu’il faudra créer dans la librairie de Type (TLB) l’interface et d’utiliser pour la coClass et l’interface des numéros d’identifications aléatoires.

  3. Pour ajouter un numéro d’identification à la librairie elle-même, il faudra cocher la case « Rendre l’assembly visible par COM » que vous trouverez en activant les propriétés de la classe, puis l’onglet Application, puis le bouton « Informations de l’assembly »

  4. Compilez le projet, la DLL ClassLibrary1.dll est ainsi construite.


Enregistrement de votre proxy et création de la librairie de Type.

  • Si vous possédez une version autre que Visual Basic Express, vous pouvez enregistrer directement la DLL en cochant la case : « Enregistrer pour COM Interop », dans l’onglet « compilation », des propriétés du projet, ou vous pouvez utiliser l’outil regasm.exe :

     Regasm ClassLibrary1.DLL /tlb 

    L’instruction /tlb créée la librairie de type ClassLibrary1.tlb

  • Si vous n’avez que Visual basic Express, vous pouvez également utiliser l’outil Regasm que vous trouverez en téléchargeant le SDK du FrameWork.NET 2.0.

  • Si vous ne souhaitez pas télécharger le SDK, vous pouvez utiliser l’outil que j’ai développé à cet égard.

    Pour l’utiliser, installez-le (binaire fourni en téléchargement avec cet article), allez directement à l’onglet « Enregistrement »


    Activez le menu Assembly, et chargez l’assembly ClassLibrary1.dll que vous venez de créer. Cela à pour effet d’activer le bouton « Enregistrement » Appuyez sur le bouton « Enregistrement »


    Si tout se passe correctement vous devez recevoir le message

    Non seulement l’outil enregistre le composant, mais crée également une TypeLibrary nommée ClassLibrary1.tlb que nous allons utiliser par la suite dans Visual Basic 6.0


Consommation du Proxy .NET dans Visual Basic 6.0

  1. Allez dans Visual basic 6.0

  2. Ajoutez une référence au proxy en prenant comme référence ClassLibrary1.tlb

  3. Puis ajoutez le code de consommation sous l’évènement click d’un Bouton

                Private Sub Command1_Click()
                Dim wrapper As ClassLibrary1.Class1
                Set wrapper = New ClassLibrary1.Class1
                wrapper.MaMethodeNET
                End Sub
              

    Exécutez le programme, vous devez obtenir le message

J’aimerai attirer votre attention sur le fait suivant :
En utilisant l’attribut ComClass, avec comme unique paramètre InterfaceShadows=true, nous restons dans une construction sensiblement identique à Visual Basic 6.0. C'est-à-dire, que nous ne maitrisons pas la création des numéros d’identification pour notre CoClass, Interface voir nos évènements ou tous autres types. Il est donc de bon ton d’aller un peu plus loin, et de forcer l’utilisation de nos propres GUID évitant de polluer notre registre avec d’anciennes versions qui auraient été générées automatiquement. Pour ce faire notre code doit être modifié comme ceci :

        <ComClass(Class1.ClassID, _="
           Class1.InterfaceID=", _="
           Class1.EventID=")>
          _
          Public Class Class1
          Public Const ClassID As String = "03c3452d-6b57-4c54-8fed-46abdda0ece9"
          Public Const InterfaceID As String = "62fba3d5-a0d0-42d2-adb1-2d7a4d9aeded"
          Public Const EventID As String = "a78a4d65-3462-496e-be86-f9be77022eff"
          Sub New()
          MyBase.New()
          End Sub
          Sub MaMethodeNET()
          MsgBox("Bonjour en VB 2005")
          End Sub
          End Class
        

On force l’utilisation d’un Global Unique Identifier, pour la coClass, l’interface et les évènements. Pour obtenir les GUID, vous avez plusieurs solutions.

  1. Si vous utilisez une version autre que la version Visual basic Express, un outil est intégré nommé « Create GUID » que vous pouvez activer par le biais du menu Outils\Create Guid.


    Attention de bien sélectionner le format N°4

  2. Si par contre vous utilisez Visual basic Express, vous pouvez utiliser un second outil que j’ai développé et qui est disponible en téléchargement avec cet article, et qui fait la même chose.


    Une fois le Guid crée, copiez le dans le presse papier avec le bouton approprié, puis allez dans votre code et collez-le.

Création automatique d’un proxy .NET pour COM

Si comme moi, vous voulez automatiser la création d’un proxy, vous pouvez :

  1. Soit créer un extrait de code avec Visual basic 2005 et le réutiliser. Je ne vais pas rentrer ici dans les détails, mais sachez qu’il existe un outil SnippetEditor, qui mâche le boulot pour vous

  2. Soit utiliser mon outil qui est en téléchargement avec cet article, dont voici quelques explications.

En un mot, l’outil « Créer proxy COM » permet de générer tout le code Visual Basic 2005 en un seul click.

Comment ça marche ?
Au lancement de l’application, vous tombez sur le 1er Ecran. L’écran Informations, vous permet d’ajoutez un entête sous forme de commentaire dans le code du proxy :


Ecran informations


L’écran Type du Proxy, vous permet de définir le minimum requis pour créer votre Proxy. Un espace de nom, un nom de classe, une méthode de type Sub sans paramètre, ainsi qu’un événement .NET disponible pour COM.


Vous pouvez dés à présent allez directement à l’écran générer en sélectionnant l’onglet Générer.
Cochez la case Sauvegarder le proxy dans un fichier pour créer un fichier avec extension *.vb que vous pourrez réutiliser dans une solution

Ensuite, activez le bouton pour générer le proxy qui s’affiche dans la fenêtre

Dans mon exemple, le proxy a été crée dans un fichier nommée Class1.vb (dans le répertoire de l’application) dont voici le détail.

        Imports System
        Imports System.Runtime.InteropServices
        Imports Microsoft.VisualBasic

        'Titre        :       Création d'un composant .NET/COM pour Visual Basic 6.0
        'Auteur       :       Eric Vernié
        'Date         :       13/06/2006
        'Mise à jour  :
        'Description  :       Exemple de Wrapper COM pour Visual Basic 6.0
        'Pour rendre visible l'assembly pour COM, décommenter les lignes suivantes <Assembly...>
      'Ou n'oubliez pas de cocher la case Rendre Visible pour COM
      '<Assembly: ComVisibleAttribute(True=")>
      '<Assembly: Guid="("8ddbae82-ee79-4401-954b-2bc490838c2e")>
        'Pour Enregistrer l'assembly, utiliser l'outil regasm
        Namespace Microsoft.DPE

        <Microsoft.VisualBasic.ComClass("0ca724be-3ae8-4462-913c-47c0ff7e8f00", 
		"868e0078-eff7-43c3-83c6-0d6a7211158b", "281261cd-b6f2-4254-ace1-8da4c8436eb4")>
      _
      Public Class WrapperCOM

      Public Event MonEvent As MonHandler

      <ComVisible(true)>
      _
      Sub Initialiser()
      'TODO : Ajoutez votre code d'initialisation
      End Sub

      'Méthode à tester Via VB6
      <ComVisible(true)>
      _
      Sub MethodeTest()
      Msgbox("Hello le monde !!!")

      End Sub

      'Cette méthode n'est pas visible pour COM
      <ComVisible(false)>
      _
      Sub AutreMethode()
      End Sub

      <ComVisible(true)>
      _
      Sub SurEvenement(ByVal timeout As Integer)
      System.Threading.Thread.Sleep(timeout)
      RaiseEvent MonEvent(me,new EventArgs())
      End Sub

      Public Delegate Sub MonHandler(ByVal Sender As Object, ByVal e As System.EventArgs)
      End Class
      End Namespace
     

On y retrouve l’entête sous forme de commentaires, l’espace de nom Microsoft.DPE, une classe accrochée à un attribut ComClass, dont les GUIDS ont été crée automatiquement, la méthode Initialiser(), ainsi que l’évènement MonEvent de type MonHandler.

Vous pourrez remarquer que j’y ai ajouté aussi plusieurs méthodes de test comme la Sub, MethodeTest() qui affiche un message, ainsi que la méthode SurEvenement qui lève notre évènement au bout d’un certain temps. Ce code est prêt à l’emploi et vous pouvez déjà le tester dans Visual Basic 6.0. Point que nous aborderons un peu plus loin.

Le bouton permet de valider les éventuels changements que vous auriez faits directement dans la fenêtre. En effet, rien ne vous empêche à ce niveau de rajouter manuellement du code vb. Par exemple, vous pouvez ajouter manuellement des méthodes, des propriétés, des événements, tout le code VB 2005 qui vous passe par la tête.

Avant de tester ce proxy dans Visual Basic 6.0, vous devez compiler le proxy et l’enregistrer. Deux méthodes s’offrent à vous.

  1. Si vous avez sauvegardé le proxy dans un fichier *.vb, avec Visual Basic 2005, vous pouvez le réutiliser et le compiler. Pour l’enregistrement refaite les étapes vues à la section « Enregistrement de votre proxy et création de la librairie de Type »

  2. Ou alors sans sortir de l’outil, activez l’onglet « Compiler » vous devez tomber sur l’écran suivant

Cet écran, comme son nom l’indique vous permettra de compiler et d’enregistrer automatiquement l’assembly en activant le bouton et en cochant la case Enregistrer pour COM. Voici ce que vous devez obtenir

Le faite de cocher la case enregistrer pour COM, crée également une librairie de type nommée Microsoft.DPE.WrapperCOM.tlb que nous allons réutiliser dans Visual Basic 6.0

Pour consommer et tester notre Proxy

  • Allez dans Visual basic 6.0

  • Créez un projet de type EXE

  • Ajoutez une référence à la librairie Microsoft.DPE.WrapperCOM.tlb

  • Puis ajoutez le code suivant

        Public WithEvents objNet As Microsoft_DPE_WrapperCOM.WrapperCOM
        Private Sub Command1_Click()
        Set objNet = New Microsoft_DPE_WrapperCOM.WrapperCOM
        objNet.SurEvenement (1000)
        objNet.MethodeTest
        End Sub

        Private Sub objNet_MonEvent(ByVal Sender As Variant, ByVal e As mscorlib.EventArgs)
        MsgBox ("J'ai fini mon travail")
        End Sub
      

Et voila c’est fait, vous avez crée votre premier proxy COM prêt à l’emploi. A vous de jouer maintenant. Très prochainement, vous pourrez retrouver sur le site VBasic de MSDN France sous formes de Vidéos des exemples d’utilisation des librairies du FrameWork .NET 2.0.
En attendant vous pouvez aller voir l’article que j’ai écrit sur le multi-threading et Visual Basic 6.0 qui s’inspire de cette technique de COMInterop.

J’aimerai terminer rapidement par les écrans, « Méthodes », « Propriétés », « Evènements » qui vous permettent d’ajouter à votre proxy les éléments qu’ils décrivent. Prenons par exemple l’écran Méthodes (Je vous laisse découvrir les autres par vous-même)

Cet écran vous permet d’ajouter des Méthodes de type Sub (sans type de retour) ou des Méthodes de type Function, les deux avec ou sans paramètre. Par exemple, pour ajouter une méthode nommée ClientExiste, qui prend en paramètre un long, et un tableau de String et qui retourne un Boolean, suivez les étapes suivantes :

  1. Entrez le nom de la méthode : ClientExiste

  2. Cochez la case : Function

  3. Sélectionnez le type de retour : System.Boolean

  4. Entrez un nom de paramètre : IDClient

  5. Cochez ByVal ou ByRef

  6. Sélectionnez le type : System.Int32

  7. Ajoutez le paramètre en activant le bouton

  8. Entrez un second nom de paramètre avec des parenthèses: MonTableau()

  9. Sélectionnez Byref

  10. Sélectionnez le type : System.String

  11. Ajoutez le paramètre en activant le bouton

  12. Ajoutez la méthode en activant le bouton

Il est important d’ajouter d’abord les paramètres, avant d’ajouter la méthode. Répétez l’opération autant de fois que vous avez de méthodes

Pour générer le proxy avec les nouvelles informations, activez directement le bouton générer ou click sur bouton droit de la souris, menu générer. Contre toute attente, le code suivant dans notre cas doit être ajouté au proxy.

        <ComVisible(true)>
          _
          Function ClientExiste(ByVal IDClient As Integer, ByVal MonTableau() As String) As Boolean
          End Function
        

Compilez le code avec l’outil pour valider qu’il n’y a pas d’erreur. A noter que vous pouvez supprimer paramètre par paramètre ou tous les paramètres d’un coup idem pour les méthodes.
Si vous souhaitez ajouter des propriétés et des méthodes, le même principe est applicable, si ce n’est que pour les propriétés, l’outil génère à la fois la méthode Get et Set selon les cas, mais aussi les données membres privées et leur consommation. Comme ceci :

        Private _fichierexiste As Boolean

        Public Property FichierExiste() As Boolean
        Get
        Return _fichierexiste
        End Get
        Set
        Me._fichierexiste = value
        End Set
        End Property
      

Ca fait gagner du temps ;-)

Conclusion

Nous venons de voir dans cet article, comment il était simple de créer avec Visual Basic 2005 des composants qui soient exploitables dans vos applications Visual basic 6.0. Avec cette technique il est possible de faire évoluer son application Visual Basic 6.0 préférée tout en profitant des nouveautés du Framework .NET 2.0 et de sa simplicité d’utilisation. L’application évolue en douceur, et vous évoluez en douceur aussi, en appréhendant le Framework 2.0 et Visual basic 2005 à votre rythme.

© 2009 Microsoft Corporation. Tous droits réservés. Conditions d'utilisation  |  Marques  |  Confidentialité
Page view tracker