Comme le titre l'indique, cet article va exposer deux éléments importants : L'utilisation de GDI+ dans une DLL ActiveX écrite en VB6; L'appel à cette DLL ActiveX en C#.
Programmation > .Net
Recherche :   
Actualité Système Salon Concours Outils Programmation Devparadise Programmation HTML .Net JavaScript VBScript ASP PHP Visual Basic Perl Java Active X SQL XML WAP Delphi Graphisme Flash Web Design Promotion Référencement Publicité Valeur de votre site Outils Systèmes Windows Unix Linux Benchmark Hardware Réseaux locaux Droit Sécurité
Création en VB6 d'une DLL ActiveX utilisant GDI+, et appel de cette dernière en C# dans une application Web ASP.NET
  Auteur : Siegfried DUHAMEL

Comme le titre l'indique, cet article va exposer deux éléments importants : L'utilisation de GDI+ dans une DLL ActiveX écrite en VB6; L'appel à cette DLL ActiveX en C#.

Publicité 
Je vous propose donc dans un premier temps d’expliquer comment appeler GDI+ en VB6 pour manipuler une image et écrire un texte à l’intérieur. Une fois le projet achevé, nous obtiendrons une DLL pouvant être enregistrée sur un serveur.

Dans un second temps je vais vous montrer comment appeler cet ActiveX dans un projet de type application Web écrit en C#.

Appeler GDI+ en VB6.

Le projet

Le but ici est de créer un projet de type DLL ActiveX. Je fais donc un nouveau projet et dans la liste des types choisissez DLL ActiveX.

Il va se présenter ainsi :

- 9 modules de classe dont :

  • 8 pour s’interfacer sur GDI+;
  • 1 utilisé comme point d’entrée de l’ActiveX.
- 1 module contenant un certain nombre d’éléments (fonctions, types, etc.) pour utiliser GDI+.

Les éléments du projet

Le module de classe "Dessin".

Il va me servir par la suite comme point d’entrée de l’ActiveX.
Il contient 5 propriétés :

  • "CheminImage" : elle recevra le chemin vers le dossier qui contiendra l’image que je vais utiliser comme modèle pour écrire mon texte;
  • "NomImageModele" : elle recevra le nom de l’image que je veux utiliser comme modèle;
  • "NomFont" : elle recevra le nom de la police de caractère avec laquelle je veux écrire dans l’image;
  • "MaCouleur" : elle recevra la couleur du texte;
  • "TailleTexte" : elle recevra la taille du texte.
Pour ceux qui ne sont pas familiers de la structure des propriétés en VB6 voilà comment écrire "CheminImage" :

Private m_nTailleTexte As Integer
Public Property Get TailleTexte() As Integer
   TailleTexte = m_nTailleTexte
End Property
Public Property Let TailleTexte(ByVal vNewValue As Integer)
   m_nTailleTexte = vNewValue
End Property

  • m_nTailleTexte constitu le champs privé qui va contenir la valeur de la propriété.
  • L’élément Get permet de récupéré sa valeur.
  • L’élément Let permet de renseigner sa valeur.
"Dessin" contient aussi deux fonctions public :

Public Function DessinerAvecProprietes()

Regardons-la d’un peu plus près, elle n’accepte pas de paramètres, et c’est ici que je vais déclarer les objets qui vont me permettre de créer l’image que l’on attend.

Par exemple l’objet "GdipBitmap" qui va récupérer l’image qui sert de modèle :
   ’ Création du bitmap à partir du fichier
   Set oBmp = New GdipBitmap
   strImg = CheminImage & "" & NomImageModele
   status = oBmp.CreerBitmapFromFile(strImg)

Public Function DessinerAvecParametres(strChmImg As String, strNomImgModele As String, strNomFont As String, nCouleur As Long, nTailleTexte As Integer)

Pour cette fonction, il y a cinq paramètres. Elle sert simplement à collecter les éléments permettant de renseigner les propriétés servant à générer l’image et à appeler la précédente fonction pour retourner son résultat.

Les modules de classes permettant d’accéder à GDI+.

On les appelle aussi "Wrapper". Vous en trouverez 6 dans ce projet. Je vous les présente dans l’ordre d’apparition à l’intérieur de la fonction DessinerAvecProprietes :

  • "GdipBitmap" : elle va me permettre de créer dans GDI+ un "Bitmap" à partir du chemin vers l’image qui me servira de modèle et d’en récupérer le pointeur;
  • "GdipImage" : en utilisant le pointeur généré par "GdipBitmap" (une image étant un "Bitmap", ça ne vous fait pas penser a l’héritage du .NET ?) je vais pouvoir générer un pointeur vers un "Graphics";
  • "GdipGraphics" : elle va me permettre de manipuler le"Graphics"dont je viens de récupérer le pointeur, c’est lui qui va écrire dans notre image;
  • "GdipFontFamily" : elle va me permettre de créer dans GDI+ une "FontFamily" à partir de la propriété "NomFont" vue plus haut et d’en récupérer le pointeur;
  • "GdipFont" : elle va me permettre de créer dans GDI+ une "Font" à partir des différents éléments qui lui sont passés en paramètres et d’en récupérer le pointeur;
  • "GdipSolidBrush" : elle va me permettre de créer dans GDI+ une "SolidBrush" à partir de la propriété "MaCouleur" et d’en récupérer le pointeur;
Leur implémentation est volontairement partielle par soucis de clarté. Vous trouverez en fin d’article les liens vers les sites qui m’ont permis de les réaliser.
Pour les explications je vais prendre l’exemple de "GdipBitmap". Les autres sont construits sur le même principe.

Tout d’abord le code qui va me permettre de créer un bitmap à partir d’un fichier en utilisant GDI+ :

   Private Declare Function GdipCreateBitmapFromFile Lib "gdiplus" (ByVal filename As String, bitmap As Long) As GpStatus

Je déclare en fait une fonction dans "GdipBitmap" en indiquant qu’elle se trouve dans la librairie "gdiplus", qu’elle accepte deux paramètres ("filename" de type "String" et "bitmap" de type "Long") et qu’elle retourne une valeur de type "GpStatus".
"filename" : représente le chemin d’accès à mon fichier, je vais devoir le récupérer quelque part pour alimenter ma fonction.
"bitmap" : est la variable qui va prendre, dans la fonction "GdipCreateBitmapFromFile" de GDI+, la valeur du pointeur vers mon "Bitmap".
"GpStatus" : est un enum (voir dans GdipHelper.cls) qui représente les valeurs d’erreur retournés par GDI+.
J’ai ensuite implémenté une fonction "CreerBitmapFromFile" qui me permet de passer en paramètre le chemin vers mon fichier, de traiter la chaîne de caractères pour appeler "GdipCreateBitmapFromFile", de faire une gestion d’erreur et de récupérer mon pointeur pour en faire une propriété de mon objet.
Voilà pour le principe de l’appel à GDI+, utiliser les pointeurs qu’il nous retourne.

Que fait-on du projet ?

Ce projet va être compilé sous forme d’une dll qu’il sera possible d’enregistrer sur un serveur en utilisant regsrv32.exe.
Voilà pour la partie VB6, nous avons un ActiveX qu’il va falloir maintenant appeler dans un projet web écrit en c#.

Appeler un ActiveX VB6 en C#.

Quel est le problème ?

En fait, il s’est posé lorsqu’il m’a été demandé de le faire. Le but ici est d’utiliser "Server.CreateObject" et de renseigner les propriétés de l’ActiveX et d’appeler ses méthodes sans l’ajouter dans les références du projet .NET.
J’ai donc cherché sur internet pour trouver à peu près le même résultat à chaque fois : contourner le problème en écrivant la page qui appelle l’ActiveX en VB.NET !

Pourquoi ?

En VB ou VB.NET il est possible de faire ceci :

    Object x = Server.CreateObject("Object.Class")
    x.UserName ="sup"
    x.Password =""
    x.Connect("CWT","data",@"servernameClient Data")
C’est-à-dire créer un objet avec "Server.CreateObject", renseigner les propriétés ou appeler les méthodes directement.
Par contre en C#, ce n’est pas possible. "x" sera de type "object" et ne contient évidemment que les quatre méthodes habituelles.

Le projet.

Je vais commencer par créer un nouveau projet de type "Application Web ASP.NET".

J’y insère un nouveau "Web Form"q ue je nomme "Default.aspx" et qui se présente ainsi :

Les différents control vont permettre d’obtenir des valeurs à passer à notre ActiveX.

Remarque importante : vous devez ajouter à la balise "Page" du "Web Form" l’attribut AspCompat="True". Il autorisera l’appel à l’ActiveX.

Comment faire ?

Je vais donc utiliser "Server.CreateObject" pour obtenir une instance de mon ActiveX (remarquez la désignation du module de classe "Dessin" comme point d’entrée) :

   // appel de l’ActiveX
   object oDessin = Server.CreateObject("ArticleAppelActiveX.Dessin");

Puis je récupère le "System.Type" de "oDessin" :

   // récupération de son type
   Type tDessin = oDessin.GetType();

Puis j’utilise sur "tDessin" la méthode "InvokeMember" pour renseigner les propriétés :

   // les propriétés sont renseignées en utilisant le type de l’ActiveX et le namespace System.Reflection
   tDessin.InvokeMember("CheminImage", System.Reflection.BindingFlags.SetProperty, null, oDessin, new object[] { CheminImage } );

Ou les méthodes :

   // toujours avec le type et le namespace System.Reflexion on appelle la méthode de dessin
   // la méthode InvokeMember renvois un object, résultat de l’appel
   object oResultat = tDessin.InvokeMember("DessinerAvecProprietes", System.Reflection.BindingFlags.InvokeMethod, null, oDessin, new object[] { } );

Dans les deux cas c’est le "BindingFlags" qui détermine ce qu’on veut faire : renseigner une propriété ou appeler une méthode.

Lorsque l’on veut passer une ou des valeurs à l’ActiveX, il faut utiliser le cinquième paramètre de "InvokeMember". Il s’agit d’un tableau d’objets dans lequel il convient de mettre la ou les valeurs à faire passer.
Vous en trouverez l’illustration derrière le bouton "Utiliser méthode avec paramètres".
"InvokeMember" retourne un "object" qui contient, s’il y a lieu la valeur de retour de l’élément appelé, ce qui me permet de récupérer ici le nom de l’image générée par l’ActiveX :

   // si oResultat est bien ce que l’on attent
   // la propriété BackImageUrl du panel est modifié
   if ( oResultat != null && oResultat is String )
   {
      this.Panel1.BackImageUrl ="~/Images/"+ (string)oResultat;
   }

Le contrat est rempli, je vous ai montré comment appeler GDI+ en VB6. Et comment appeler un ActiveX en C# dans un projet web. Bien évidemment l’exemple est succinct et il vous appartient de l’enrichir selon vos besoins.

A lire aussi sur Devparadise.com :
  • Message de confirmation sur un DataGrid via le code Behind
  • Comment ouvrir un pop-up après validation d’un formulaire par les contrôles d...
  • Illustration de l’héritage de classe et de l’implémentation d’interface en c#...
  • La sérialisation (Marshaling) en XML en C# .Net 2.0
  • Création d’une DLL en C# .Net 2.0
  • A télécharger aussi sur Devparadise.com :
  • SOURCE : Message de confirmation sur un DataGrid via le code Behind
  • Comment ouvrir un pop-up après validation d’un formulaire par les contrôles d...
  • SOURCES : Création en VB6 d'une DLL ActiveX utilisant GDI+, et appel de cette...
  • Source de l'article sur l’héritage de classe et de l’implémentation
  • Code Source : sérialisation (Marshaling) en C# .Net 2.0

  • © 1997-2009 tous droits réservés Devparadise.com
    Les logos, et marques déposées sont la propriété de leurs détenteurs respectifs.
    Devparadise.com s'est engagé à respecter la confidentialité des données personnelles régies par la loi 78-17 du 6 janvier 1978.
    Déclaration C.N.I.L. n° 621623
    DLL,ActiveX,VB,Visual Basic 6,.Net,C#,GDI+,ASP .Net,ASP.Net,Reflexion,appel