Une application MDI (multiple document interface) par opposition au SDI (single document interface) est une application telle que Works, qui permet l'ouverture de plusieurs documents en même temps. On appelle feuille MDI la feuille principale de l'application, et feuille(s) fille(s), les feuilles documents qui peuvent être multiples dans la feuille principale.
Pour créer une application MDI, on peut soit utiliser l'assistant en cliquant sur l'icône (à gauche), et en choisissant de créer une interface multi-documents (image de droite), avec le bouton radio approprié, soit en le faisant à la main. C'est ainsi que je vais faire car c'est plus simple à expliquer. Tout d'abord, créer un nouveau projet :
Choisir de créer un EXE Standard et cliquer sur OK. Le feuille obtenue ent vierge. On va alors la désigner comme feuille fille de l'application MDI que nous allons créer : pour cela, attribuez tout simplement la valeur True à la propriété MDIChild. Vous pouvez de plus noter que son icône a changé, si vous ne l'avez pas changée au départ.Ensuite, il s'agit d'ajouter une feuille principale qui sera le conteneur de cette feuille fille. Pour cela, on va dans le menu Projet/Ajouter une feuille MDI. Et on valide.
Remarque :
On ne peut ajouter qu'une seule feuille MDI à un projet. Cette manipulation faite, on a maintenant une application où sont définie la feuille conteneur et la feuille fille. Regardez le résultat en exécutant l'application (F5). on a une feuille fille contenue dans la feuille principale. Si ce n'est pas le cas, vous devez aller dans les propriétés du projet pour spécifier que la feuille MDI est l'objet de démarrage.Par la suite, on appelera frmMain la feuille principale MDI et frmChild la feuille MDIChild, feuille fille.
Pour comprendre le fonctionnement de ces types de feuilles, on va prendre l'exemple d'un traitement de texte. Ajoutez les contrôles suivants à votre projet, avec les propriétés spécifiées :
frmChild : Ajoutez un RichTextBox à la feuille :
Contrôle Propriété Valeur RichTextBox Name rtb1 frmMain : Ajoutez un contrôle PictureBox nommé picTB qui simulera une barre d'outils puis incorporez-y trois boutons cmdNew, cmdOpen, cmdSave. Oour les trois boutons, réglez leur propriétés Height et Top respectivement à 375 et 50. Ensuite, appliquez les propriétés suivantes :
Contrôle Propriété Valeur picTB Align Align Top picTB Height 495 picTB BorderStyle None cmdNew Caption Nouveau cmdOpen Caption Ouvrir cmdSave Caption Enregistrer
Placez une liste combobox sur picTB (nom : cmbAlign) avec 3 éléments : Gauche (index 0), Centre (1), Droite (2). Pour cela, entrez un à un les éléments de la liste dans sa propriété List. (Validez votre saisie entre chaque entrée).
Voici l'aspect en exécution du projet que nous faisons :
Niveau : 1 Exercice : lorsque vous redimensionnez la feuille fille créée, le cadre de texte reste inchangé et ce n'est pas esthétique : programmez une routine pour palier à ceci et pensez où la mettre...
Indice 1 : La routine doit être exécutée quand l'utilisateur redimensione la feuille
Indice 2 : Redimensionner se dit Resize en anglais. Cherchez donc la procédure idoine.
Indice 3 : la taille de rtb1 est celle de la feuille (Me) ôtée de 240 par exemple.Réponse : La procédure est : (à placer dans le code de la feuille fille bien sûr)
Private Sub Form_Resize()
rtb1.Width = Me.Width - 420
rtb1.Height = Me.Height - 600
End SubAccès aux commandes de la feuille fille depuis la feuille principale et inversement :
Feuille mère => Feuille fille :
Pour créer un nouveau document tout d'abord, il est nécessaire d'ouvrir une nouvelle feuille fille. pour cela on définit une variable du nom de la feuille fille et on l'affiche (on appelle ceci créer une nouvelle instance de la feuille) :Private Sub cmdNew_Click()
Dim frmD As New frmChild
frmD.Caption = "Nouveau document"
frmD.Show
End SubOn peut corser la chose en affichant le n° du document créé dans la feuille. Pour cela, on définit à l'extérieur de la procédure une variable qui compte le nombre de feuilles déjà créées (à l'extérieur pour qu'elle soit accessible par toutes les procédures et non réinitialisée) :
Dim DocNum As Integer
Private Sub cmdNew_Click()
'Au départ, DocNum = 0
DocNum = DocNum +1
Dim frmD As New frmChild
frmD.Caption = "Document n°" & str(DocNum)
frmD.Show
End SubCommande Ouvrir : Il faut ajouter auparavant dans frmMain un contrôle de boîte de dialogue commune, nommé "cd". Ensuite, on veut accéder à la feuille créée, pour cela, on utilise frmMain.ActiveForm pour désigner la feuille active du conteneur frmMain ; ainsi, on peut définir le nom de fichier à ouvrir :
Private Sub cmdOpen_Click()
cd.Filter = "Texte (*.txt)|*.txt"
cd.ShowOpen
Call cmdNew_Click 'création d'une nouvelle instance de la feuille fille
frmMain.ActiveForm.rtb1.filename = cd.filename
End SubAttention : il faut penser à tout : si jamais l'utilisateur clique sur annuler dans la boîte de dialogue d'ouverture, il faut penser à le gérer. Pour cela, on met la propriété CancelError de cd à True et on fait une gestion d'erreur comme suit :
Private Sub cmdOpen_Click()
On Error GoTo GestErr
cd.Filter = "Texte (*.txt)|*.txt"
cd.ShowOpen
Call cmdNew_Click
frmMain.ActiveForm.rtb1.FileName = cd.FileName
Exit Sub 'pour sortir de la procédure
GestErr:
If Err.Number <> 32755 Then '32755 est le n° de l'erreur généré en cas de
'clic sur annuler : dans ce cas, on ne fait rien et on quitte la procédure. Sinon on
'affiche le mesage d'erreur correspondant.
MsgBox "Une erreur est survenue :" & vbCrLf & Err.Number & " : " & Err.Description
End If
End Sub
Niveau : 3 Exercice : Procédez à la programmation de l'alignement du texte de rtb1, en utilisant le contrôle cmbAlign de la feuille conteneur frmMain :
Indice 1:
Utilisez la procédure Change de cmbAlign pour placer le code de l'alignement.
Indice 2:
Utilisez une structure Select Case cmbAlign.text pour savoir quel alignement a été choisi.
Indice 3:
Accédez à la feuille fille par frmMain.ActiveForm
Indice 4:
Pensez à On Error Resume Next au début (sinon, si aucune feuille n'est ouverte, vous aurez des surprises).Réponse de l'exercice : une solution efficace :
Private Sub cmbAlign_Click()
On Error Resume Next
Select Case cmbAlign.Text
Case "Gauche"
frmMain.ActiveForm.rtb1.SelAlignment = 0
Case "Centre"
frmMain.ActiveForm.rtb1.SelAlignment = 2
Case "Droite"
frmMain.ActiveForm.rtb1.SelAlignment = 1
End Select
End Sub
L'utilisation de If est moins claire pour la décision de la commande à appliquer. Attention, la variable Text est spécifique à une liste déroulante. Une liste simple n'utilise pas de cette variable.Feuille fille => Feuille mère :
On veut rendre le programme plus performant : on veut afficher l'alignement en cours du texte dans la liste déroulante de la feuille conteneur. Pour cela, comme précédemment, on utilise un SELECT CASE. et on fait l'inverse de tout à l'heure. Pour accéder depuis la feuille fille vers la feuille mère, on utilise tout simplement frmMain :Private Sub rtb1_SelChange()
On Error Resume Next
Select Case rtb1.SelAlignment
Case 0
frmMain.cmbAlign.Text = "Gauche"
Case 2
frmMain.cmbAlign.Text = "Centre"
Case 1
frmMain.cmbAlign.Text = "Droite"
End Select
End Sub