|
|
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 dexpliquer comment appeler GDI+ en VB6 pour manipuler une image et écrire un texte à linté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 sinterfacer sur GDI+;
- 1 utilisé comme point dentrée de lActiveX.
- 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 dentrée de lActiveX.
Il contient 5 propriétés :
- "CheminImage" : elle recevra le chemin vers le dossier qui contiendra limage que je vais utiliser comme modèle pour écrire mon texte;
- "NomImageModele" : elle recevra le nom de limage que je veux utiliser comme modèle;
- "NomFont" : elle recevra le nom de la police de caractère avec laquelle je veux écrire dans limage;
- "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 dun peu plus près, elle naccepte pas de paramètres, et cest ici que je vais déclarer les objets qui vont me permettre de créer limage que lon attend.
Par exemple lobjet "GdipBitmap" qui va récupérer limage 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 limage et à appeler la précédente fonction pour retourner son résultat.
Les modules de classes permettant daccéder à GDI+.
On les appelle aussi "Wrapper". Vous en trouverez 6 dans ce projet. Je vous les présente dans lordre dapparition à lintérieur de la fonction DessinerAvecProprietes :
- "GdipBitmap" : elle va me permettre de créer dans GDI+ un "Bitmap" à partir du chemin vers limage qui me servira de modèle et den 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 lhé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, cest 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 den 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 den récupérer le pointeur;
- "GdipSolidBrush" : elle va me permettre de créer dans GDI+ une "SolidBrush" à partir de la propriété "MaCouleur" et den récupérer le pointeur;
Leur implémentation est volontairement partielle par soucis de clarté. Vous trouverez en fin darticle les liens vers les sites qui mont permis de les réaliser.
Pour les explications je vais prendre lexemple de "GdipBitmap". Les autres sont construits sur le même principe.
Tout dabord le code qui va me permettre de créer un bitmap à partir dun 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 quelle se trouve dans la librairie "gdiplus", quelle accepte deux paramètres ("filename" de type "String" et "bitmap" de type "Long") et quelle retourne une valeur de type "GpStatus".
"filename" : représente le chemin daccè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 derreur retournés par GDI+.
Jai 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 derreur et de récupérer mon pointeur pour en faire une propriété de mon objet.
Voilà pour le principe de lappel à GDI+, utiliser les pointeurs quil nous retourne.
Que fait-on du projet ?
Ce projet va être compilé sous forme dune dll quil sera possible denregistrer sur un serveur en utilisant regsrv32.exe.
Voilà pour la partie VB6, nous avons un ActiveX quil 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 sest posé lorsquil ma été demandé de le faire. Le but ici est dutiliser "Server.CreateObject" et de renseigner les propriétés de lActiveX et dappeler ses méthodes sans lajouter dans les références du projet .NET.
Jai 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 lActiveX 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")
Cest-à-dire créer un objet avec "Server.CreateObject", renseigner les propriétés ou appeler les méthodes directement.
Par contre en C#, ce nest 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".
Jy insère un nouveau "Web Form"q ue je nomme "Default.aspx" et qui se présente ainsi :
Les différents control vont permettre dobtenir des valeurs à passer à notre ActiveX.
Remarque importante : vous devez ajouter à la balise "Page" du "Web Form" lattribut AspCompat="True". Il autorisera lappel à lActiveX.
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 dentrée) :
// appel de lActiveX
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 jutilise sur "tDessin" la méthode "InvokeMember" pour renseigner les propriétés :
// les propriétés sont renseignées en utilisant le type de lActiveX 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 lappel
object oResultat = tDessin.InvokeMember("DessinerAvecProprietes", System.Reflection.BindingFlags.InvokeMethod, null, oDessin, new object[] { } );
Dans les deux cas cest le "BindingFlags" qui détermine ce quon veut faire : renseigner une propriété ou appeler une méthode.
Lorsque lon veut passer une ou des valeurs à lActiveX, il faut utiliser le cinquième paramètre de "InvokeMember". Il sagit dun tableau dobjets dans lequel il convient de mettre la ou les valeurs à faire passer.
Vous en trouverez lillustration derrière le bouton "Utiliser méthode avec paramètres".
"InvokeMember" retourne un "object" qui contient, sil y a lieu la valeur de retour de lélément appelé, ce qui me permet de récupérer ici le nom de limage générée par lActiveX :
// si oResultat est bien ce que lon 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 lexemple est succinct et il vous appartient de lenrichir 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
|
|