Powershell : création d'interfaces graphiques - deuxième partie

Après une première partie traitant des bases de la conception d'une UI en Powershell, voici un deuxième article pour aller un peu plus loin. Je vais aborder dans cet article les points suivants :

  • L'ajout d'un menu en haut de la fenêtre grâce au contrôle MenuStrip
  • L'ajout de contrôles GroupBox pour mieux organiser les contrôles
  • L'activation ou désactivation de contrôles
  • L'ajout de bulles d'info au passage de la souris sur les contrôles
Si vous n'avez pas lu le premier article, je vous invite à le faire car je ne vais pas revenir sur les points qui ont été abordés précédemment.

Création d'une barre de menus

Tout d'abord, il s'agit de définir la fenêtre :

$Form = New-Object System.Windows.Forms.Form
$Form.ClientSize = '500,500'
$Form.Text = "Mon UI en PS ep. II"
$Form.FormBorderStyle = 'Fixed3D'
$Form.MaximizeBox = $false

FormBorderStyle réglé sur Fixed3D permet d'éviter à l'utilisateur de prendre le coin de la fenêtre et l'étendre ; ce qui fausserait tout le design de l'interface puisque nous nous basons sur des coordonnées par rapport à une taille de fenêtre définie dans le code. MaximizeBox sur False permet de désactiver le bouton d'agrandissement de la fenêtre. Avec ces simples paramètres, nous barrons déjà la possibilité pour l'utilisateur de nuire à sa propre expérience par deux fois.
Ensuite, nous allons nous servir du contrôle MenuStrip pour définir un menu en haut de notre fenêtre.

$Menu = New-Object System.Windows.Forms.MenuStrip
$Menu.Location = New-Object System.Drawing.Point(0,0)
$Menu.ShowItemToolTips = $True

Le menu est bien ajouté et visible :
Notre fenêtre vide avec son menu en haut. Ne reste qu'à ajouter des éléments sur ce menu.
Pour ajouter des sections dans ce menu, il faut utiliser l'objet ToolStripMenuItem, qu'on va instancier comme n'importe quel autre objet. Avec ce code, je vais donc ajouter une section "Fichier" qui aura un élément "Quitter", et une section "A propos" qui n'aura aucun élément.

$MenuFile = New-Object System.Windows.Forms.ToolStripMenuItem
$MenuFile.Text = "&Fichier"
$MenuAbout = New-Object System.Windows.Forms.ToolStripMenuItem
$MenuAbout.Text = "&A propos"
$MenuFileQuit = New-Object System.Windows.Forms.ToolStripMenuItem
$MenuFileQuit.Text = "&Quitter"

En ajoutant le symbole & au début de chaque titre, je permets au contrôle de réagir par raccourci clavier. Un ALT + F ira donc ouvrir la section "Fichier". Une fois ces trois objets créés, il faut indiquer que je souhaite avoir mon "Quitter" dans la section "Fichier" ; c'est réalisable avec la méthode DropDownItems.Add :

$MenuFile.DropDownItems.Add($MenuFileQuit)

Et enfin, nous allons rattacher les deux ToolStripMenuItem à notre MenuStrip :

$Menu.Items.AddRange(@($MenuFile,$MenuAbout))

Voici le résultat :
Nous allons rajouter une info-bulle et ajouter un EventHandler sur "Quitter".

$MenuFileQuit.ToolTipText = "Infobulle d'aide"

$MenuFileQuit.Add_Click({
$Form.Close()
})

Nous obtenons ceci :

Et lorsque nous cliquons sur "Quitter", la fenêtre et le script se terminent.

Mieux organiser ses contrôles avec des GroupBox

Le contrôle GroupBox permet d'encadrer simplement plusieurs contrôles à des fins visuelles. Je vais ajouter à la Form quelques contrôles Label, Button et deux GroupBox pour les séparer. Je vais donc créer un Label qui va afficher le nom de l'utilisateur sur clic du bouton associé et son pendant pour le nom de la machine exécutant le script ; en rangeant tout cela dans des GroupBox. Afin de les définir proprement, il faut spécifier la hauteur, largeur et la légende. A noter qu'il est important de définir les GroupBox après les contrôles que l'on souhaite placer dedans, sans quoi la GroupBox les masquera au lieu de les intégrer.

$LabelLogUser = New-Object System.Windows.Forms.Label
$LabelLogUser.Location = New-Object System.Drawing.Point(40,70)
$LabelLogUser.AutoSize = $true 

$LabelCompName = New-Object System.Windows.Forms.Label
$LabelCompName.Location = New-Object System.Drawing.Point(300,70)
$LabelCompName.AutoSize = $true 

$BoutonGetUser = New-Object System.Windows.Forms.Button
$BoutonGetUser.Location = New-Object System.Drawing.Point(40,150)
$BoutonGetUser.Width = 125
$BoutonGetUser.Text = "Nom user" 

$BoutonGetComp = New-Object System.Windows.Forms.Button
$BoutonGetComp.Location = New-Object System.Drawing.Point(300,150)
$BoutonGetComp.Width = 125
$BoutonGetComp.Text = "Nom station" 

$Form.controls.AddRange(@($LabelLogUser,$LabelCompName))
$Form.controls.AddRange(@($BoutonGetComp,$BoutonGetUser))

$GroupBoxUser = New-Object System.Windows.Forms.GroupBox
$GroupBoxUser.Location = New-Object System.Drawing.Point(20,50)
$GroupBoxUser.Width = 180
$GroupBoxUser.Height = 220
$GroupBoxUser.Text = "User" 

$GroupBoxComp = New-Object System.Windows.Forms.GroupBox
$GroupBoxComp.Location = New-Object System.Drawing.Point(250,50)
$GroupBoxComp.Width = 180
$GroupBoxComp.Height = 220
$GroupBoxComp.Text = "Station"

$Form.controls.AddRange(@($GroupBoxUser,$GroupBoxComp))

Exécutons :

N'ayant pas ajouté de propriété Text à mes Label, ils n'apparaissent donc pas pour l'instant, mais en ajoutant des EventHandlers aux boutons, ils apparaîtront. Je vais coder 2 handlers sur les boutons :

$BoutonGetUser.Add_Click({
$LabelLogUser.Text = $env:username
})

$BoutonGetComp.Add_Click({
$LabelCompName.Text = hostname
})

Et mon Label apparaît suite au clic sur le bouton pour récupérer le nom de la station :

Activation et désactivation de contrôles

Avec ces deux boutons, nous allons pouvoir voir la propriété Enabled qui existe sur beaucoup de contrôles : elle permet de rendre (in)-utilisable ledit contrôle par l'utilisateur. Dans le cadre d'un bouton, il sera grisé. Je vais changer le texte des boutons puis modifier les EventHandlers liés aux boutons pour qu'un clic sur le premier le désactive en activant le second et réciproquement. Par défaut, la propriété Enabled d'un contrôle est à True, ce qui signifie qu'à moins de la passer à False à un moment dans votre code, ce contrôle sera toujours actif.

$BoutonGetUser.Add_Click({
$BoutonGetUser.Enabled = $false
$BoutonGetComp.Enabled = $true
$BoutonGetUser.Text = "Inactif"
$BoutonGetComp.Text = "Actif"
})

$BoutonGetComp.Add_Click({
$BoutonGetComp.Enabled = $false
$BoutonGetUser.Enabled = $true
$BoutonGetComp.Text = "Inactif"
$BoutonGetUser.Text = "Actif"
})

Voyons le résultat :

Ajout de tooltips au passage de la souris

Certains contrôles comme le MenuStrip évoqué plus haut gèrent "nativement" les bulles d'information. D'autres ont besoin d'un objet, simplement nommé ToolTip. L'ajout d'une info-bulle sur un contrôle se fait en deux phases : la première consiste en la création de l'objet et la deuxième du rattachement de cet objet au contrôle en question. Ce snippet va créer deux objets ToolTip et les associer aux boutons.

$BoutonGaucheTooltip = New-Object System.Windows.Forms.ToolTip
$BoutonDroitTooltip = New-Object System.Windows.Forms.ToolTip
$BoutonGaucheTooltip.SetTooltip($BoutonGetUser,"Ce bouton permettait d'afficher le nom de l'utilisateur.")
$BoutonDroitTooltip.SetTooltip($BoutonGetComp,"Ce bouton permettait d'afficher le nom de la machine.")

Et le résultat :

Voici donc pour la deuxième partie de ma suite d'articles sur la création d'interfaces graphiques avec Powershell.

Liens

Télécharger le script de l'article
Développement d'une UI en Powershell : première partie - troisième partie
Documentation et référence des classes : MenuStrip - ToolStripMenuItem - GroupBox -  ToolTip

Lien pour marque-pages : Permaliens.

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.