5.7.un petit éditeur de texte
(à améliorer, en Visual Basic et en Delphi)
     


    Plan du chapitre:

    1. Un éditeur de texte
     

      L’énoncé et les choix


    2. En Visual Basic ...
     

      2.1 L’interface choisie
      2.2 Les procédures événementielles


    3. En Delphi ...
     

      3.1 L’interface choisie
      3.2 Les gestionnaires d’événements

      Remarquessur VB et Delphi dans la construction de cet exemple



    1. Un éditeur de texte

 

L’énoncé et les choix

Delphi.µediteur\Editeur1

un micro-éditeur de texte
 

Nous souhaitons développer rapidement un petit éditeur de texte qui nous permettra :
2. En Visual Basic
 

VB n'étant pas un langage fortement orienté objet, nous n'exploiterons pas toutes les fonctionnalités de l'analyse précédente. Nous utiliserons l'objet principal de feuille et la structure des menus pour représenter nos objets conceptuels.
 
 

2.1 L’interface choisie

Une feuile (Form1) comportant


Le constructeur de menu de VB qui est un outil intégré dans l'environnement de conception de VB, nous permet de définir deux menus principaux "Ficher" et "Edition" avec chacun des sous-menus :
 

Remarque :
Chacun des 3 items couper, copier, coller est automatiquement associé à un raccourci clavier classique (Ctrl+...)lors de la conception.

 

2.2 Les procédures événementielles

Passons maintenant à la gestion des évènements. A chacun des items utilisables de chacun des 2 menus, il nous reste à associer une procédure événementielle qui indique au programme comment il doit réagir lorsque l'utilisateur sélectionne un champ de l'un des menus. Tous les contrôles de VB sont sensibles à certains événements et possèdent pour chaque événement une procédure événementielle de réaction à cet événement.
 

Voici les prototype des 7 procédures événementiells automatiquement construites:
 
Private Sub Quitter1_Click()¬gestionnaire "Quitter"
Private Sub Ouvrir1_Click() ¬gestionnaire "Ouvrir"
Private Sub Enregistrersous1_Click() ¬gestionnaire "Enregistrer sous..."
Private Sub Couper1_Click() ¬gestionnaire "Couper"
Private Sub Copier1_Click() ¬gestionnaire "Copier"
Private Sub Coller1_Click() ¬gestionnaire "Coller"
Private Sub Nouveau1_Click() ¬gestionnaire "Nouveau"

Il ne nous reste plus qu'à écrire le code de réaction que nous désirons dans le corps de chacune de ces procédures.

Voici pour chaque gestionnaire le code écrit par le programmeur.
 

Le code de la procédure Quitter1Click
Private Sub Quitter1_Click()
 End ¬ écrit par le développeur
End Sub

Le code de la procédure Ouvrir1Click
Private Sub Ouvrir1_Click()
Dim NomFichier As String
 CommonDialog1.ShowOpen
 Enregistrersous1.Enabled = True
 NomFichier = CommonDialog1.FileName
 TextEditeur.Text = LoadFromFile(NomFichier)
End Sub

Le code de la procédure Enregistrersous1Click
Private Sub Enregistrersous1_Click()
 Call SaveToFile(NumFichier, TextEditeur.Text)
End Sub

 

Le code de la procédure Couper1Click
Private Sub Couper1_Click()
 Clipboard.SetText TextEditeur.SelText, vbCFText
 TextEditeur.SelText = ""
End Sub

Le code de la procédure Copier1Click
Private Sub Copier1_Click()
 Clipboard.SetText TextEditeur.SelText, vbCFText
End Sub

Le code de la procédure Coller1Click
Private Sub Coller1_Click()
 TextEditeur.SelText = Clipboard.GetText(vbCFText)
End Sub

Le code de la procédure Nouveau1Click
Private Sub Nouveau1_Click()
 TextEditeur.Text = ""
 Enregistrersous1.Enabled = True
End Sub

Pour la compréhension complète nous livrons ci-dessous le code écrit pour la fonction LoadFromFile et celui de la procédure SaveToFile.
 

Option Explicit
Dim NumFichier As Integer 'le fichier texte en cours


Private Function LoadFromFile(Nom As String) As String
 Dim Msg As String
 If Nom <> "" Then
  OnErrorGoTo GestionErreur
  Open Nom For Input As NumFichier
  LoadFromFile = Input(LOF(NumFichier), NumFichier)
  Close NumFichier
 End If
 Exit Function
GestionErreur:
 If Err.Number = 53 Then
  Msg = "Erreur fichier: '" + Nom + "' inexistant !"
  MsgBox Msg, , "Chargement impossible"
  Err.Clear   ' Efface les champs de l'objet Err
 End If
End Function


Private Sub SaveToFile(Nom As String, texte As String)
 If Nom <> "" Then
  Open Nom For Output As NumFichier
  Print #NumFichier, texte
  Close NumFichier
 End If
End Sub


Private Sub Form_Load()
'le numéro du fichier en cours :
 NumFichier = FreeFile
End Sub


Private Sub Form_Resize()
'repositionne le contrôle sur la zone client de la feuille
 TextEditeur.Move 0, 0, ScaleWidth, ScaleHeight
End Sub

 

3. En Delphi

Delphi étant orienté objet nous allons exploiter complètement l'analyse présentée dans le graphe événementiel ci-haut en mettant en place quatre objets.
 

3.1 L’interface choisie

Une fiche (Form1) comportant


 
  • TMainmenu (une barre de 2 menus)
  • TopenDialog (pour le chargement de fichier)
  • TSaveDialog (pour la sauvegarde d'un texte)


  Le composant Tmainmenu(1er menu)
  comporte un premier menu Fichier à 5 items
 

Le composant Tmainmenu (2ème menu)
 
comporte un deuxième menu Edition à 3 items.
 
Les menus dans la barre et les sous-menus sont tous des objets de classe TmenuItem qui sont gérés à travers le champ Items d'un objet de classe TMainMenu :



Mise en place de la gestion des événements.

A chacun des items utilisables de chacun des 2 menus, il nous faut associer un gestionnaire d’événement qui indique au programme comment il doit réagir lorsque l'utilisateur sélectionne un champ de l'un des menus par un click de souris. Nous avons vu que Delphi contient le mécanisme d'association des événements à nos gestionnaires. Beaucoup de contrôles (classes visuelles)et beaucoup d'autres classes non visuelles comme les TMenuItem, de Delphi sont sensibles à l’événement. de click de souris : property OnClick : TnotifyEvent.

Remarque :
Chacun des 3 items est associé à un raccourci clavier classique (Ctrl+...)

Elaboration de la gestion des évènements. A chacun des items utilisables de chacun des 2 menus, il nous faut associer un gestionnaire d’événement qui indique au programme comment il doit réagir lorsque l'utilisateur sélectionne un champ de l'un des menus. Delphi contient le mécanisme d'association des événements à nos gestionnaires. Tous les contrôles et beaucoup d'autres classes de Delphi possèdent de tesl gestionnaires d’événement.

     
3.2 Les gestionnaires d’événements

Voici les en-têtes des 7 gestionnaires automatiquement construits:
procedure Quitter1Click(Sender: TObject);¬ gestionnaire "Quitter"
procedure Ouvrir1Click(Sender: TObject); ¬ gestionnaire "Ouvrir"
procedure Enregistrersous1Click(Sender: TObject); ¬ gestionnaire "Enregistrer sous..."
procedure Couper1Click(Sender: TObject); ¬ gestionnaire "Couper"
procedure Copier1Click(Sender: TObject); ¬ gestionnaire "Copier"
procedure Coller1Click(Sender: TObject); ¬ gestionnaire "Coller"
procedure Nouveau1Click(Sender: TObject); ¬ gestionnaire "Nouveau"

Voici pour chaque gestionnaire le code écrit par le programmeur.

Le code du gestionnaire Quitter1Click
procedure TForm1.Quitter1Click(Sender: TObject);
begin
 Close; ¬ écrit par le développeur (fermeture de la fenêtre)
end;

Le code du gestionnaire Ouvrir1Click
procedure TForm1.Ouvrir1Click(Sender: TObject);
begin
 if OpenDialog1.Execute then ¬ écrit par le développeur
 begin
  Enregistrersous1.enabled:=true;
  TextEditeur.Lines.LoadFromFile(OpenDialog1.FileName);
 end
end;

Le code du gestionnaire Enregistrersous1Click
procedure TForm1.Enregistrersous1Click(Sender: TObject);
begin
 if SaveDialog1.Execute then ¬ écrit par le développeur
 begin
  Enregistrersous1.enabled:=false;
  TextEditeur.Lines.SaveToFile( SaveDialog1.FileName );
 end
end;

Le code du gestionnaire Couper1Click
procedure TForm1.Couper1Click(Sender: TObject);
begin
 TextEditeur.CutToClipboard; ¬ écrit par le développeur
end;

Le code du gestionnaire Copier1Click
procedure TForm1.Copier1Click(Sender: TObject);
begin
 TextEditeur.CopyToClipboard; ¬ écrit par le développeur
end;

Le code du gestionnaire Coller1Click
procedure TForm1.Coller1Click(Sender: TObject);
begin
 TextEditeur.PasteFromClipboard; ¬ écrit par le développeur
end;

Le code du gestionnaire Nouveau1Click
procedure TForm1.Nouveau1Click(Sender: TObject);
begin
 TextEditeur.Clear; ¬ écrit par le développeur
 Enregistrersous1.enabled:=true ¬ écrit par le développeur
end;

Vous remarquerez que nous avons écrit au total 16 lignes de programme Delphi pour construire notre micro-éditeur. Ceci est rendu possible par la réutilisabilité de méthodes déjà intégrées dans les objets de Delphi et en fait présentes dans le système Windows.

Vous pouvez voir la puissance de ce RAD lorsque vous observez par exemple l'instruction qui a permis de faire exécuter le "copier" ou le "chargement d'un fichier" :
 
TextEditeur.CopyToClipboard;

 
TextEditeur.Lines.LoadFromFile(OpenDialog1.FileName);

La méthode CopyToClipboard s'applique à l'objet TextEditeur qui est de la classe Tmemo; cette instruction correspond à un ensemble complexe d'opérations de bas niveau :

le Tmemo autorise une suite complexe d'opérations permettant de sélectionner un texte écrit sur plusieurs lignes du Tmemo. Il les affiche en surbrillance et la méthode CopyToClipboard récupère le texte sélectionné puis le recopie enfin dans le presse-papier du système.

Nous n'avons par ailleurs eu aucun code particulier à écrire pour le chargement de fichier texte, la méthode LoadFromFile présente dans l'objet lines (de classe TStrings) effectue toutes les actions.
 

Une amélioration proposée du petit éditeur se trouve dans :
Delphi.µediteur\Editeur2
 

Nous remarquerons que :
  • Nous avons dû écrire moins de lignes de code pour cet exemple avec Delphi.
  • Les gestionnaires d'événements possèdent tous le paramètre Sender:Tobject qui permet de connaître le contrôle qui appelé le gestionnaire et donc nous avons la possibilité avec le transtypage d'objet de construire un gestionnaire général pour plusieurs types de contrôles.
  • Les menus de Delphi ont une gestion "orthogonale" dans la mesure où ils ne sont pas traités différemment des autres objets.
  • La qualification orientée objet de Delphi met à notre disposition de nombreuses méthodes et propriétés que nous n'avons pas à réécrire.