Coding responses to user actions in the Code Editor (IDE Tutorial)
Go Up to Starting your first RAD Studio application Index (IDE Tutorial)
By following the instructions in this section, you will make your application interactive
and provide it with the functionality you want. You will code the event handlers, that is, the responses to clicking the various items in the main menu.
Beginning the code
Begin writing code by defining a String variable that you use
throughout the execution of the application to retain the name of the currently opened
text file. Make sure you are in Code Editor mode by selecting the Code tab, next
to the Design tab in the status bar. To toggle between Form Designer and Code Editor mode, press F12.
In Delphi, define a String variable called CurrentFile in the private section of the TTextEditorForm class in the interface part, as in the following figure.
Figure 3-18. Defining the CurrentFile private variable (Delphi view)
In C++, use the tabs at the bottom of the Code Editor window to display the
TextEditor.h file. Declare the currentFile variable in the private section of TTextEditorForm, as in the following figure.
Figure 3-19. Defining the currentFile private variable (C++Builder view)
Creating an event handler for the New command
You are now ready to define the responses to clicking menu items. In the Form Designer, click File > New on the menu bar in your text editor form. Then select the Events tab in the Object Inspector, as in the following image. Click the plus sign (+) to expand the Action list if necessary.
Figure 3-20. Opening the Events tab in the Object Inspector
Double-click the edit box corresponding to the OnExecute event. The Code Editor opens and displays the following function skeleton, using Delphi or C++Builder, respectively.
Figure 3-21. Automatic generation of the code skeleton for the OnExecute event (Delphi view)
Figure 3-22. Automatic generation of the code skeleton for the OnExecute event (C++Builder view)
Now write the code that executes when the user selects File > New inside the code skeleton previously generated, as in the following:
// New Delphi menu item event handler procedure TTextEditorForm.NewExecute(Sender: TObject); var UserResponse : Integer; begin // Check TMemo number of lines property if TextMemo.Lines.Count > 0 then begin UserResponse := MessageDlg( 'This will clear the current document. ' + 'Do you want to continue?' , mtInformation, mbYesNo, 0); if UserResponse = mrYes then begin TextMemo.Clear; CurrentFile := ''; end; end; end;
// New C++ menu item event handler void __fastcall TTextEditorForm::NewExecute(TObject *Sender) { // Check TMemo number of lines property if (TextMemo->Lines->Count > 0) { int userResponse = MessageDlg( String("This will clear the current document. ") + "Do you want to continue?", mtInformation, TMsgDlgButtons() << mbYes << mbNo, 0); if (userResponse == mrYes) { TextMemo->Clear(); currentFile = ""; } } }
Creating the event handlers for the Open command
Return to the form on the Design tab. Perform a set of steps similar to creating the handler for the New menu item.
Click File > Open on the menu bar in your text editor form. Select the Events tab in the Object Inspector and click the plus sign (+) to
expand the Action list if necessary.
Double-click the OnAccept event and write the code displayed below.
// Delphi procedure TTextEditorForm.FileOpen1Accept(Sender: TObject); var FileName: String; begin // Get file name from TFileOpen component FileName := FileOpen1.Dialog.FileName; if FileExists(FileName) then begin TextMemo.Lines.LoadFromFile(FileName); CurrentFile := FileName; Self.Caption := 'Text Editor - ' + ExtractFileName(FileName); end; end;
// C++ void __fastcall TTextEditorForm::FileOpen1Accept(TObject *Sender) { // Get file name from TFileOpen component String fileName = FileOpen1->Dialog->FileName; if (FileExists(fileName)) { TextMemo->Lines->LoadFromFile(fileName); currentFile = fileName; this->Caption = "Text Editor - " + ExtractFileName(fileName); } }
Creating the event handlers for the SaveAs command
Return to the form and double-click the OnAccept event of File > SaveAs and write the following code.
// Delphi procedure TTextEditorForm.FileSaveAs1Accept(Sender: TObject); var FileName: String; UserResponse : Integer; begin // Get file name from TFileSaveAs component FileName := FileSaveAs1.Dialog.FileName; if FileExists(FileName) then begin UserResponse := MessageDlg( 'File already exists. ' + 'Do you want to overwrite?' , mtInformation, mbYesNo, 0); if UserResponse = mrNo then Exit(); end; TextMemo.Lines.SaveToFile(FileName); CurrentFile := FileName; Self.Caption := ExtractFileName(FileName); end;
// C++ void __fastcall TTextEditorForm::FileSaveAs1Accept(TObject *Sender) { // Get file name from TFileSaveAs component String fileName = FileSaveAs1->Dialog->FileName; if (FileExists(fileName)) { int userResponse = MessageDlg( String( "File already exists. " ) + "Do you want to overwrite?" , mtInformation, TMsgDlgButtons() << mbYes << mbNo, 0); if (userResponse == mrNo) { return; } } TextMemo->Lines->SaveToFile(fileName); currentFile = fileName; this->Caption = ExtractFileName(fileName); }
Creating the event handlers for the Save command
Double-click the OnExecute event of File > Save and write the following lines of code.
// Delphi procedure TTextEditorForm.SaveExecute(Sender: TObject); begin if CurrentFile = '' then Self.FileSaveAs1.Execute() else TextMemo.Lines.SaveToFile(CurrentFile); end;
// C++ void __fastcall TTextEditorForm::SaveExecute(TObject *Sender) { if (currentFile == "") { this->FileSaveAs1->Execute(); } else { TextMemo->Lines->SaveToFile(currentFile); } }
Creating the event handlers for the Font command
Double-click the OnAccept event of Format > Font and write the following code.
// Delphi procedure TTextEditorForm.FontEdit1Accept(Sender: TObject); begin // Set TMemo font property TextMemo.Font := FontEdit1.Dialog.Font; end;
// C++ void __fastcall TTextEditorForm::FontEdit1Accept(TObject *Sender) { // Set TMemo font property TextMemo->Font = FontEdit1->Dialog->Font; }
Creating the event handlers for the Word Wrap command
Next, double-click the OnExecute event of Format > Word Wrap and write the following code.
// Delphi procedure TTextEditorForm.WordWrapExecute(Sender: TObject); begin { Toggle the word wrapping state. } TextMemo.WordWrap := not TextMemo.WordWrap; WordWrap.Checked := TextMemo.WordWrap; if TextMemo.WordWrap = True then { Only vertical scrollbars are needed when word wrapping is set. } TextMemo.ScrollBars := ssVertical else TextMemo.ScrollBars := ssBoth; end;
// C++ void __fastcall TTextEditorForm::WordWrapExecute(TObject *Sender) { // Toggle the word wrapping state. TextMemo->WordWrap = !TextMemo->WordWrap; WordWrap->Checked = TextMemo->WordWrap; if (TextMemo->WordWrap == True) { // Only vertical scrollbars are needed when word wrapping is set. TextMemo->ScrollBars = ssVertical; } else { TextMemo->ScrollBars = ssBoth; } }
Creating event handlers for the status bar
Use the status bar to display the current cursor position and the number of lines in the open text file. Double-click the OnMouseDown event
of the TextMemo component and write the following code, in Delphi and C++ respectively. The CaretPos property is used to indicate the coordinates of the cursor inside the text memo box.
// Delphi procedure TTextEditorForm.TextMemoMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin TextStatus.Panels.Items[ 0].Text := 'L: ' + IntToStr(TextMemo.CaretPos.Y + 1); TextStatus.Panels.Items[ 1].Text := 'C: ' + IntToStr(TextMemo.CaretPos.X + 1); TextStatus.Panels.Items[ 2].Text := 'Lines: ' + IntToStr(TextMemo.Lines.Count); end;
// C++ void __fastcall TTextEditorForm::TextMemoMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { TextStatus->Panels->Items[ 0]->Text = "L: " + String (TextMemo->CaretPos.y + 1); TextStatus->Panels->Items[ 1]->Text = "C: " + String (TextMemo->CaretPos.x + 1); TextStatus->Panels->Items[ 2]->Text = "Lines: " + IntToStr (TextMemo->Lines->Count); }
Finally, double-click the OnKeyDown event of TextMemo and write the code below. The OnKeyDown event is triggered whenever you press a key inside the text memo box.
// Delphi procedure TTextEditorForm.TextMemoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin // Perform same action as for mouse down in TMemo TextMemoMouseDown(Sender, mbLeft, Shift, 0, 0); end;
// C++ void __fastcall TTextEditorForm::TextMemoKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { // Perform same action as for mouse down in TMemo TextMemoMouseDown(Sender, mbLeft, Shift, 0, 0); }
