Rechercher
 
Retour accueil Visual Basic 6.0

Création de contrôles ActiveX en Visual Basic 6.0

Introduction

Nous allons, dans cet article, étudier comment mettre en oeuvre un contrôle ActiveX à l'aide de l'environnement de développement Visual Basic 6.0. Pour ce faire, nous allons commencer par introduire les concepts de composants COM et de contrôles ActiveX. Nous allons aussi voir que ces spécifications reposent sur l'utilisation de la base de registre.

Ensuite nous commencerons par coder un contrôle élémentaire. Celui-ci aura pour objectif d'afficher l'heure courante au niveau de la feuille qui va l'héberger. Puis au fur et à mesure, nous y rajouterons des possibilités supplémentaires : définition de propriétés, de méthodes puis d'événements. Puis nous finirons par conclure.

Les composants COM

Le modèle COM (Component Object Model), présent sur l'architecture Windows, est une technologie très performante. En effet, cette spécification, indépendante d'un langage de programmation quelconque, définie comment vous allez pouvoir coder un composant (un bout de code) que vous pourrez réutiliser à l'infini dans vos programmes. En tout cas, si l'environnement de développement que vous utilisez est compatible avec cette spécification.

En fait, COM n'a pas réellement d'impacte sur votre façon de coder en Visual Basic. COM spécifie comment réaliser un appel de fonction à partir d'un langage vers un autre. Effectivement, l'appel de fonction peut poser des problèmes : si nous prenons par exemple le type entier, il utilise deux octets en Visual Basic alors qu'il en utilise quatre en C++. Comment à partir de là faire un appel en Visual Basic d'une fonction coder en C++ si cette dernière prends un paramètre entier ? La solution réside dans les différents compilateurs du pack Visual Studio, notamment. En effet, chaque compilateur peut respecter COM (c'est vous qui choisissez), en terme de génération de code. Dans ce cas, cette spécification lisse les choses entre les différents langages utilisés.

De base, la plate-forme Windows propose plusieurs composants COM. Ils sont souvent massivement utilisés par le système d'exploitation lui même, mais vous pouvez aussi les utiliser dans vos propres applications. Pour ce faire, je vous conseille vivement de trouver une documentation sur les différents composants disponibles. La référence, en terme de documentation, est le MSDN Library qui distribué par Microsoft trimestriellement en DVD. Le MSDN Library est aussi consultable en ligne à l'adresse http://msdn.microsoft.com/library.

Les contrôles ActiveX

Les contrôles ActiveX sont en fait des composants COM proposant des particularités supplémentaires. En effet, pour utiliser un composant COM vous devez "mettre les mains à la pâte" et donc coder. Un contrôle ActiveX facilite sérieusement son utilisation en le rendant visuellement manipulable par l'atelier de développement utilisé. En Visual Basic, vous pouvez poser tout contrôle ActiveX sur votre feuille. Vous changez ses propriétés via le panneau de propriétés et vous codez facilement un gestionnaire d'événement (la plupart du temps en double-cliquant simplement sur le composant).

Mais attention ! Etre visuellement manipulable dans un atelier de développement ne veux pas forcément dire que le contrôle sera visible à l'exécution. Il existe effectivement des contrôles non visibles à l'exécution : le contrôle Timer par exemple.

Généralement, le code des contrôles ActiveX se trouve dans un fichier d'extension ".ocx". Il s'agit en fait d'elle DLL classique (Dynamic Linking Library).

La base de registre Windows

Dans les deux cas (composants COM ou contrôles ActiveX) la base de registre est fondamentale. C'est à partir d'elle qu'un programme peut savoir ou se trouve le code du composant à utiliser. En effet, votre programme identifie le composant COM via un numéro unique : le CLSID (CLasS IDentifier). La base de registre contient tous les CLSID des composants utilisés par votre machine et pour chaque CLSID, un ensemble de données sont mémorisées (localisation de l'exécutable, ...).

Dans la base, un composant COM est aussi identifiable via un autre identificateur : le PROGID (PROgrammatic IDentifier). La valeur de cet identificateur est bien plus mémorisable que le CLSID. A titre d'exemple, regardez la capture d'écran suivante : on y trouve le ProgID "Infini.Clock" et le CLSID "B3A5F463-EBD7-487E-B737-D2B772908D0F"

Visual Basic, vous aide un peu à ce niveau, en tout cas sur le poste de développement. En effet : pour qu'un composant COM soit utilisable, faut t'il qu'il soit inscrit dans cette base. Un outil vous permet d'inscrire un fichier ocx dans la base de registre : regsvr32.exe. Il s'avère que son utilisation et assez simple, mais Visual Basic l'utilise à votre place dés la compilation du contrôle. Cela vous simplifie la vie, mais ne perdez pas de vu que l'enregistrement du composant sur la machine est une condition sine qua non.

Mise en oeuvre d'un contrôle ActiveX simple

Nous allons maintenant rentrer dans le vif du sujet et nous intéresser à la conception du contrôle ActiveX. Pour ce faire, nous allons utiliser l'atelier Visual Basic, qui va grandement nous assister. Nous allons aussi voir comment tester notre contrôle ActiveX, par l'intermédiaire d'un autre projet. Une fois les choses mises en oeuvre, nous verrons comment générer le fichier ocx afin que le contrôle puisse être utilisé dans un autre environnement.

Création du projet de contrôle ActiveX

La première chose qui nous faut réaliser c'est donc de créer le projet qui va contenir notre (ou nos) contrôle(s). Par défaut, quand vous lancez Visual Basic, une boîte de dialogue apparait et vous propose plusieurs modèles de projets. Si ce n'est pas le cas, cliquez dans le menu "Fichier" sur "Nouveau Projet". La capture d'écran suivante montre cette boîte de dialogue.

Le modèle de projet qui nous intéresse est donc le projet de contrôle ActiveX. Cliquez sur ouvrir après l'avoir choisit. Dans une certaine mesure, ce type de projet ressemble à un projet de type "Exe Standard". En effet, vous allez pouvoir éditer votre contrôle via deux outils : le concepteur visuel et l'éditeur de code. Mais une différence apparait malgré tout : dans le concepteur graphique, votre contrôle n'a pas de détourage autour de sa zone visuel comme l'aurait une feuille. Cela est normal : l'objectif du contrôle c'est d'être utilisé dans une feuille. Il aura donc juste un espace rectangulaire comme le montre la capture d'écran suivante.

Vous pouvez ensuite remplir l'espace de votre contrôle avec des sous-contrôles : on parle alors de contrôles constitutifs. La partie visuelle de notre contrôle va contenir : un contrôle de type Frame pour le look, et Label (placé dans le Frame) pour afficher l'heure et un contrôle Timer pour actualiser régulièrement l'heure dans le Label. Nommez respectivement vos contrôles fraClock, lblClock et tmrClock. Affectez aussi à la propriété Interval du Timer la valeur 1000 (l'unité étant la milli-seconde, nous avons donc 1 seconde d'intervalle). Au final, votre contrôle (en mode conception) devrait ressembler à la capture d'écran suivante.

Une chose importante est à ne pas oublier : il faut renommer le projet et le contrôle. En effet, Visual Basic génère le ProgID (voir plus haut) en fonction de ces deux noms. Dans l'exemple proposé, le nom du projet est "Infini" et l'unique contrôle de ce projet est nommé "Clock". Le ProgID de ce composant sera donc "Infini.Clock". Ajoutez aussi le code suivant pour permettre la mise à jour de l'heure dans le Label. Vous pouvez aussi, sur le projet, changer la propriété ToolboxBitmap : elle permettra d'afficher l'icône souhaitée lorsque votre contrôle devra être insérer dans la boîte à outils.

Option Explicit

'-Mise à jour du label d'affichage de l'heure-----------------------
Private Sub tmrSeconds_Timer()
    lblClock.Caption = Time
End Sub

'-Code de retaillage de l'horloge-----------------------------------
Private Sub UserControl_Resize()
    fraClock.Width = UserControl.Width
    fraClock.Height = UserControl.Height
    
    lblClock.Width = UserControl.Width
    lblClock.Top = (UserControl.Height - lblClock.Height) / 2 + 100
End Sub

'-Initialisation de la valeur du label au premier affichage---------
Private Sub UserControl_Show()
    tmrSeconds_Timer
End Sub

Ajout du projet de test

Nous allons maintenant ajouter un projet secondaire. En effet, Visual Basic gère la notion de groupe de projet. Pour ce faire, allez dans le menu "Fichier" et cliquez sur "Ajouter un projet". Le type de projet à ajouter est "Exe standard". La capture d'écran suivante montre l'explorateur de projets après l'ajout. Notez aussi que, comme les deux projets font parties du même groupe de projet, l'icône du contrôle ActiveX apparait lorsque que vous éditez la feuille du projet de test.

A partir de maintenant, vous pouvez poser vos contrôles sur la feuille de test. La capture d'écran suivante montre ce qu'affiche la feuille de test contenant un contrôle d'horloge. Notez que d'autres contrôles (deux boutons) sont aussi ajoutés. Ils pourront ultérieurement nous servir pour réaliser quelques tests sur le comportement du contrôle.

Enregistrement du contrôle ActiveX

Arrivé à ce stade, on pourrait croire que le principal est fait. Il en est rien ! En effet, pour l'heure, votre contrôle ActiveX n'hexite pas réellement. Certes, il apparait dans la boîte à outils, mais cela est fait par ce les deux projets sont intégrés dans le même groupe de projets. Pour pouvoir utiliser votre contrôle dans un autre projet, sans forcément disposer du code source, il vous faut compiler votre code pour générer le fichier ".ocx". Ensuite, il vous faut enregistrer votre (ou vos) composant(s) dans la base de registre Windows.

Tant que vous êtes sur le poste de développement les choses sont plus simples qu'il n'y parait : en effet, le fait de compiler le projet via l'environnement Visual Basic, enregistrement automatiquement le contrôle dans la base. Si par contre, vous êtes sur une autre machine et que vous n'avez que le fichier ".ocx" à votre disposition il va falloir réaliser l'enregistrement à la main, via l'outil "regsvr32.exe". Pour ce faire, prenez une console, placez-vous dans le répertoire contenant votre fichier ".ocx" et tapez la command "regsvr32 file.ocx" (ou file.ocx représente le nom de votre fichier).

L'outil d'empaquetage et de déploiement fournit avec Visual Basic permet de gérer un programme d'installation, qui heureusement saura installer les contrôles automatiquement sur le poste client. Il ne sera donc plus utile de lancer la commande "regsvr32.exe" manuellement.

Définition de propriétés

Jusqu'à présent, nous avons vu comment créer un contrôle ActiveX simple. Mais dans la majorité des cas, ce que nous venons de voir ne suffira pas. Vos contrôles auront besoin d'exposer vers l'extérieur plus de choses : des propriétés, des méthodes et des événements. Dans un premier temps nous allons voir comment ajouter des propriétés à vos contrôles.

Ajout d'une propriété

Pour ajouter une propriété à une classe, en Visual Basic, il vous faut utiliser les instructions Property Get et Property Let. Ce que vous définissez via la construction Property Get est en fait proche d'une fonction qui a pour but de renvoyer la valeur de la propriété. La construction Property Let correspond à une procédure ayant pour but de modifier la valeur de la propriété.

Afin d'y voir plus clair, nous allons ajouter une propriété à notre contrôle d'horloge. Cette propriété permettra de contrôler le délai de réaffichage de notre contrôle. Nous choisissons d'appeler cette propriété "Interval" et nous utiliserons comme unité de mesure la seconde. En fait, nous avons déjà quelque chose de similaire dans notre contrôle. En effet, notre contrôle possède un contrôle constitutif de classe Timer. Mais de l'extérieur (dans le projet de test), nous n'avons plus de moyen de contrôler cet élément. Le code suivant rajoute donc la propriété attendue.

Public Property Get Interval() As Integer
    Interval = tmrSeconds.Interval \ 1000
End Property

Public Property Let Interval(value As Integer)
    If value < 1 Then
        MsgBox "Interval must be positive !", vbExclamation
        value = 1
    End If
    tmrSeconds.Interval = value * 1000
End Property

Une fois la propriété définie, fermez toutes les fenêtres liées au contrôle et reprenez la feuille du projet de test. Notez que la propriété Interval est maintenant disponible sur notre contrôle.

Une chose importante est à noter. Si votre propriété n'est pas d'un type simple (Integer ou Single par exemple), mais si au contraire elle permet de manipuler un objet alors il ne vous faudra pas utiliser la construction Property Let mais plutôt la construction Property Set. Pour le reste, il n'y pas d'autres différences.

Mais un problème apparait alors ! Vous pouvez, dans la feuille de test, configurer votre contrôle et donc changer la valeur de sa propriété de rafraichissement. Malheureusement, si vous fermez la fenêtre et que vous la rouvrez dans l'atelier, vous vous apercevrez que la valeur n'a pas été conservée. Cela est tout à fait normal : il nous faut encore coder quelques petites choses pour que la valeur de la propriété soit persistante.

Persistance des propriétés

Pour que dans l'éditeur de feuille, les valeurs des propriétés d'un contrôle ActiveX soient conservées, il vous faut coder deux gestionnaires d'événements dans votre contrôle. Ces deux gestionnaires sont UserControl_ReadProperties et UserControl_WriteProperties. Dans le deux cas, un paramètre de type PropertyBag vous est fournit. Ce paramètre permet la lecture et la sauvegarde des vos valeurs dans certains fichiers de votre projets, lors de la conception. Ce même objet permet à l'exécution de charger les valeurs initiales du contrôle.

Le bout de code suivant vous montre comment rendre persistante la valeur de notre propriété Interval sur notre horloge. Si votre contrôle possède plus qu'une propriété, il ne vous faudra pas coder d'autres gestionnaires d'événements, mais seulement rajouter autant de lignes de code que de valeurs de propriétés. En effet, n'oubliez pas que les deux gestionnaires de code sont rattachés non pas à une propriété, mais bien au contrôle lui-même.

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    Me.Interval = PropBag.ReadProperty("Interval", 1)
End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    PropBag.WriteProperty "Interval", Me.Interval, 1
End Sub

Définition de méthodes

Un contrôle ActiveX peut aussi exposer des méthodes. Une méthode est en fait une fonction (ou une procédure, si aucune valeur de retour n'est calculée) qui s'invoque obligatoirement sur un objet. Tout comme pour les propriétés, la méthode doit être qualifiée de publique pour pouvoir être utilisée de l'extérieur.

A titre d'exemple, nous allons coder deux méthodes qui auront pour but de suspendre et de reprendre l'activité de votre horloge. Ces méthodes seront respectivement appelée StopClock et StartClock. Voici le code de ces deux méthodes. Deux boutons peuvent être utilisés sur la feuille de test pour valider le bon fonctionnement de ces deux méthodes.

'-Cette méthode permet de (re)démarrer l'horloge--------
public Sub StartClock()
    tmrSeconds.Enabled = True
End Sub

'-Celle-ci permet de stopper l'horloge------------------
Public Sub StopClock()
    tmrSeconds.Enabled = False
End Sub

Définition d'événements

Considérons un contrôle de type CommandButton. Il expose aussi un autre type de chose : des événements, dont le plus connu est certainement le click. En fait un gestionnaire d'événement est une méthode. La différence c'est qu'il est appelé automatiquement par le runtime (l'exécutif) Visual Basic. Mais pour pouvoir coder un gestionnaire d'événement sur un objet, faut t'il que la classe (le type) définisse au moins un événement.

Pour définir un nouvel événement sur votre contrôle, il vous faut utiliser la construction Event. L'événement doit aussi être déclaré en public et il peut prendre des éventuels paramètres. Cette déclaration doit obligatoirement être faîte dans la partie déclaration de votre module de code. Mais cela ne suffit pas, il faut aussi coder dans votre contrôle les moments ou l'événement va déclencher.

'-Définition d'un événement déclenchant chaque minute----------
Public Event NewMinute(value As Integer)

'-Mise à jour du label d'affichage de l'heure------------------
Private Sub tmrSeconds_Timer()
    lblClock.Caption = Time
    If Second(Time) = 0 Then RaiseEvent NewMinute(Minute(Time))
End Sub

L'exemple de code qui suit, le dernier de cet article, vous montre comment l'événement est capturé, dans le code de la feuille contenant le contrôle ActiveX. N'oubliez pas que dans l'éditeur de code Visual Basic, deux listes déroulantes sont proposées dans la partie supérieure de la fenêtre : elles servent à générer les gestionnaires de code.

Private Sub clkTime_NewMinute(value As Integer)
    lblStatus.Caption = "The minute is " & value
End Sub

Conclusion

Nous avons donc vu qu'en Visual Basic, il est simple de pouvoir coder un contrôle ActiveX réutilisable. Comme ce contrôle respecte la spécification COM, il peut même être réutilisé dans l'environnement Visual J++, Visual C++ ou tout autre outil de développement supportant COM.

Nous avons ensuite vu qu'il est possible d'enrichir les possibilités de votre contrôle en rajoutant des propriétés, des méthodes et des événements. Si vous souhaitez récupérer l'intégralité de ce contrôle ActiveX, Activez ce lien pour en télécharger le fichier ZIP.

Si vous souhaitez voir un autre exemple de contrôles ActiveX, un petit peu plus riche, je vous conseil de télécharger le projet de contrôles d'éditions. N'hésitez pas non plus, à m'envoyer vos commentaires et vos suggestions à propos de cet article : cela m'aide à faire évoluer les choses.

Retour accueil Visual Basic 6.0