The TMemo Component


The TMemo component is a multiline text box that enables us to load, edit, and save plain text files. The contents of the text file are stored in the Lines property.

Listing 15-4 shows how to use the TMemo and TListBox components to emulate Delphi's Code Editor and its code completion feature.

image from book
Figure 15-19: Code completion

Start by creating a new VCL Forms application project and then drop a TMemo component on the Designer Surface. Rename the TMemo component Editor.

The first thing that we have to do is dynamically create a TListBox component that will be displayed when the user types a period (full stop) in the editor.

Listing 15-4: Creating the code completion list

image from book
type   TMainForm = class(TForm)     Editor: TMemo;     procedure FormCreate(Sender: TObject);   private     { Private declarations }   public     { Public declarations }     CodeList: TListBox;   end; var   MainForm: TMainForm; implementation {$R *.dfm} procedure TMainForm.FormCreate(Sender: TObject); begin   CodeList := TListBox.Create(Self);   CodeList.Parent := Editor;   CodeList.Visible := False;   CodeList.Width := 200;   CodeList.Height := 100;   CodeList.Items.Add('Caption');   CodeList.Items.Add('Top');   CodeList.Items.Add('Left'); end;
image from book

Now that we have the code completion list, we have to write code that displays it when the user types a period (full stop) in the editor. The best place for this code is the OnKeyPress event of the Editor component.

Listing 15-5: Displaying the code completion list

image from book
procedure TMainForm.EditorKeyPress(Sender: TObject; var Key: Char); var   CliPos: TPoint;   ListX: Integer;   ListY: Integer; begin   if Key = '.' then   begin     { get caret position }     GetCaretPos(CliPos);     { adjust list position }     ListX := CliPos.X;     ListY := CliPos.Y + CodeList.Canvas.TextHeight('W') + 4;     if ListX + CodeList.Width >= Editor.Width then       ListX := Editor.Width - CodeList.Width - 20;     if ListY + CodeList.Height >= Editor.Height then       ListY := Editor.Height - CodeList.Height - 20;     CodeList.Top := ListY;     CodeList.Left := ListX;     CodeList.ItemIndex := 0;     CodeList.Visible := True;     CodeList.SetFocus;   end else     CodeList.Visible := False; end;
image from book

The most important thing when displaying the code completion list is to display it as close to the caret as possible. To get the position of the caret in pixels, we have to use the Windows API GetCaretPos function. After we read the caret's position with the GetCaretPos function, we have to adjust it so that the list appears beneath the line that contains the caret. This adjustment is done by calling the Canvas.TextHeight method to calculate the height of a line in the editor. In this case, we can call the CodeList's TextHeight method because both the Editor and CodeList components use the same font.

If you run the application now and type a period in the editor, you will see the custom code completion list.

image from book
Figure 15-20: The code completion list

Finally, we have to write the code completion code — the code that adds the selected item from the code completion list to the editor.

Listing 15-6: Code completion

image from book
procedure TMainForm.CodeListClick(Sender: TObject); var   currentLine: Integer; begin   if CodeList.ItemIndex <> -1 then   begin     currentLine := Editor.CaretPos.Y;     { add text from the list to the editor }     Editor.Lines[currentLine] := Editor.Lines[currentLine] +       CodeList.Items[CodeList.ItemIndex];   end;   CodeList.Visible := False;   Editor.SetFocus; end;
image from book

To determine the X and Y coordinates of the caret, we can use the TMemo's CaretPos property. The difference between the GetCaretPos function and the CaretPos property of the TMemo component is that the CaretPos property doesn't contain pixel values. The X value of the CaretPos property specifies the horizontal coordinate of the caret, in characters. The Y value of the CaretPos property specifies the vertical coordinate of the caret, the index of the line that contains the caret.

The last thing we have to do is assign the CodeListClick method to the OnDblClick event of the CodeList component in the OnCreate event handler.

Listing 15-7: Creating the code completion list, revisited

image from book
procedure TMainForm.FormCreate(Sender: TObject); begin   CodeList := TListBox.Create(Self);   CodeList.Parent := Editor;   CodeList.Visible := False;   CodeList.Width := 200;   CodeList.Height := 100;   CodeList.Items.Add('Caption');   CodeList.Items.Add('Top');   CodeList.Items.Add('Left');   CodeList.OnDblClick := CodeListClick; end;
image from book



Inside Delphi 2006
Inside Delphi 2006 (Wordware Delphi Developers Library)
ISBN: 1598220039
EAN: 2147483647
Year: 2004
Pages: 212
Authors: Ivan Hladni

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net