Developpez.com

Club des développeurs et IT pro
Plus de 4 millions de visiteurs uniques par mois

Comment personnaliser le Ruban de Word 2007

Word 2007 est arrivé avec une grande nouveauté, le RUBAN. Nous allons voir comment le personnaliser.

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

0. Introduction

La suite Office 2007 possède une nouvelle interface graphique. Certains éléments de cette interface sont modifiables et d'autres pas. L'élément sur lequel nous allons nous attarder est le Ruban. Vous trouverez ci-après la description de quelques éléments composants cette interface et parmi eux le Ruban.

Si les versions précédentes de Word permettaient d'ajouter, supprimer ou modifier rapidement les menus et barres d'outils, la version 2007 se révèle un peu plus complexe.

Il est également possible de réattribuer de nouvelles commandes aux boutons existants. Nous n'aborderons pas cet aspect des choses.

Comme les fichiers, le ruban de la suite Office 2007 est basé sur la technologie XML. Toutes les modifications que nous allons faire à notre ruban se feront en XML.
Si vous n'êtes pas familier avec le XML, vous pouvez vous en faire une idée ici. Vous y trouverez des tutoriels, des outils et bien d'autres choses.

0-A. Le Bouton Office

C'est un bouton Rond qui vous donne accès à certaines commandes standards comme la sauvegarde et l'ouverture de documents, l'accès aux options de Word, ...

Image non disponible

0-B. La barre d'outils Accès rapide

Image non disponible
Barre d'outils Accès rapide

Cette barre d'outils contient des outils par défaut et des outils ajoutés. Vous pouvez la personnaliser assez rapidement en utilisant la petite flèche située directement à droite de la barre d'outils.

Image non disponible

0-C. Le Ruban

C'est quoi le Ruban ?

Le Ruban est un bandeau qui remplace les menus et barres d'outils présents sur les versions précédentes de Word. Après de longues années, Microsoft a décidé de revoir l'interface utilisateur de sa suite et Word a aussi été modifié.

Image non disponible
Un morceau du ruban

Nous allons nous attarder un peu sur cette interface pour mieux comprendre les terminologies que nous allons aborder dans cet article.

Le Ruban est composé de différents morceaux qui ont tous une certaine utilité et surtout un nom.

0-C-1. Les onglets

Les onglets permettent le regroupement de certaines commandes. Le nom anglais des onglets est "Tab". Les onglets possèdent une étiquette, c'est elle qui est affichée.

Image non disponible
Les onglets

0-C-2. Les groupes

Les groupes constituent un regroupement supplémentaire dans un onglet.
Un groupe possède une étiquette.
Certains groupes possèdent un lanceur de boîte de dialogue.

Image non disponible
  1. Étiquette de l'onglet
  2. Groupe
  3. Lanceur de boîte de dialogue
  4. Description de la boîte de dialogue (elle donne un aperçu rapide du contenu de la boîte de dialogue)

0-C-3. Les boutons

Les onglets sont donc structurés en groupes et les groupes contiennent les commandes. On les retrouve sous forme de boutons, cases à cocher, listes déroulantes, liste modifiables, ...

Image non disponible
  • 2 Les boutons simples qui ont un effet immédiat
  • 1 et 3 Des boutons qui vont ouvrir une liste déroulante.

1. Ajout de notre ruban au fichier Word

Les modifications apportées au ruban se font directement dans le fichier Word. Si vous n'avez jamais tenté l'expérience, créez un fichier Word, dans l'explorateur de fichiers, renommez ce fichier en changeant son extension par .zip.

Image non disponible

Après modification :

Image non disponible

Si vous ouvrez votre fichier avec un logiciel d'archives, voila ce que vous devriez avoir.

Image non disponible

Le contenu de votre fichier est une arborescence de répertoires et des fichiers XML. Ces fichiers peuvent être édités avec un éditeur de texte ou un éditeur XML.

Pour personnaliser notre ruban nous allons ajouter dans cette arborescence un répertoire contenant un fichier XML.

Ne soyez pas effrayé, nous allons procéder étape par étape pour modifier le Ruban.

1-A. Création de notre fichier XML pour notre ruban

Nous allons faire un fichier très basique contenant un onglet, un groupe et un bouton.

 
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <ribbon>
    <tabs>
      <tab id="MonOnglet" label="Essai">
        <group id="Groupe_1" label="Premier Groupe">
          <button id="Bouton_1" label="Premier Bouton" size="large" onAction="PremierBouton" />
        </group >
      </tab>
    </tabs>
  </ribbon>
</customUI>

Le détail du fichier permet de visualiser sa structure.

Le name space
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">

Il devrait servir de référence pour la validation du fichier, mais ce n'est pas vraiment le cas.

Balise de ruban
Sélectionnez

<ribbon>

</ribbon>

C'est entre ces deux balises que doivent se trouver les éléments de votre ruban.

Balise pour les onglets
Sélectionnez

<tabs>

</tabs>

C'est entre ces balises que nous allons insérer les différents onglets que nous désirons ajouter.

L'onglet
Sélectionnez

<tab id="MonOnglet" label="Essai">

 </tab>

Entre les balises de l'onglet, on retrouve deux choses :
1. L'id de l'onglet : MonOnglet
2. L'étiquette qui sera appliquée à l'onglet : Essai

Les groupes
Sélectionnez

<group id="Groupe_1" label="Premier Groupe">
          
</group >

Comme pour les onglets, les groupes possèdent un Id, et une étiquette.

Les boutons
Sélectionnez

<button id="Bouton_1" label="Premier Bouton" size="large" onAction="ActionSurBouton" />

Dernier morceau de notre onglet, les boutons. Les boutons en plus de l'id et de l'étiquette possèdent au moins un attribut supplémentaire : onAction qui va être utilisé pour l'exécution d'une routine.

Vous allez sauvegarder ce fichier dans un nouveau répertoire CustomUI avec le nom suivant CustomUI.xml.

1-B. Insertion de notre fichier XML dans le document

Avant d'insérer notre fichier XML et son répertoire dans l'arborescence de notre document, nous allons créer un document et le sauvegarder. Ce document va nous servir de base pour la suite des manipulations.

Nous allons modifier l'extension du fichier de "dotm" en "zip" comme montré un peu plus tôt. Mais cette fois, nous allons extraire le contenu du fichier dans un répertoire de préférence vide. Je vous propose comme nom testruban.

Image non disponible

Le dossier.

Image non disponible

Le contenu du dossier après extraction.

Nous allons simplement coller le répertoire contenant notre fichier XML CustomUI dans ce répertoire.

Image non disponible

Le répertoire complet avec notre répertoire CustomUI contenant notre fichier CustomUI.xml.

Pour terminer, nous allons modifier le fichier xml contenant les relations. Ce fichier se trouve dans le répertoire _rels et porte le nom de .rels. Vous devez éditer ce fichier pour ajouter la ligne faisant référence au fichier CustomUI.xml ajouté.

La ligne à ajouter :

La ligne à ajouter
Sélectionnez

<Relationship Id="MonId" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml" />

Nous obtiendrons un fichier semblable à celui-ci.

Le fichier complet
Sélectionnez

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
	<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" 
	                         Target="docProps/app.xml"/>
	<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" 
	                         Target="docProps/core.xml"/>
	<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" 
	                         Target="word/document.xml"/>
	<Relationship Id="MonId" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" 
	                        Target="customUI/customUI.xml" />
</Relationships>

Il ne nous reste plus qu'à reconstruire notre fichier Word. Pour cela, nous allons sélectionner tous les fichiers et avec un clic droit les insérer dans un fichier archive.

Image non disponible

Pour obtenir un fichier .zip.

Image non disponible

Nous allons renommer le fichier pour en changer l'extension en ".docm". Si vous ouvrez le fichier fraîchement fait, vous obtiendrez ceci.

Image non disponible
L'onglet
Image non disponible
Le groupe et son bouton

2. Action de notre ruban

Dans le chapitre précédent, nous avons créé et intégré un onglet dans le ruban. C'est la première étape, nous allons voir comme agir avec notre ruban. Pour l'instant, les éventuelles actions que vous pourriez tenter se solderaient par un échec.

Dans le code XML de notre ruban, au niveau du bouton, nous avons un paramètre OnAction, c'est la valeur passée à ce paramètre qui va lancer une routine.

 
Sélectionnez

<button id="Bouton_1" label="Premier Bouton" size="large" onAction="PremierBouton" />

La solution est très simple : dans votre document, vous allez ajouter une procédure dans ThisDocument.

Image non disponible
 
Sélectionnez

Sub PremierBouton(ByVal control As IRibbonControl)
End Sub

Il ne nous reste qu'à tester si le tout fonctionne. Nous allons ajouter une petite ligne supplémentaire pour que notre procédure fasse quelque chose.

 
Sélectionnez

Sub ActionSurBouton(ByVal control As IRibbonControl)

ActiveDocument.Range.InsertAfter "Mon premier bouton"

End Sub

Si vous avez correctement œuvré, après un clic sur le bouton, vous devriez obtenir ceci :

Image non disponible

3. Les outils pour le ruban

Il existe sur le Web quelques outils permettant de travailler sur les fichiers du ruban. Nous allons aborder le logiciel Custom UI Editor qui est le seul logiciel gratuit que j'ai trouvé.

3-A. Custom UI Editor

Ce logiciel en anglais va vous aider à éditer votre ruban de façon bien plus facile. Nous allons ouvrir notre fichier de test. Custom UI Editor

Image non disponible

Si vous faites un saut un peu plus haut dans ce document, vous allez retrouver des éléments "déjà" vus.

En plus d'éditer des onglets personnels, ce logiciel permet de modifier les onglets existants.

3-A-1. Modification d'un document

Dans l'exemple précédent, nous avons ouvert un fichier qui possédait déjà un onglet personnalisé. Nous allons maintenant faire le test avec un document créé de toute pièce.
Notre première étape sera la création d'un nouveau document vierge. Je vous propose de créer un document "TestRuban2.docm", que nous allons utiliser immédiatement.

Image non disponible

A l'aide du bouton ouvrir (1), nous ouvrons une boîte de dialogue qui n'affiche que les fichiers Office. Choisissons notre fichier "TestRuban2.docm". Ce fichier ne contient pas de fichier de modification du ruban, la fenêtre est vide.

Image non disponible

C'est bien notre fichier qui est ouvert.

À l'aide du menu Sample, nous allons ajouter un fichier XML à notre document.

Image non disponible

J'ai triché un peu, le fichier XML que nous avons utilisé plus haut a été copié dans le répertoire "C:\Program Files\CustomUIEditor\Samples" sous le nom Onglet En plus.xml. C'est la raison de la présence d'un fichier en plus des fichiers fournis.

Image non disponible

Une fois de plus, nous voilà en terrain conquis.
Je pense que les autres commandes ne seront pas plus compliquées.

Une commande très intéressante est la commande permettant d'ajouter une icone à votre bouton. Il est en effet possible de créer vos propres icônes. Le programme autorise l'utilisation des images jpeg.

Image non disponible

Lors de la sauvegarde, le fichier XML est directement implanté dans le document et les liens sont ajoutés au fichier .rels .

Attention, l'implémentation d'un fichier XML dans un document efface le contenu du document !

3-B. Fonction avancée de l'éditeur

L'éditeur possède une fonction très sympathique qui permet de générer du code pour les boutons de notre Ruban personnalisé.

Image non disponible

Et le résultat que vous devez copier et coller dans le VBE.

Image non disponible

Il ne vous reste qu'à modifier le code.

4. Le XML en détail

Comme nous avons pu le voir, le fichier XML pour la personnalisation du ruban offre beaucoup de possibilités. Ces possibilités sont liées au fichier XSD. Si vous avez installé l'utilitaire Custom UI Editor, le fichier XSD se trouve dans le répertoire principal de l'application. Une autre possibilité est la recherche sur le WEB de CustomUI.xsd et finalement, consulter le site de Microsoft qui recèle d'innombrables ressources sur la personnalisation du Ruban.

Microsoft a mis à la disposition des utilisateurs quelques fichiers en format Excel pour vous aider à mettre en place un Ruban efficace et efficient. Vous trouverez dans les liens au bas de l'article tout ce qui vous manque pour faire votre bonheur.

La personnalisation du Ruban peut également passer par un affichage exclusif de votre Ruban. Lors de la déclaration du Ruban dans le XML, vous pouvez ajouter un attribut à la balise <ribbon> pour masquer les onglets prédéfinis.

Par facilité, je vais ajouter les contrôles décrits les uns à la suite des autres sur notre Ruban de test.

Affichage Exclusif
Sélectionnez

<ribbon startFromScratch="true">

</ribbon>

Vous pouvez également afficher certaines parties du Ruban par défaut, il suffit alors d'insérer votre onglet devant un onglet prédéfini et vous masquerez les onglets qui suivent le vôtre.

Affichage d'une partie des onglets
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
	<ribbon startFromScratch="true">
		<tabs>
			<tab idMso="TabHome" visible="true" />
			<tab id="MyTab01" label="Mon Onglet" insertBeforeMso="TabInsert"> 
				<group id="Gp02" label="Groupe de course" tag="Mon Tag" >
				</group>
				<group id="Gp01" label="Groupe de course 01">
				</group>
			</tab>
		</tabs>
	</ribbon>
</customUI>

4-A. Les onglets

Pour chaque type d'objet du Ruban, on peut passer des paramètres dans le fichier XML, nous allons les passer en revue. Le premier objet est l'onglet.

Les onglets
Sélectionnez

<tab id="" label="" visible="" insertBeforeMso="" >
	...
</tab>
  • id : L'id de notre onglet, sert à référencer l'onglet et doit être unique.
  • label : L'étiquette qui sera affichée sur l'onglet
  • insertBeforeMso : si vous ne mettez rien, l'onglet sera le dernier, si vous spécifiez un onglet, votre onglet sera juste avant. (insertAfterMso existe aussi)
  • visible : affiche ou cache l'onglet. Prend comme valeur 0 ou 1, true ou false (en minuscule)

Essayons tout de suite :

Test avec onglet
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
	<ribbon>
		<tabs>
			<tab idMso="TabHome" visible="0" />
			<tab id="MyTab01" label="Mon Onglet" insertBeforeMso="TabInsert" />
		</tabs>
	</ribbon>
</customUI>
Image non disponible
Le résultat

Nous avons dans le code XML demandé de cacher l'onglet TabHome qui correspond à l'onglet Accueil avec le paramètre visible = "0", et spécifié que l'onglet ajouté devait se trouver devant l'onglet Insertion par le paramètre insertBeforeMso="TabInsert".

Nous avons donc la possibilité de cacher ou d'afficher les onglets par défaut de Word et en ajouter des nouveaux.

Les onglets prédéfinis sont les suivants :

Nom Onglet
TabHome Accueil
TabInsert Insertion
TabPageLayoutWord Mise en page
TabReferences Références
TabMailings Publipostage
TabReviewWord Révision
TabView Affichage
TabDeveloper Développeur

4-B. Les groupes

Pour les Groupes, nous retrouvons pratiquement les mêmes attributs que pour les Onglets

Les groupes
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
	<ribbon>
		<tabs>
			<tab idMso="TabHome" visible="false" />
			<tab id="MyTab01" label="Mon Onglet" insertBeforeMso="TabInsert"> 
				<group id="Gp02" label="Groupe de course" tag="Mon Tag" >
				</group>
				<group id="Gp01" label="Groupe de course 01">
				</group>
			</tab>
		</tabs>
	</ribbon>
</customUI>

Les groupes fonctionnent de la même manière que les onglets. Le nombre d'attributs autorisés par le XSD est plus important. On retrouve l'attribut Image qui ne sert pas, l'attribut ScreenTip qui n'a pas d'utilité.

Image non disponible
Avec deux groupes

4-C. Les boutons ou contrôles

C'est probablement la partie la plus importante et complexe. Pour être correct, nous devrions parler de contrôles et pas de boutons, les boutons ne représentent qu'un seul élément de la collection contrôle.

4-C-1. Le contrôle "Bouton"

Le bouton est l'objet le plus simple de la "collection".

Essayons de suite
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
	<ribbon>
		<tabs>
			<tab idMso="TabHome" visible="false" />
			<tab id="MyTab01" label="Mon Onglet" insertBeforeMso="TabInsert"> 
				<group id="Gp02" label="Groupe de course" tag="Mon Tag" >
					<button id="but01" label="Bouton01" size="large" screentip="mon texte"/>
					<button id="but02" label="Bouton02" image="ange" />
				</group>
				<group id="Gp01" label="Groupe de course 01">
				</group>
			</tab>
		</tabs>
	</ribbon>
</customUI>

Le résultat :

Image non disponible
Mon bouton large
Image non disponible
Mon bouton avec image

Passons en détail les différents attributs utilisés pour les boutons.

Les attributs utilisés
  • id : Identification du bouton, doit être unique, mais vous avez le choix.
  • label : Étiquette du bouton
  • size : Taille du bouton, vous n'avez que deux possibilités, normal ou large
  • screentip : Texte qui va s'afficher lorsque vous allez survoler le contrôle avec la souris
  • image : Image qui sera affichée sur votre bouton

On peut également citer les imageMso qui sont des images déjà contenues dans les applications et qui peuvent être utilisées dans vos boutons.

Bouton avec image MSO
Sélectionnez

<button id="but03" label="Avec image MSO" imageMso="AcceptInvitation"/>
Image non disponible
Le résultat avec image MSO

Le nom des images MSO se trouve dans les classeurs que vous pouvez télécharger avec les liens ci-dessous.

Dans tous les boutons, nous avons omis la déclaration de la procédure à utiliser.

Avec un possibilité d'action
Sélectionnez

<button id="but03" label="Avec image MSO" imageMso="AcceptInvitation" onAction="ThisDocument.MonAction"/>

Si vous ne spécifiez pas l'attribut onAction, un clic sur le bouton ne lève pas d'erreur.

4-C-2. Les "Boutons à bascule"

Ces boutons possèdent deux états, normal ou enfoncé. Ils possèdent deux caractéristiques intéressantes, la première est que l'on peut activer une procédure sur le onAction du bouton, et la seconde est que l'état du bouton peut être récupéré.

Essayons !
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
	<ribbon>
		<tabs>
			<tab idMso="TabHome" visible="true" />
			<tab id="MyTab01" label="Mon Onglet" insertBeforeMso="TabInsert"> 
				<group id="Gp02" label="Groupe de course" tag="Mon Tag" >
					<button id="but01" label="Bouton01" size="large" screentip="mon texte"/>
					<button id="but02" label="Bouton02" image="ange" size="large" />
					<button id="but03" label="Avec image MSO" imageMso="AcceptInvitation" 
					         onAction="MacroRuban.MonAction"/>
				</group>
				<group id="Gp01" label="Groupe de course 01">
					<toggleButton id="togl01" label="Bouton à bascule" getPressed="Enfonce" 
					        onAction="MacroRuban.Bascule"/>
				</group>
			</tab>
		</tabs>
	</ribbon>
</customUI>

Et dans le document :

Code du bouton à bascule
Sélectionnez

Sub Bascule(control As IRibbonControl, Enfonce As Boolean)
If Enfonce Then
    MsgBox "Bouton enfoncé !"
Else
    MsgBox "Bouton relâché !"
End If
End Sub

Si nous revenons à notre document, lors d'une action sur le bouton à bascule, nous allons déclencher une procédure et l'état du bouton sera pris en compte. L'état du bouton est renvoyé par la variable "Enfonce". Variable que l'on retrouve dans notre code et dans le XML du bouton avec l'attribut getPressed.

On peut aussi utiliser ce changement d'état pour affecter une valeur à une variable qui pourra être utilisée dans une procédure.

 
Sélectionnez

Option Explicit
'Déclaration d'une variable booléenne
Dim MaVal As Boolean

Sub monAction(control As IRibbonControl)
	' Affichage de la valeur de ma variable
    MsgBox "Action sur bouton" & "  " & MaVal
    
End Sub


Sub Bascule(control As IRibbonControl, Enfonce As Boolean)
If Enfonce Then
	' Affichage d'un message sur action
	' et affectation d'une valeur
    MsgBox "Bouton enfoncé !"
    MaVal = True
    
Else
    MsgBox "Bouton relâché !"
    MaVal = False
End If
End Sub

On peut donc effectuer une action lors de l'utilisation d'un bouton, mais aussi affecter une valeur à une variable que l'on pourra réutiliser par la suite.

4-C-3. Les "Cases à cocher"

Le principe des cases à cocher est le même que pour les boutons à bascule.

 
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
	<ribbon startFromScratch="true">
		<tabs>
			<tab idMso="TabHome" visible="true" />
			<tab id="MyTab01" label="Mon Onglet" insertBeforeMso="TabInsert"> 
				<group id="Gp01" label="Groupe de course 01">
					<toggleButton id="togl01" label="Bouton à bascule" getPressed="Enfonce" 
					                   onAction="MacroRuban.Bascule"/>
					<checkBox id="chk01" label="Ma case à cocher" enabled="true" 
					                   onAction="MacroRuban.CaseACocher" />
				</group>
			</tab>
		</tabs>
	</ribbon>
</customUI>

Le résultat :

Image non disponible

4-C-4. Les "Zones de saisie"

Les zones de saisie sont des zones de texte qui permettent d'effectuer la saisie d'une valeur.

 
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
	<ribbon>
		<tabs>
			<tab idMso="TabHome" visible="true" />
			<tab id="MyTab01" label="Mon Onglet" insertBeforeMso="TabInsert"> 
				<group id="Gp01" label="Groupe de course 01">
					<toggleButton id="togl01" label="Bouton à bascule" getPressed="Enfonce" 
					                    onAction="MacroRuban.Bascule"/>
					<checkBox id="chk01" label="Ma case à cocher" enabled="true" 
					                    onAction="MacroRuban.CaseACocher" />
					<editBox id="ed01" label="Zone de saisie" maxLength="10" sizeString="aaaaa" tag="Donnee" 
					                    onChange="Changement"  />
				</group>
			</tab>
		</tabs>
	</ribbon>
</customUI>

Avec le résultat :

Image non disponible
  • maxLength représente la longueur maximale de la chaîne
  • sizeString représente la largeur du contrôle

Cette fois, j'ai utilisé la génération des Callbacks pour le code.

 
Sélectionnez

'Callback for ed01 onChange
Sub Changement(control as IRibbonControl, text as String)
End Sub

Et avec les actions qui doivent être prises :

 
Sélectionnez

'Callback for ed01 onChange
Sub Changement(control As IRibbonControl, text As String)
monTxt = text
MsgBox "Changé" & vbCrLf & text
End Sub

Le contenu du contrôle est dans la variable "text".

4-C-5. Les "Listes déroulantes"

Les listes déroulantes sont des listBox dans lesquelles vous pouvez choisir une valeur parmi des valeurs existantes. Ces listes sont enrichies avec des éléments "Item".

 
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
	<ribbon>
		<tabs>
			<tab idMso="TabHome" visible="true" />
			<tab id="MyTab01" label="Mon Onglet" insertBeforeMso="TabInsert"> 
				<group id="Gp01" label="Groupe de course 01">
					<toggleButton id="togl01" label="Bouton à bascule" getPressed="Enfonce" 
					                          onAction="MacroRuban.Bascule"/>
					<checkBox id="chk01" label="Ma case à cocher" enabled="true" 
					                          onAction="MacroRuban.CaseACocher" />
					<editBox id="ed01" label="Zone de saisie" maxLength="10" sizeString="aaaaa" tag="Donnee" 
					                          onChange="Changement"  />
					<dropDown id="list01" label="Ma Liste" tag="DeLaListe" 
					                          onAction="MacroRuban.ListeDerou" >
						<item id="it01" label="item 001" />
						<item id="it02" label="item 002" />
						
					</dropDown>
				</group>
			</tab>
		</tabs>
	</ribbon>
</customUI>

Dans la construction du contrôle, on inclut la liste des éléments qui vont composer la liste. De cette liste, sur l'évènement onAction, nous pouvons récupérer soit l'id de l'élément soit son index.

 
Sélectionnez

'Callback for list01 onAction
Sub ListeDerou(control As IRibbonControl, id As String, index As Integer)
MsgBox id & vbCrLf & index

End Sub
Image non disponible

4-C-6. Les "Listes modifiables"

La liste modifiable est un peu différente, alors que la liste déroulante impose le choix d'une valeur préexistante, la liste modifiable autorise la saisie d'un élément non présent dans la liste.

 
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
	<ribbon>
		<tabs>
			<tab idMso="TabHome" visible="true" />
			<tab id="MyTab01" label="Mon Onglet" insertBeforeMso="TabInsert"> 
				<group id="Gp01" label="Groupe de course 01">
					<toggleButton id="togl01" label="Bouton à bascule" getPressed="Enfonce" 
					                          onAction="MacroRuban.Bascule"/>
					<checkBox id="chk01" label="Ma case à cocher" enabled="true" 
					                          onAction="MacroRuban.CaseACocher" />
					<editBox id="ed01" label="Zone de saisie" maxLength="10" sizeString="aaaaa" 
					                          tag="Donnee" onChange="Changement"  />
					<dropDown id="list01" label="Ma Liste" tag="DeLaListe" 
					                          onAction="MacroRuban.ListeDerou" >
						<item id="it01" label="item 001" />
						<item id="it02" label="item 002" />
					</dropDown>
					<comboBox id="comb01" label="Mon combo" onChange="cmbOnChange" >
						<item id="it001" label="item 001" />
						<item id="it002" label="item 002" />
					</comboBox>
				</group>
			</tab>
		</tabs>
	</ribbon>
</customUI>

Contrairement au contrôle listBox, le comboBox permet de récupérer le contenu du Label.

 
Sélectionnez

'Callback for comb01 onChange
Sub cmbOnChange(control As IRibbonControl, text As String)
MsgBox text

End Sub

Comme à chaque fois, une image :

Image non disponible

Tous les id des éléments doivent être différents même s'ils appartiennent à des listes différentes.

4-C-7. Les "Éléments de liste"

Les éléments de liste ont été abordés plus tôt. Ils sont déclarés par les balises "Items", leurs id doivent être uniques, même si ces éléments appartiennent à des listes différentes.

 
Sélectionnez

<item id="it001" label="item 001" />
<item id="it002" label="item 002" />

4-C-8. Les "Groupes de boutons"

Cette fonctionnalité va permettre de grouper des contrôles.

 
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
	<ribbon>
		<tabs>
			<tab idMso="TabHome" visible="true" />
			<tab id="MyTab01" label="Mon Onglet" insertBeforeMso="TabInsert"> 
				<group id="Gp02" label="Groupe de course" tag="Mon Tag" >
					<buttonGroup id="bgr01" >
					<button id="BG01" label="lbl 01" />
					<button id="BG02" label="lbl 02" />
					<button id="BG03" label="lbl 03" />
					</buttonGroup>
					
				</group>
			</tab>
		</tabs>
	</ribbon>
</customUI>

Et le résultat :

Image non disponible

4-C-9. Les "Menus"

Les menus sont en réalité des déroulants contenant des commandes.

 
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
	<ribbon>
		<tabs>
			<tab idMso="TabHome" visible="true" />
			<tab id="MyTab01" label="Mon Onglet" insertBeforeMso="TabInsert"> 
				<group id="Gp02" label="Groupe de course" tag="Mon Tag" >
					<splitButton id="SPL01" >
					<menu>
					<button id="SPB01" label="lbl 01" onAction="MacroRuban.BoutGroup1"/>
					<button id="SPB02" label="lbl 02 Dans menu" />
					<button id="SPB03" label="lbl 03" />
					</menu>
					</splitButton>
				</group>
			</tab>
		</tabs>
	</ribbon>
</customUI>
Image non disponible

On peut ajouter des images qui vont figurer devant l'étiquette.

 
Sélectionnez

<button id="SPB03" label="lbl 03" image="ange"/>
Image non disponible

4-C-10. Les "Étiquettes"

Les étiquettes permettent d'afficher des informations dans votre ruban.

 
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
	<ribbon>
		<tabs>
			<tab idMso="TabHome" visible="true" />
			<tab id="MyTab01" label="Mon Onglet" insertBeforeMso="TabInsert"> 
				<group id="Gp02" label="Groupe de course" tag="Mon Tag" >
					<labelControl id="lbl001" label="mon étiquette" />
					<buttonGroup id="bgr01" >
					<button id="BG01" label="lbl 01" onAction="MacroRuban.BoutGroup1"/>
					<button id="BG02" label="lbl 02" />
					<button id="BG03" label="lbl 03" />
					<toggleButton id="BG04" label="lbl 04" />

					</buttonGroup>
				</group>

			</tab>
		</tabs>
	</ribbon>
</customUI>
Image non disponible

4-C-11. Le "Lanceur de boîte de dialogue"

Nous allons aborder les lanceurs de boîtes de dialogue. Pour donner une touche professionnelle à vos rubans, c'est le détail qu'il faut ajouter !

 
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
	<ribbon>
		<tabs>
			<tab idMso="TabHome" visible="true" />
			<tab id="MyTab01" label="Mon Onglet" insertBeforeMso="TabInsert"> 
				<group id="Gp02" label="Groupe de course" tag="Mon Tag" >
					<labelControl id="lbl001" label="mon étiquette" />
					
 					<buttonGroup id="bgr01" >
					<button id="BG01" label="lbl 01" onAction="MacroRuban.BoutGroup1"/>
					<button id="BG02" label="lbl 02" />
					<button id="BG03" label="lbl 03" />
					<toggleButton id="BG04" label="lbl 04" />

					</buttonGroup>

					<splitButton id="SPL01" >
					<menu>
					<button id="SPB01" label="lbl 01" onAction="MacroRuban.BoutGroup1"/>
					<button id="SPB02" label="lbl 02 Dans menu" />
					<button id="SPB03" label="lbl 03" image="ange"/>
					</menu>

					</splitButton>
					<box id="box01">
					<button id="but01" label="Bouton01" size="large" screentip="mon texte"/>
					<button id="but02" label="Bouton02" image="ange" size="large" />
					<button id="but03" label="Avec image MSO" imageMso="AcceptInvitation" 
					                   onAction="MacroRuban.MonAction"/>
					</box>
			            <dialogBoxLauncher>
                  			<button id="lau01" label="Mon Lanceur" screentip="Mon lanceur." 
							            onAction="OnAction" />
               			</dialogBoxLauncher>
				</group>
			</tab>
		</tabs>
	</ribbon>
</customUI>
Le détail du dialogBoxLauncher
Sélectionnez

<dialogBoxLauncher>
		<button id="lau01" label="Mon Lanceur" screentip="Mon lanceur." onAction="OnAction" />
</dialogBoxLauncher>
Image non disponible

4-C-12. la "Barre d'outils Accès rapide"

Dernier morceau, la Barre d'outils Accès rapide. Cette barre d'outils est modifiable de la même manière que le ruban.

 
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
	<ribbon startFromScratch="true">
      <qat> 
         <sharedControls> 
            <button idMso="Copy"  /> 
            <button idMso="Paste" /> 
         </sharedControls> 
      </qat>
	</ribbon>
</customUI>
Image non disponible

5. Utilisation Avancée

Dans les chapitres précédents, nous avons vu comment modifier le ruban. Ces modifications sont statiques. Le ruban peut également être modifié de façon dynamique, soit lors de l'ouverture du document ou lors d'une action ou encore en fonction d'informations.

Nous n'allons pas faire le tour de tous les éléments qui peuvent être utilisés pour la personnalisation du ruban, nous allons simplement parcourir les plus courants.

Pour pouvoir utiliser le Ruban de façon dynamique, vous devez utiliser l'argument "OnLoad" du Ruban. Dans le même module, vous devez déclarer une variable IRibbonUI du genre "Dim monRub As IRibbonUI" Fondements sur les variables et constantes

La variable IRibbonUI sera alors disponible pour votre projet.

Affectation d'une valeur à la variable de type IRibbonUI
Sélectionnez

Option Explicit
Dim monRub As IRibbonUI

'Callback for customUI.onLoad
Sub ChargerRuban(ribbon As IRibbonUI)
Set monRub = ribbon
End Sub

Nous pouvons maintenant utiliser le ruban dans nos procédures à condition d'appeler cette procédure lors du chargement du ruban.

 
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="ChargerRuban">
  <ribbon>
    
  </ribbon>
</customUI>

5-A. Les boutons

Le bouton est l'objet le plus basique du ruban. Il est possible de le cacher, nous utiliserons l'argument getVisible. Nous allons dans un premier temps afficher un bouton qui est caché sur l'action d'un autre bouton du ruban.

Le code XML du ruban
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="ChargerRuban">
  <ribbon>
    <tabs>
      <tab id="MonOnglet" label="Essai">
        <group id="Groupe_1" label="Premier Groupe">
          <button id="Bouton_1" label="Premier Bouton" size="large" 
		             onAction="ThisDocument.PremierBouton" getShowImage="ajoutimage" 
					 image="ange" getVisible="BoutonAffiche"/>
		  <button id="Bouton_2" label="Cacher 1" onAction="CacherBouton"/>
        </group >
      </tab>
    </tabs>
  </ribbon>
</customUI>

L'image "ange" est une image jpg que j'ai importée avec le "CustomUI Editor".

Les procédures liées au ruban
Sélectionnez

Option Explicit
Dim monRub As IRibbonUI
Dim imgVis As Boolean

'Callback for customUI.onLoad
Sub ChargerRuban(ribbon As IRibbonUI)
Set monRub = ribbon

End Sub

'Callback for Bouton_1 onAction
Sub PremierBouton(control As IRibbonControl)
MsgBox "Mon Bonton est fou !"
End Sub

'Callback for Bouton_1 getShowImage
Sub ajoutimage(control As IRibbonControl, ByRef returnedVal)
returnedVal = imgVis
End Sub

'Callback for Bouton_1 getVisible
Sub BoutonAffiche(control As IRibbonControl, ByRef returnedVal)
returnedVal = imgVis
End Sub

'Callback for Bouton_2 onAction
Sub CacherBouton(control As IRibbonControl)
imgVis = True
monRub.Invalidate

End Sub

Lors de l'ouverture du document, nous avons un onglet supplémentaire contenant un bouton avec le texte suivant : "cacher 1".

Image non disponible

Après clic sur le bouton :

Image non disponible

Le déroulement est assez simple, nous avons déclaré une variable de type Booleen Dim imgVis As Boolean. Nous affectons la valeur True à cette variable lors du clic sur le bouton "imgVis = True". Il ne nous reste plus qu'à utiliser cette variable pour afficher le bouton qui est caché (Valeur de imgVis est à False à l'ouverture).

Il est également possible de récupérer certaines informations du ruban pour agir sur le ruban. Pour récupérer des informations ou changement d'informations, il faut utiliser la procédure on Action du contrôle concerné par l'information à transmettre. Nous allons utiliser une case à cocher pour déterminer si notre bouton doit être affiché ou non.

Nous allons ajouter à notre XML la ligne suivante :

Ligne à ajouter
Sélectionnez

<checkBox id="chk01" label="Afficher" onAction="chk01_chcked"/>

Pour obtenir ce résultat :

 
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="ChargerRuban">
  <ribbon>
    <tabs>
      <tab id="MonOnglet" label="Essai">
        <group id="Groupe_1" label="Premier Groupe">
          	<button id="Bouton_1" label="Premier Bouton" size="large" 
			    onAction="ThisDocument.PremierBouton" getShowImage="ajoutimage" 
				image="ange" getVisible="BoutonAffiche"/>
		<button id="Bouton_2" label="Cacher 1" onAction="CacherBouton"/>
		<checkBox id="chk01" label="Afficher" onAction="chk01_chcked"/>
        </group >
      </tab>
    </tabs>
  </ribbon>
</customUI>
Image non disponible

Si nous voulons que le contrôle CheckBox soit utilisé pour déterminer si le bouton doit être affiché ou non, sur le onAction du checkBox, nous allons modifier une variable de notre code.

 
Sélectionnez

Dim bl_Chk01 As Boolean

Cette valeur sera modifiée lors du clic sur la case à cocher.

Récupération de la valeur du contrôle sur son action
Sélectionnez

Sub chk01_chcked(control As IRibbonControl, pressed As Boolean)
bl_Chk01 = pressed
End Sub

Pressed étant la valeur que possède le contrôle au moment où il est utilisé. Il ne nous reste plus qu'à utiliser cette valeur pour déterminer l'état du bouton.

 
Sélectionnez

'Callback for Bouton_1 getVisible
Sub BoutonAffiche(control As IRibbonControl, ByRef returnedVal)
Debug.Print bl_Chk01
'Renvoie la valeur de la case à cocher
' Si vrai, le bouton est affiché
returnedVal = bl_Chk01
End Sub
'**********************************************
'Callback for Bouton_2 onAction
Sub CacherBouton(control As IRibbonControl)

monRub.Invalidate

End Sub

Si la case à cocher a été cochée, le bouton sera affiché.

5-B. Les listes déroulantes

Les listes déroulantes sont des contrôles très intéressants lors d'une utilisation dynamique. En effet, il est possible de leur affecter une liste de valeur.
Pour remplir la liste, nous allons faire appel à deux arguments supplémentaires : getItemCount et getItemLabel

Le premier des deux va renseigner le nombre d'éléments que comporte la liste.
Le second va donner les étiquettes qui seront utilisées pour chaque élément de la liste.

En fait, le nombre d'éléments correspond au nombre de fois que sera utilisé l'appel à getItemLabel.

Pour imager ce fait, nous allons faire un petit test. Nous allons définir le nombre d'entrées de notre liste : 5.

Nombre d'entrées
Sélectionnez

'Callback for Lite_1 getItemCount
Sub NbreItems(control As IRibbonControl, ByRef returnedVal)
returnedVal = 5
End Sub

Dans la procédure de "Remplissage", nous allons tenter d'utiliser la valeur de l'index de la liste pour l'étiquette des éléments.

Peupler la liste
Sélectionnez

'Callback for Lite_1 getItemLabel
Sub EtiquettesItems(control As IRibbonControl, index As Integer, ByRef returnedVal)
returnedVal = "Entrée no " & index
End Sub

Le résultat est sans surprise :

Image non disponible

Comme vous l'aurez constaté, l'index commence à 0 et pas à 1. N'oubliez pas d'en tenir compte dans votre code.

Nous avons bien un appel de cette procédure par item de la liste. Il ne nous reste qu'à obtenir un résultat après avoir validé un choix dans la liste.

 
Sélectionnez

'Callback for Lite_1 getItemLabel
Sub EtiquettesItems(control As IRibbonControl, index As Integer, ByRef returnedVal)
returnedVal = "Item  " & index

End Sub

5-C. Les listes modifiables

Les listes modifiables sont comparables aux listes déroulantes, la différence est que dans une liste déroulante, vous êtes limité aux entrées de la liste alors que pour une liste modifiable, vous pouvez modifier le contenu par un contenu de votre choix.

Nombre d'éléments de la liste
Sélectionnez

'Callback for combo_1 getItemCount
Sub ComboItemsCount(control As IRibbonControl, ByRef returnedVal)
returnedVal = 4
End Sub

Pour enrichir la liste, on utilise le même principe et là encore, l'index commence à 0 et pas à 1.

Peupler la liste
Sélectionnez

'Callback for combo_1 getItemLabel
Sub ComboItemsLab(control As IRibbonControl, index As Integer, ByRef returnedVal)
returnedVal = "Item Combo  " & index
End Sub

5-D. En pratique

Nous allons utiliser un exemple assez simple. Depuis la version 2007, le passage d'un document ouvert à un autre n'est plus aussi aisé que pour la version précédente. Nous allons utiliser un ruban personnalisé pour y arriver.

Le fichier est disponible en téléchargement ici

5-D-1. La création du modèle

Nous allons nous baser sur un document vide et spécifier que ce sera un modèle de document. Pour obtenir la boîte de dialogue qui suit, dans les différents choix proposés par Word, nous allons utiliser "Mes Modèles" .

Image non disponible
Nouveau document

Nous obtenons un document totalement vide basé sur le Normal.dotm. Ce modèle, nous allons le sauvegarder dans un répertoire quelconque du disque dur jusqu'à ce qu'il soit terminé. Une fois terminé, nous allons placer ce modèle dans C:\Documents and Settings\UserName\Application Data\Microsoft\Word\STARTUP. Il deviendra alors disponible en permanence et semblera faire partie de l'interface normale de Word 2007.

5-D-2. La création d'un groupe qui sera ajouté à l'onglet Accueil

Nous allons le placer dans l'onglet Accueil qui est TabHome. Ensuite nous allons ajouter un groupe qui portera le nom de : Changer de Document et finalement, nous allons ajouter à ce groupe une liste déroulante Documents Ouverts

Le xml de notre groupe
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="ChargerRuban">
	<ribbon>
		<tabs>
			<tab idMso="TabHome">
				<group id="SwitchDocuments" label="Changer de Document" 
				            insertAfterMso="GroupIllustrations">
					<dropDown id="listDocs" label="Documents Ouverts" tag="DeLaListe" 
							onAction="ListeDocs" getItemCount="NbreElement" getItemLabel="AjoutTexte"  >
						
					</dropDown>					
					
				</group>
			</tab>
		</tabs>
	</ribbon>
</customUI>

5-D-3. Procédures pour le remplissage de la liste

Comme vous l'avez probablement remarqué, la liste ne contient pas d'éléments. Nous allons remplir cette liste de manière dynamique. Pour remplir la liste, deux méthodes sont utilisées : getItemCount et getItemLabel. Ces deux méthodes sont liées à deux procédures qui seront utilisées pour obtenir le nombre d'éléments qui va alimenter la liste et le texte des éléments qui va être utilisé pour construire la liste.

Nombre d'éléments de la liste
Sélectionnez

'Callback for listDocs getItemCount
Sub NbreElement(control As IRibbonControl, ByRef returnedVal)
'Nous allons utiliser le nombre de documents contenus dans la 
'collection des documents ouverts
returnedVal = Documents.Count

End Sub

En fonction du nombre d'éléments que va contenir la liste, Word va "boucler" la procédure getItemLabel pour construire la liste.

Procédure pour construire la liste
Sélectionnez

'Callback for listDocs getItemLabel
Sub AjoutTexte(control As IRibbonControl, index As Integer, ByRef returnedVal)
Dim i As Integer

returnedVal = Documents(index + 1).Name

End Sub

L'étape suivante est le basculement dans Word du document choisi.

Procédure exécutée par le ruban
Sélectionnez

onAction="ListeDocs"

Dans notre XML, nous avons déterminé que lorsque la liste déroulante serait mise à jour, la procédure listDocs serait exécutée.

Notre procédure listDocs
Sélectionnez

'Callback for listDocs onAction
Sub ListeDocs(control As IRibbonControl, id As String, index As Integer)
'Activation du document choisi

Documents(index + 1).Activate

End Sub

Dans le code, vous aurez probablement remarqué que nous ajoutons 1 à l'index renvoyé par la liste. La raison est assez simple, l'index de la liste commence à 0 alors que l'index des documents commence à 1. Le simple fait d'ajouter 1 corrige cet écart.
Lorsque vous choisirez un document dans la liste, ce dernier sera automatiquement activé et passera au premier plan.

Le souci que nous rencontrons maintenant est bloquant, la liste n'est mise à jour que lors du chargement du modèle, si nous chargeons un autre document ou changeons de document, le liste n'est plus mise à jour.

5-D-4. Mise à jour de la liste

Pour mettre la liste à jour lors de chaque changement, nous allons faire appel aux évènements de l'application Word. L'évènement qui sera le plus approprié est Document_Change qui se produit lors de chaque changement de document.

Pour permettre à Word de réagir face à certains évènements, nous allons ajouter à notre projet un module de classe.

Image non disponible
Ajout d'un module de classe

Nous allons renommer ce module en "EventClassModule".

Image non disponible
Changement de nom

Nous allons ajouter un peu de code pour permettre à Word d'utiliser l'évènement qui nous intéresse.

 
Sélectionnez

Public WithEvents wApp As Word.Application


Private Sub wApp_DocumentChange()
'Si votre code fonctionne, vous aurez une boite de message
MsgBox "Document changé "
End Sub

Pour faire fonctionner ce code, nous avons encore besoin d'une ou deux petites choses. Il faut activer la prise en compte des évènements lors du chargement du document. Nous allons ajouter un morceau de code dans le module "ThisDocument".

 
Sélectionnez

Dim X As New EventClassModule

Private Sub Document_Open()
    Set X.wApp = Word.Application
End Sub

Sans ces quelques lignes les évènements ne seront pas pris en compte.

Pour vérifier que notre évènement est pris en compte, nous allons utiliser une boite de message qui sera affichée lors de chaque changement de document. Cette boite de message sera enlevée par la suite.

Avec cette procédure, nous avons le moyen d'appeler un autre code qui mettra notre Ruban à jour.

 
Sélectionnez

Public WithEvents wApp As Word.Application

Private Sub wApp_DocumentChange()
MettreAJour
'MsgBox "Document changé du complément"
End Sub

Avec le même principe que pour le module de classe, nous allons ajouter à notre projet un simple module qui contiendra les procédures pour la mise à jour du Ruban. Pour pouvoir mettre le Ruban à jour, il faut le charger dans notre module. Dans le XML, nous avons spécifié que sur l'action OnLoad du Ruban, nous exécutions une procédure.

 
Sélectionnez

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="ChargerRuban">

Cette procédure sera : "ChargerRuban". Nous allons l'ajouter dans notre module.

Le chargement du Ruban
Sélectionnez

Dim monRub As IRibbonUI

Public Sub ChargerRuban(ribbon As IRibbonUI)
Set monRub = ribbon

End Sub

Cette procédure permet d'initialiser une variable : monRub qui est un objet Ruban et qui reste disponible hors de la procédure.

L'étape suivante reste la mise à jour du ruban lorsque l'on change de document. Si cette mise à jour n'est pas faite, la liste devient erronée et ne peut par conséquent plus être utilisée.

Mise à jour du ruban
Sélectionnez

Public Sub MettreAJour()
monRub.InvalidateControl "listDocs"
monRub.Invalidate


End Sub

Cette procédure qui va redessiner le ruban est appelée lors de chaque changement de document.

 
Sélectionnez

Private Sub wApp_DocumentChange()
MettreAJour
'MsgBox "Document changé du complément"
End Sub

Ce code n'est que le rappel du code déjà cité plus haut.

Notre document est prêt pour être utilisé en tant que modèle.

si vous copiez ce modèle dans le répertoire : C:\Documents and Settings\user\Application Data\Microsoft\Word\STARTUP, ses fonctionnalités seront disponibles pour tous les documents Word, il fonctionnera comme un complément.

6. Liens Utiles

7. Remerciements

Un grand merci à DVP pour son hébergement de Qualité.
Un grand merci à Cl@audius, Jeannot45 et à Lou Pitchoun pour leur patience à me relire.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2008 Olivier Lebeau. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.