Ce tutoriel (article) met en avant, au travers d'un exemple simple et concret, la facilité d'extension du menu des applications Office 2007 avec Visual Studio Tools for Office 2005 Second Edition.
Cet article a initialement été publié dans le numéro 92 (Décembre 2006) du magazine Programmez! (http://www.programmez.com/magazine.php?num_magazine=92)
La suite Office 2007 vient de faire son apparition en version finale, accompagnée de son nouveau menu appelée « Ribbon », francisé pour l'instant en « ruban ». Comme les menus des précédentes versions d'Office, Il est complètement extensible et personnalisable, vous permettant de rajouter des actions écrites en .NET interagissant avec vos documents. Les documents office ayant évolués sur un format XML, les méthodes de personnalisations s'appuient en grande partie sur celui-ci au travers de deux méthodes :
Le but de cet article est de présenter la personnalisation du Ruban grâce à la création d'un Add-in COM pour Microsoft Office Word 2007, le tout au travers d'un exemple simple. Le Ruban devra permettre aux utilisateurs de sélectionner un nombre dans n'importe quel un document Word et de convertir celui-ci d'une devise monétaire vers une autre, le choix de la conversion étant paramétrable directement au niveau du Ruban. Vu que le calcul du taux de conversion évolue quotidiennement, celui-ci s'appuiera sur un service Web public afin d'être correct en temps réel.
Une fois la version finale de Visual Studio Tools for Office 3 SE installée, la première étape consiste en la création d'un projet d'extensibilité de type « Shared Add-in ». Le modèle de celui-ci se trouve dans la catégorie « Other Project Type » puis « Extensibility ». Après que le nom du projet et son répertoire aient été sélectionnés, un assistant permet de pré-paramétrer l'Add-in : choix du langage (C# pour cet exemple), choix de l'application pour laquelle l'Add-in doit fonctionner (Microsoft Word uniquement dans ce cas), le couple nom/description définissant celui-ci et enfin ses paramètres d'installation (multi utilisateurs) et de chargement (automatique lorsque l'application hôte démarre ou non).
Une fois l'assistant terminé, une solution contenant le projet d'Add-in à proprement parlé est créé. Celle-ci contient aussi un programme d'installation déjà configuré, permettant de déployer le fruit de vos efforts sans perte de temps.
Le projet d'Add-in contient une classe « Connect », coeur de son fonctionnement, représentant l'objet à implémenter pour ajouter des fonctionnalités notamment lorsque celui-ci démarre ou est arrêté. Le but étant ici de personnaliser le Ruban, la première chose à faire de notifier l'application hôte de ce choix en implémentant l'interface IRibbonExtensibility présente dans le namespace « Microsoft.Office.Core ».
[GuidAttribute("3CA05C71-46E5-4DCC-BF7C-510E47650A26"), ProgId("ProgrammezDemoAdd-in .Connect")] public class Connect : Object, Extensibility.IDTExtensibility2, IRibbonExtensibility
Cette interface définit une seule méthode nommée « GetCustomUI » qui à pour but de spécifier l'endroit et la manière pour accéder au contenu XML définissant le Ribbon.
string IRibbonExtensibility.GetCustomUI(string RibbonID) { Assembly asm = Assembly.GetExecutingAssembly(); foreach (string name in asm.GetManifestResourceNames()) { if (name.EndsWith("customUI.xml")) { System.IO.TextReader tr = new System.IO.StreamReader(asm.GetManifestResourceStream(name)); string resource = tr.ReadToEnd(); tr.Close(); return resource; } } return null; }
Dans cet exemple le fichier XML se nomme donc « customUI.xml » et est présent dans l'assemblage en temps que ressource incorporée (Build Action = Embedded Resource). Le contenu de celui-ci est extrait au travers d'un Stream et renvoyé sous forme de chaine de caractère tel que la signature de la méthode « GetCustomUI » le requiert.
La définition de la composition du Ruban peut donc être externalisée dans un fichier XML, celui-ci décrivant chaque section et chaque contrôle de manière beaucoup plus simple que uniquement en code tel que c'étais le cas dans la version précédente. Toute la mise en forme se définit à ce niveau : Quels éléments la section du ruban doit contenir, comment les grouper, quelle doit être la taille de chaque icône.
Il existe une quinzaine de contrôles d'affichage visuel de base, de l'essentiel bouton à la galerie d'images en passant par les habituelles TextBox, liste déroulante et autres éléments de saisie. Chacun de ces contrôles dispose d'attributs permettant de le configurer :
Dans cet exemple, le but est de posséder deux zones :
ne deuxième zone intitulée « Group2 », contenant uniquement le bouton déclenchant l'action de conversion de la valeur sélectionnée.
<?xml version="1.0" encoding="utf-8" ?> <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"> <ribbon> <tabs> <tab id="ProgrammezTab" label="Programmez"> <group id="Group1" label="Données"> <editBox id="EditBoxDe" getText="GetDeviseDe" onChange="SetDeviseDe" label="De" /> <editBox id="EditBoxVers" getText="GetDeviseVers" onChange="SetDeviseVers" label="Vers" /> </group> <group id="Group2" label="Action"> <button id="Button" label="Convertion de la selection" size="large" onAction="ConvertDevise" /> </group> </tab> </tabs> </ribbon> </customUI>
L'aspect visuel du Ruban défini, il reste maintenant à écrire le code .NET permettant son interaction avec le contenu du document.
Dans un premier temps, il est nécessaire d'écrire les méthodes définissant les valeurs par défaut contenues dans les deux zones de sélection de devise ainsi que celles correspondants à l'édition de ces zones et aux stockages de leurs valeurs dans des variables privées.
private string _deviseDe = "USA"; public string GetDeviseVers(IRibbonControl control) { return _deviseVers; } public string GetDeviseDe(IRibbonControl control) { return _deviseDe; } private string _deviseVers = "EURO"; public void SetDeviseDe(IRibbonControl control, string text) { _deviseDe = text; } public void SetDeviseVers(IRibbonControl control, string text) { _deviseVers = text; }
Le seul pré-requis à ce niveau est de respecter les signatures des méthodes d'interactions avec le ruban, celles-ci étant définies dans les diverses documentations disponibles sur Internet.
Une fois l'opération de communication avec les zones de saisie terminée, il reste à écrire le code événementiel devant s'exécuter lors du click de l'utilisateur sur le bouton, et notamment l'appel au Service Web renvoyant le taux de change en fonction des pays sélectionnés (http://www.freewebs.com/jimmy_cheng/CurrencyExchangeService.wsdl).
public void ConvertDevise(IRibbonControl control) { float DataToConvert; if (float.TryParse(((MSword.Application)applicationObject).Selection.Text, out DataToConvert)) { using (Converter.CurrencyExchangeService ws = new Converter.CurrencyExchangeService()) { float taux = ws.getRate(_deviseDe, _deviseVers); float resultat = DataToConvert * taux; ((MSword.Application)applicationObject).Selection.Text = resultat.ToString(); } } }
Ici aussi, pour permettre l'interaction avec le Ruban, il est obligatoire de respecter la bonne signature sur la méthode représentant le click (ConvertDevise).
L'objet « applicationObject.Selection.text » permet quand à lui de récupérer la sélection courante dans Word, c'est-à-dire le block de texte surligné. Si celui-ci est convertible en type float (donc est un nombre), la récupération du taux de conversion est effectuée via l'appel au service Web puis appliquée afin d'obtenir la nouvelle valeur et remplacer la zone sélectionnée par celle-ci.
Nul besoin de plus de code, il reste juste à compiler le tout, à installer l'Add-in grâce au projet fournit et à lancer Word pour le tester.
Avec ce modèle de définition du rendu graphique XML, la personnalisation du Ruban Office se rapproche du développement ASP.NET ou du tout nouveau WPF où l'aspect affichage est séparé de l'aspect code et interaction, simplifiant ainsi le développement et l'évolution de zones visuelles.