Codage des réponses aux actions des utilisateurs dans l'éditeur de code (tutoriel de l'EDI)

De RAD Studio
Aller à : navigation, rechercher

Remonter à Démarrage de votre première application RAD Studio - Index (tutoriel de l'EDI)


En suivant les instructions de cette section, vous rendrez votre application interactive et lui fournirez les fonctionnalités de votre choix. Vous coderez les gestionnaires d'événement, c'est-à-dire les réponses aux clics sur les divers éléments du menu principal et à d'autres types d'interaction de l'utilisateur.

Commencement du code

Commencez l'écriture du code en définissant une variable String que vous utiliserez pendant l'exécution de l'application pour stocker le nom du fichier texte ouvert.

Dans Delphi, sélectionnez l'onglet Code dans la barre d'état pour ouvrir l'éditeur de code. Utilisez l'éditeur de code pour définir une variable String appelée CurrentFile dans la section private de la classe TTextEditorForm dans la partie interface :

TutorialIDENewFig3-18kh2.PNG
Définition de la variable private CurrentFile (vue Delphi)

Dans C++Builder, sélectionnez l'onglet TextEditorUnit.h dans la barre d'état pour ouvrir le fichier en-tête de l'unité dans l'éditeur de code. Utilisez l'éditeur de code pour déclarer une variable String appelée CurrentFile dans la section private de TTextEditorForm :

TutorialIDENewFig3-19kh.PNG
Définition de la variable private CurrentFile (vue C++Builder)

Pour permuter entre les modes Concepteur de fiches et Editeur de code, appuyez sur F12.

Mise à jour de la barre d'état en réponse aux actions sur l'éditeur de texte

Lorsque les utilisateurs déplacent le signe d'insertion (curseur de texte) ou modifient le contenu de votre composant TMemo, vous devez mettre à jour la barre d'état. Comme vous devez mettre à jour la barre d'état en réponse à de nombreux événements différents, vous avez la possibilité de définir une procédure unique dans votre code et de l'appeler ultérieurement à partir d'un gestionnaire d'événement pour procéder à la mise à jour.

Dans Delphi, pour définir cette nouvelle procédure dans votre application, ajoutez la signature de procédure suivante à la section private de la classe TTextEditorForm dans la partie interface , juste en dessous de la variable CurrentFile que vous avez précédemment définie :

 procedure UpdateStatusBar;

Cliquez avec le bouton droit sur UpdateStatusBar dans votre code, puis sélectionnez Compléter la classe au niveau du curseur de manière à ce que RAD Studio ajoute une définition squelette pour votre procédure à la partie implementation de votre code :

 procedure TTextEditorForm.UpdateStatusBar;
 begin
 
 end;

Définissez la logique de la procédure UpdateStatusBar entre ces mots-clés begin et end comme suit :

 LineNumber.Text := 'L: ' + (Editor.CaretPosition.Line+1).ToString;
 ColumnNumber.Text := 'C: ' + (Editor.CaretPosition.Pos+1).ToString;
 LineCount.Text := 'Lines: ' + Editor.Lines.Count.ToString;

Dans C++, pour définir cette nouvelle fonction dans votre application, ajoutez la signature de fonction suivante à la section private de la classe TTextEditorForm dans le fichier TextEditorUnit.h, juste en dessous de la variable CurrentFile que vous avez précédemment définie :

 void UpdateStatusBar();

Sélectionnez le fichier d'implémentation, TextEditorUnit.cpp, et implémentez cette fonction comme suit :

 void TTextEditorForm::UpdateStatusBar()
 {
     TextEditorForm->LineNumber->Text = L"L: " + String(TextEditorForm->Editor->CaretPosition.Line+1);
     TextEditorForm->ColumnNumber->Text = L"C: " + String(TextEditorForm->Editor->CaretPosition.Pos+1);
     TextEditorForm->LineCount->Text = L"Lines: " + String(TextEditorForm->Editor->Lines->Count);
 }

Vous pouvez à présent appeler UpdateStatusBar à partir de n'importe quel gestionnaire d'événement pour mettre à jour votre barre d'état.

Votre application doit mettre à jour pour la première fois les informations affichées sur la barre d'état lorsque votre application démarre. Pour cela, vous pouvez utiliser l'événement OnCreate de votre fiche :

  1. Sélectionnez l'onglet Conception pour revenir au Concepteur de fiches.
  2. Sur la vue Structure, sélectionnez votre composant fiche, que vous avez nommé TextEditorForm.
  3. Sur l'inspecteur d'objets, ouvrez l'onglet Evénements.
  4. Sur l'onglet Evénements, double-cliquez sur le champ de valeur de l'événement OnCreate. RAD Studio bascule vers l'éditeur de code et ajoute une définition squelette pour votre nouveau gestionnaire d'événement. Utilisez ce gestionnaire d'événement pour appeler votre procédure UpdateStatusBar :
Delphi :
 procedure TTextEditorForm.FormCreate(Sender: TObject);
 begin
   Editor.Lines.Add('');
   UpdateStatusBar;
 end;
C++ :
 void __fastcall TTextEditorForm::FormCreate(TObject *Sender)
 {
         TextEditorForm->Editor->Lines->Add(L"");
         UpdateStatusBar();
 }

Notez qu'avant d'appeler UpdateStatusBar, ce code ajoute une ligne vide à votre composant TMemo. Cette action initialise le nombre de lignes du mémo, de sorte que le libellé du nombre de lignes dans la barre d'état affiche "1" ligne à partir du début au lieu de "0" ligne.

Répétez les étapes ci-dessus avec les événements OnKeyUp et OnMouseUp de votre composant TMemo, que vous avez nommé Editor

Delphi :
 procedure TTextEditorForm.EditorKeyUp(Sender: TObject; var Key: Word;
   var KeyChar: Char; Shift: TShiftState);
 begin
   UpdateStatusBar;
 end;
 
 procedure TTextEditorForm.EditorMouseUp(Sender: TObject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Single);
 begin
   UpdateStatusBar;
 end;

C++ :

 void __fastcall TTextEditorForm::EditorKeyUp(TObject *Sender, WORD &Key, System::WideChar &KeyChar,
           TShiftState Shift)
 {
     UpdateStatusBar();
 }
 
 void __fastcall TTextEditorForm::EditorMouseUp(TObject *Sender, TMouseButton Button,
           TShiftState Shift, float X, float Y)
 {
     UpdateStatusBar();
 }

Création de gestionnaires d'événement pour les entrées du menu Fichier

Vous êtes maintenant prêt à définir les réponses aux clics sur les éléments de menu. Dans le Concepteur de fiches ouvert, sélectionnez NewAction dans la vue Structure :

IDETutorialSelectingNewAction.png

Sélectionnez ensuite l'onglet Evénements dans l'inspecteur d'objets, et double-cliquez sur la zone d'édition correspondant à l'événement OnExecute. L'éditeur de code s'ouvre et affiche un squelette pour votre nouveau gestionnaire d'événement. Ecrivez dans ce gestionnaire d'événement le code qui s'exécute lorsque les utilisateurs choisissent Fichier > Nouveau.

Delphi :
 procedure TTextEditorForm.NewActionExecute(Sender: TObject);
 var
   UserResponse: Integer;
 begin
   // Ask for confirmation if the memo is not empty.
   if not Editor.Text.IsEmpty then
   begin
     UserResponse := MessageDlg(
       'This will clear the current document. Do you want to continue?',
       TMsgDlgType.mtInformation, mbYesNo, 0);
     if UserResponse = mrYes then
     begin
       Editor.Text := '';
       Editor.Lines.Add(''); // Initialize the memo line count to "1".
       UpdateStatusBar;
       CurrentFile := ''; // New files have no file name until saved.
     end;
   end;
 end;
C++ :
 void __fastcall TTextEditorForm::NewActionExecute(TObject *Sender)
 {
     if (!TextEditorForm->Editor->Text.IsEmpty()) {
         int UserResponse = MessageDlg(
             L"This will clear the current document. Do you want to continue?",
             TMsgDlgType::mtInformation, mbYesNo, 0);
         if (UserResponse == mrYes) {
             TextEditorForm->Editor->Text = L"";
             TextEditorForm->Editor->Lines->Add(L"");  // Initialize the memo line count to "1".
             UpdateStatusBar();
             CurrentFile = L"";  // New files have no file name until saved.
         }
     }
 }

Cliquez sur l'onglet Conception pour revenir au Concepteur de fiches, et répétez le processus pour les actions restantes utilisées par les entrées du menu Fichier : OpenAction, SaveAction, SaveAsAction, ExitAction. Il s'agit des implémentations des gestionnaires d'événement de l'événement OnExecute de chacune de ces actions :

Delphi :
 // File > Open
 procedure TTextEditorForm.OpenActionExecute(Sender: TObject);
 var
   FileName: String;
 begin
   if OpenFileDialog.Execute = True then
   begin
     FileName := OpenFileDialog.FileName;
     if FileExists(FileName) then
     begin
       Editor.Lines.LoadFromFile(FileName);
       CurrentFile := FileName;
       Caption := 'Text Editor - ' + ExtractFileName(FileName);
     end;
   end;
 end;
 
 // File > Save
 procedure TTextEditorForm.SaveActionExecute(Sender: TObject);
 begin
   if CurrentFile = '' then
     SaveAsAction.Execute()
   else
     Editor.Lines.SaveToFile(CurrentFile);
 end;
 
 // File > Save As
 procedure TTextEditorForm.SaveAsActionExecute(Sender: TObject);
 var
   FileName: String;
   UserResponse: TModalResult;
 begin
   if SaveFileDialog.Execute = True then
   begin
     FileName := SaveFileDialog.FileName;
     if FileExists(FileName) then
     begin
       UserResponse := MessageDlg(
         'File already exists. Do you want to overwrite?',
         TMsgDlgType.mtInformation, mbYesNo, 0);
       if UserResponse = mrNo then
         Exit;
     end;
     Editor.Lines.SaveToFile(FileName);
     CurrentFile := FileName;
     Caption := 'Text Editor - ' + ExtractFileName(FileName);
   end;
 end;
 
 // File > Exit
 procedure TTextEditorForm.ExitActionExecute(Sender: TObject);
 begin
   Application.Terminate;
 end;
C++ :
 // File > Open
 void __fastcall TTextEditorForm::OpenActionExecute(TObject *Sender)
 {
     if (TextEditorForm->OpenFileDialog->Execute()) {
         String FileName = TextEditorForm->OpenFileDialog->FileName;
         if (FileExists(FileName)) {
             TextEditorForm->Editor->Lines->LoadFromFile(FileName);
             CurrentFile = FileName;
             Caption = L"Text Editor - " + ExtractFileName(FileName);
         }
     }
 }
 
 // File > Save
 void __fastcall TTextEditorForm::SaveActionExecute(TObject *Sender)
 {
     if (CurrentFile == L"") {
         TextEditorForm->SaveAsAction->Execute();
     } else {
         TextEditorForm->Editor->Lines->SaveToFile(CurrentFile);
     }
 }
 
 // File > Save As
 void __fastcall TTextEditorForm::SaveAsActionExecute(TObject *Sender)
 {
     if (TextEditorForm->SaveFileDialog->Execute()) {
         String FileName = TextEditorForm->SaveFileDialog->FileName;
         if (FileExists(FileName)) {
             String UserResponse = MessageDlg(
                 L"File already exists. Do you want to overwrite?",
                 System::Uitypes::TMsgDlgType::mtInformation,
                 System::Uitypes::TMsgDlgButtons() << System::Uitypes::TMsgDlgBtn::mbNo,
                 0);
             if (UserResponse == System::Uitypes::TMsgDlgBtn::mbNo) {
                 return;
             }
         }
         TextEditorForm->Editor->Lines->SaveToFile(FileName);
         CurrentFile = FileName;
         Caption = L"Text Editor - " + ExtractFileName(FileName);
     }
 }
 
 // File > Exit
 void __fastcall TTextEditorForm::ExitActionExecute(TObject *Sender)
 {
     Application->Terminate();
 }

Création de gestionnaires d'événement pour les entrées du menu Edition et Format

Pour implémenter les actions des entrées du menu dans les menus Edition et Format, vous devez suivre la même procédure que pour les actions du menu Fichier. Ces gestionnaires d'événement sont très simples : ils transmettent simplement l'action à votre mémo, car toutes les fonctionnalités requises sont déjà implémentées dans la classe TMemo, et ils appellent UpdateStatusBar si l'action peut avoir un effet sur la position du signe d'insertion ou sur le nombre de lignes.

Delphi :
 // Edit > Cut
 procedure TTextEditorForm.CutActionExecute(Sender: TObject);
 begin
   Editor.CutToClipboard;
   UpdateStatusBar;
 end;
 
 // Edit > Copy
 procedure TTextEditorForm.CopyActionExecute(Sender: TObject);
 begin
   Editor.CopyToClipboard;
 end;
 
 // Edit > Paste
 procedure TTextEditorForm.PasteActionExecute(Sender: TObject);
 begin
   Editor.PasteFromClipboard;
   UpdateStatusBar;
 end;
 
 // Edit > Select All
 procedure TTextEditorForm.SelectAllActionExecute(Sender: TObject);
 begin
   Editor.SelectAll;
   UpdateStatusBar;
 end;
 
 // Edit > Undo
 procedure TTextEditorForm.UndoActionExecute(Sender: TObject);
 begin
   Editor.UnDo;
   UpdateStatusBar;
 end;
 
 // Edit > Delete
 procedure TTextEditorForm.DeleteActionExecute(Sender: TObject);
 begin
   if Editor.SelLength > 0 then
     Editor.DeleteSelection
   else
     Editor.DeleteFrom(Editor.CaretPosition, 1, [TDeleteOption.MoveCaret]);
   UpdateStatusBar;
 end;
 
 // Format > Word Wrap
 procedure TTextEditorForm.WordWrapActionExecute(Sender: TObject);
 begin
   Editor.WordWrap := not Editor.WordWrap;
   WordWrapAction.Checked := Editor.WordWrap;
   UpdateStatusBar;
 end;
C++ :
 // Edit > Cut
 void __fastcall TTextEditorForm::CutActionExecute(TObject *Sender)
 {
     TextEditorForm->Editor->CutToClipboard();
     UpdateStatusBar();
 }
 
 // Edit > Copy
 void __fastcall TTextEditorForm::CopyActionExecute(TObject *Sender)
 {
     TextEditorForm->Editor->CopyToClipboard();
 }
 
 // Edit > Paste
 void __fastcall TTextEditorForm::PasteActionExecute(TObject *Sender)
 {
     TextEditorForm->Editor->PasteFromClipboard();
     UpdateStatusBar();
 }
 
 // Edit > Select All
 void __fastcall TTextEditorForm::SelectAllActionExecute(TObject *Sender)
 {
     TextEditorForm->Editor->SelectAll();
     UpdateStatusBar();
 }
 
 // Edit > Undo
 void __fastcall TTextEditorForm::UndoActionExecute(TObject *Sender)
 {
     TextEditorForm->Editor->UnDo();
     UpdateStatusBar();
 }
 
 // Edit > Delete
 void __fastcall TTextEditorForm::DeleteActionExecute(TObject *Sender)
 {
     if (TextEditorForm->Editor->SelLength > 0) {
         TextEditorForm->Editor->DeleteSelection();
     } else {
         TextEditorForm->Editor->DeleteFrom(
             TextEditorForm->Editor->CaretPosition, 1,
             Fmx::Memo::TDeleteOptions() << Fmx::Memo::TDeleteOption::MoveCaret);
     }
     UpdateStatusBar();
 }
 
 // Format > Word Wrap
 void __fastcall TTextEditorForm::WordWrapActionExecute(TObject *Sender)
 {
     TextEditorForm->Editor->WordWrap = !TextEditorForm->Editor->WordWrap;
     TextEditorForm->WordWrapAction->Checked = TextEditorForm->Editor->WordWrap;
     UpdateStatusBar();
 }

Suivant

Compilation et exécution de l'application