Création d'un ActiveX via un contrôle Microsoft .net
La plateforme Microsoft .net est suffisamment riche pour permettre de créer des contrôles très évolués tels que des calendriers ou des graphiques de gestions.
L'intégration d'un contrôle utilisateur .net dans Oxygène se fait via un ActiveX et la communication entre les deux parties repose sur les liens COM.
Cette documentation explique pas à pas comment créer un ActiveX en C# pour Oxygène.
Bien sûr Oxygène supporte tout type d'ActiveX respectant la norme et donc quels que soient la technologie et le langage utilisés pour créer l'ActiveX.
NB : Un exemple complet est disponible dans oxydev\Exemples\OxChart
1. Créer un projet d'ActiveX avec Visual Studio
2. Enregistrement de l’ActiveX
1. Créer un projet d'ActiveX avec Visual Studio
- Ouvrir Visual Studio.
- Aller dans Fichier > Nouveau > Projet.
- Dans Type de projet, sélectionner Visual C# et le modèle Bibliothèque de classes.
- Mettre le nom de votre projet (par exemple ChoixDate) et valider.
Utiliser la classe de base de Memsoft pour créer un ActiveX
Memsoft fournit une classe de base qui allège la création d'un ActiveX (qui implémente déjà une interface de InteropServices, les services de communication COM).
Deux méthodes sont possibles pour l'utiliser :
Méthode 1 : en ajoutant en référence notre assembly DNetHost (conseillée)
- Aller dans Projet > Ajouter une référence
- Cliquer sur Parcourir
- Sélectionner le fichier C:\Program Files (x86)\Common Files\Memsoft\DNetHost.dll
Methode 2 : en copiant le fichier source C# dans votre solution
- Copier le fichier [OXYDEV]\Exemples\GraphT\BaseDNetHost.cs dans le répertoire de votre projet
- Aller dans Projet > Ajouter > Elément existant et sélectionner le fichier BaseDNetHost.cs
Créer la classe contrôle utilisateur final
On peut dès à présent créer la classe / l’objet souhaité en ajoutant des propriétés pour la communication COM.
Cette classe héritera de la classe de base évoquée précédemment.
- Aller dans Projet > Ajouter > Nouvel élément
- Dans Type d'élément sélectionner Contrôle utilisateur (ou Classe si votre ActiveX n'a pas d'interface graphique).
La documentation qui suit se fera en prenant exemple sur un composant graphique nommé ChoixDate qui permet d'afficher un petit calendrier.
Propriété de la classe
- Ajouter en entête de fichier : using DNetHost;
Déclarer que la classe dérive de BaseDNetControl (remplacer UserControl si présent).
Ajouter les propriétés COM à la classe en mettant bien votre propre Prog Id et votre propre GUID.
Le prototype de la classe devrait ressembler à ceci :
[ComVisible(true)]
[ProgId("TestAX.ChoixDate")]
[Guid("16DFADAD-******************")]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class ChoixDate : DNetHost.BaseDNetControl
Remplacez bien le Guid par un nouveau. C’est un identifiant qui doit être unique. Vous pouvez créer un nouvel identifiant avec l’outil de Visual Studio disponible dans Outils > Create GUID. Modifiez le ProgId ; c’est sous ce nom qu’on trouvera notre contrôle dans la liste des ActiveX dans Oxygène.
Ajout du code « métier » (création du contrôle graphique)
Il ne reste plus qu’à écrire le code du traitement souhaité. Dans notre cas, il faut créer le contrôle graphique dont le code peut être récupéré en le dessinant dans un projet temporaire.
private DateTimePicker datePicker;
public ChoixDate()
{
// Lancé par le constructeur de BaseDNetControl
//InitializeComponent();
}
override protected void InitializeComponent()
{
datePicker = new
DateTimePicker();
this.SuspendLayout();
//
this.datePicker.Location
= new System.Drawing.Point(0, 0);
this.datePicker.Name
= "Calendrier";
this.datePicker.Size
= new System.Drawing.Size(200, 20);
this.datePicker.TabIndex
= 0;
//
this.Controls.Add(this.datePicker);
this.Name = "CalendrierConteneur";
this.Size = new System.Drawing.Size(200,
20);
this.ResumeLayout(false);
}
Finalisation de la classe
Vous pouvez à présent tenter une compilation. Vous aurez probablement des erreurs au début si il manque des références. N'hésitez pas à profiter de Intellisense qui propose automatiquement les références manquantes (boîte déroulante sous le soulignement rouge).
Vous pouvez modifier AssemblyInfo.cs pour personnaliser votre ActiveX.
A ce stade le composant graphique fonctionnera et pourra être affiché dans un écran Oxygène dès que vous l’aurez enregistré.
Mais si votre composant doit envoyer des informations à Oxygène (par exemple une action utilisateur), il reste l’étape de gestion des évènements.
Vous pouvez ainsi personnaliser les propriétés de votre contrôle dans la fonction InitializeComponent(). Et vous pouvez ajouter autant de fonctions que vous souhaitez, elles seront visibles par Oxygène pour peu quelles soient déclarées public. Cependant la communication par les liens COM utilisant des types simples tel que Chaine / string, il vous faudra faire des fonctions de traduction pour manipuler les objets complexes .net. Voir le chapitre concernant la Technologie COM.
2. Enregistrement de l’ActiveX
Un ActiveX est un composant indépendant et visible par tous les programmes. Pour être visible, il faut l’enregistrer, c'est-à-dire le déclarer à Windows.
Sur la machine de compilation
Sur la machine de compilation, l’enregistrement de l’ActiveX peut se faire simplement lors de la compilation.
Aller dans les propriétés du projet, onglet Générer et cocher Inscrire pour COM Interop.
Si la compilation échoue, essayez en lançant Visual Studio avec "Exécuter en tant qu'Administrateur".
Sur les postes utilisateurs
Voici un exemple en utilisant l’outil de création d’installateur de Visual Studio :
Ajouter un nouveau projet de modèle Projet d’installation (dans le type Autres types de projet > Configuration et déploiement)
Clic droit sur le projet : Ajouter Sortie de projet et sélectionner la Sortie principale de notre projet ActiveX
Dans le projet Setup, sur la ligne nommée Sortie principale de … (Actif), faire un clic droit et aller dans les Propriétés
Dans la propriété Register, mettre la valeur vsdrpCOM
Définir le Dossier d’application (i.e. chemin d’installation)
Autre méthode :
copier sur le poste client le fichier regasm.exe disponible sur la machine de développement
sur le poste client, exécuter la commande :
regasm.exe "[chemin de la dll]"
3. Gestion des évènements
Si on souhaite que l’ActiveX envoie des données à Oxygène lors des actions de l’utilisateur (chose classique pour un contrôle graphique), il faut ajouter une gestion des évènements. C’est une partie plus complexe que nous n’expliquerons pas en détail.
Pour chaque nouvel évènement, il faudra répéter presque toutes les étapes suivantes.
Création d’un délégué, nouveau type pour l’évènement
A la fin du fichier ajouter :
[ComVisible(false)]
public delegate void ValueChangedEventHandler(DateTime date);
Déclaration de l’évènement
Dans la classe ChoixDate, ajouter :
[Category("Action")]
public event ValueChangedEventHandler ValueChanged;
Méthode déclenchant l’évènement
Dans la classe ChoixDate, ajouter:
private void datePicker_ValueChanged(object sender, EventArgs
e)
{
OnValueChanged(sender,
e);
}
protected void OnValueChanged(object sender, EventArgs e)
{
if (ValueChanged !=
null)
ValueChanged(datePicker.Value);
}
Abonnement du contrôle à l’évènement
Dans la classe ChoixDate, ajouter dans le membre InitializeComponent :
this.datePicker.ValueChanged += new System.EventHandler(this.datePicker_ValueChanged);
Création des fonctions pour l’interface COM
A la fin du fichier, ajouter ceci et personnaliser le GUID.
[ComVisible(true)]
//TODO: changer ce GUID (menu Outils>Create GUID)
[Guid("1BA2D98F-A7FF-479c-8219-980B18A7029E"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IChoixDateEvents
{
[DispId(1)]
void ValueChanged(DateTime date);
}
Pour ajouter des évènements, il faut ajouter des fonctions. Exemple :
[DispId(2)]
void VisibleStateChanged(int visible);
Attribut COM pour la classe
Ajouter aux attributs de la classe ChoixDate (opération à ne faire qu’une seule fois) :
[ComSourceInterfacesAttribute(typeof(IChoixDateEvents))]