Пишем текстовый редактор

В этой статье мы попробуем вместе написать текстовый редактор.

Курс начинающего программиста в Дельфи

Пишем текстовый редактор

В этой статье мы попробуем вместе написать текстовый редактор. Тут есть два варианта: создавать редактор наподобие Microsoft Word (имеется ввиду редактор для форматированного текста), или что-то вроде Блокнота. Предлагаю Вам пойти по первому пути, так как знаний вы получите больше и редактор выйдет красивее. А если вам будет сильно нужно, то Вы сами сможете создать Ваш Блокнот!

Теперь надо выбрать основной компонент для создания редактора. Выбор между компонентом Memo и RichEdit. Для нашего редактора мы выберем RichRdit (находится на вкладке Win32), потому что он поддерживает абзацы, нумерацию, цветовое выделение текста и т.д.

Поместив его на форму вы увидите примерно то, что  изображено на рисунке. Пока это не очень похоже на текстовый редактор, но скоро он преобразится. Теперь нам необходимо растянуть компонент, чтобы он занимал всю рабочую площадь окна. Но при этом надо помнить, что при изменении размеров окна пользователем, компонент тоже должен изменять свои размеры! 

Для этого мы воспользуемся свойством Align нашего компонента. Необходимо установить его в alClient. Это позволит нам добиться желаемого эффекта. 

В компоненте RichEdit при установке уже содержится одна строка текста (по умолчанию это имя вновь созданного компонента), многим это не понравится. Поэтому мы сейчас ее оттуда удалим. За отображение текста в компоненте отвечает свойство Lines типа TStrings. Это что-то вроде массива строк, так как каждая строка имеет свой порядковый номер (отсчет начинается с нуля). Чтобы изменить, например, первую строку, Вы должны написать так:

RichEdit1.Lines[0]:='Новая строка'; 

Если эту строку поместить в событие формы OnCreate, а в кавычках вместо Новая строка ничего не ставить (то есть просто RichEdit1.Lines[0]:='';), то при запуске программы первая строка будет пустой. Но можно все сделать намного проще! Нажмите на форме на Ваш компонент RichEdit, а теперь в Инспекторе Объектов найдите свойство Lines. Нажмите на него, а затем на кнопку с тремя точками. Перед Вами появится редактор текста. Просто сотрите все содержимое. 

Надо придумать какое-нибудь название вашей новой программе и разместить его в заголовок формы. За отображение формы отвечает свойство Caption, поэтому прямо в Инспекторе Объектов измените это значение. (не забудьте перед этим выбрать форму). 

Теперь нам надо создать панель инструментов (ToolBar), на которой будут располагаться кнопки быстрого вызова команд (например, Открыть, Сохранить и т.д.). Для этого расположите на форме компонент Panel (вкладка Standart палитры компонентов). Сотрите у нее свойство Caption. Теперь надо сделать, чтобы панель располагалась всегда в верхней части окна. Установите свойство панели - Align равным alTop.

Мы только что создали платформу, на которой будут находиться кнопки. Разместим и их на нашей панели. Пока обойдемся двумя кнопками (Button). Свойство Caption первой панели сделайте равным Открыть, второй - Сохранить. 

Чтобы нам открывать и сохранять текстовые файлы нам понадобятся еще два компонента, это OpenDialog и SaveDialog. Оба находятся на вкладке Dialogs. Это невизуальные компоненты и их не будет видно во время работы приложения, поэтому располагайте их в любое удобное  место вашей формы.

Ну вот подготовительные работы окончены и Вас должно получиться примерно это:

Я не стал помещать всю картинку целиком, так как это заняло бы много места, к тому же там нет ничего интересного!

Ну вот и настал самый интересный момент - сейчас мы начнем писать сам код! Для начала напишем процедуру открытия файла. Чтобы сделать это надо обработать нажатие на первую кнопку - то есть обработать событие OnClick. Щелкните два раза на кнопке и перед вами откроется редактор кода. Причем именно в том месте, где и надо помещать нужные команды. Текст будет таким:

procedure TForm1.Button1Click(Sender: TObject);
begin

end;

Весь код нужно поместить между Begin и End. Этот код очень прост и выглядит примерно так:

if OpenDialog1.Execute then
RichEdit1.Lines.LoadFromFile(OpenDialog1.Filename);

Здесь ничего сложного нет. Но если вы запустите программу и при  запуске диалога открытия файла выберите не текстовый файл, то произойдет ошибка. Чтобы ее избежать надо разрешить пользователю выбирать только текстовые файлы. Для это воспользуемся свойством Filter компонента OpenDialog.

Для этого выберите на форме компонент OpenDialog, и в Инспекторе Объектов найдите свойство Filter. Теперь нажмите на кнопку с тремя точками и перед вами откроется диалоговое окно "Filter Editor" (Редактор фильтра) (Рисунок 3). В поле Filter Name (имя фильтра) можно писать что вам вздумается, но характеризующее тип файлов, для которого создается фильтр. В нашем примере можно написать что-то наподобие Текстовые файлы или Только текст. А в поле Filter надо написать сам фильтр. Фильтр имеет формат:

Имя_файла . Расширение

Если допустимо любое имя, то ставится звездочка, тогда для нашего редактора можно написать:

*.txt

Добавим еще фильтр для форматированных файлов (то есть Rich Text Format). Для этого во второй строчке в поле Filter Name напишите Форматированный текст, а в поле FIlter - *.rtf. Если вам захочется добавить в фильтр для любых типов файлов, то в поле фильтр надо написать *.*

Рисунок 3. Окно Filter Editor.

Теперь вам необходимо проделать такие же действия с компонентом SaveDialog, чтобы наш текстовый редактор сохранял файлы в текстовом формате.

Кстати у компонентов SaveDialog и OpenDialog есть одно полезное свойство DefaultExt. Это расширение по умолчанию. Желательно сделать его равным *.txt у обоих компонентов.

Теперь напишем процедуру сохранения файла (обработки нажатия на вторую кнопку). Щелкните два раза на второй кнопке чтобы получить доступ к процедуре обработки клика на эту кнопку. И впишите туда такой код:

if SaveDialog1.Execute then
RichEdit1.Lines.SaveToFile(SaveDialog1.Filename);

Таким образом код процедуры обработки щелчка на второй кнопке будет таким:

procedure TForm1.Button2Click(Sender: TObject);
begin
if SaveDialog1.Execute then
RichEdit1.Lines.SaveToFile(SaveDialog1.Filename);
end;

А код всей программы будет иметь примерно такой вид: 

Листинг 1. Код наполовину готовой программы ТЕКСТОВЫЙ РЕДАКТОР

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, ExtCtrls;

type
TForm1 = class(TForm)
RichEdit1: TRichEdit;
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
RichEdit1.Lines.LoadFromFile(OpenDialog1.Filename);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if SaveDialog1.Execute then
RichEdit1.Lines.SaveToFile(SaveDialog1.Filename);
end;

end.

В принципе примитивный текстовый редактор готов, но нам нужно большего :)) к тому же нам надо учиться. Если вы заметили, что при открытии больших файлов не появляется полоса прокрутки. Конечно же это недостаток, поэтому мы сейчас его исправим. За отображение полос прокрутки компонента RichEdit отвечает свойство ScrollBars. Оно сложное и вы можете выбрать из:

  • ssNone - полосы прокрутки не отображаются

  • ssBoth - есть как горизонтальная, так и вертикальная полоса

  • ssVertical - только вертикальная полоса

  • ssHorizontal - только горизонтальная полоса

Выберите ssVertical - это обеспечит нам появление вертикальной полосы прокрутки при редактировании больших текстов.

Пишем текстовый редактор

Продолжим совершенствовать наш редактор и добавим возможность форматирования текста. То есть изменение его размера, стиля, цвета и т.д. Можно конечно все прописывать самостоятельно, но зачем тратить время и силы на это если есть компонент FontDialog (находится на вкладке Dialogs). Он реализует стандартный диалог Windows настройки шрифта. Нам нужно будет его только вызвать!

Значок компонента FontDialog.

Для этого установим его на форму. К тому же нам понадобится еще и кнопка, чтобы вызывать это диалоговое окно. Поставим на форму и ее. Задайте ее свойство Caption равным Шрифт. А в обработчике события OnCLick напишите:

if FontDialog1.Execute then
RichEdit1.SelAttributes.Assign(FontDialog1.Font);

Этот код позволит с помощью диалогового окна настройки шрифта изменят шрифт для каждого отдельного абзаца, слова, символа или всего текста.

На рисунке 4 приведен вид приложения после добавления третьей кнопки и компонента FontDialog.

Рисунок 4.

В наш проект нужно добавить еще очень много функций, а поэтому и кнопок, но место к сожалению, у нас ограничено. Но мы решим эту проблему с помощью использования в нашей программе системного и всплывающего меню.

Дальше части займемся разработкой системного меню нашей программы.

Как уже говорилось в конце прошлой главы сейчас займемся разработкой главного меню нашего приложения! Для этого мы воспользуемся компонентом MainMenu, который расположен на вкладке Standart палитры компонентов.

Значок компонента MainMenu.

Для того, чтобы можно было редактировать пункты меню следует воспользоваться встроенным редактором меню. Выделите компонент MainMenu, а затем в Инспекторе Объектов найдите свойство Items и нажмите на кнопку с тремя точками. Перед вами откроется диалоговое окно, вид которого изображен на рисунке 17

Рисунок 17.

Соответственно поля Инспектора Объектов тоже изменятся. Написав в свойстве Caption выделенного элемента вы тем самым изменяете надпись на нем. Нам понадобится такая структура меню:

     

"Файл"            "Правка" "?"

Открыть

Сохранить

Выход

Копировать

Вырезать

Вставить

Настроить Шрифт

О программе...

   

Нажимая на элемент меню в редакторе меню, вы получаете доступ к его свойствам, а также доступ к следующему элементу, который создается автоматически. Впрочем если вы его не задействовали, то в меню он не будет виден!

На рисунке 18 приведен вид нашего меню. Его совсем не сложно будет создать!

Рисунок 18.

Теперь надо создать обработчики событий для пунктов нашего меню. Перейдите на форму, нажмите на меню файл и  в раскрывшемся меню выберите первый пункт - "Открыть". Перед вами откроется редактор кода с созданным шаблоном обработки события (как всегда Дельфи берет много работы на себя:). Будет это выглядеть примерно так:

procedure TForm1.N2Click(Sender: TObject);
begin

end;

Теперь между begin и end надо написать код. Но тут есть одна маленькая хитрость: конечно, можно было бы скопировать код из обработчика события OnClick для первой кнопки, но это не совсем удобно и не рационально!!! Представьте если у вас множество кнопок и столько же пунктов меню. Во-первых размер программы увеличивается вдвое, а во-вторых вдруг вам понадобиться что-нибудь изменить!!! Тогда придется все перебирать исправляя код.

Поэтому мы сделаем всего лишь ссылку на обработку события для первой кнопки.  Напишите button1  и поставьте точку, когда появиться список возможных процедур, функций и свойств начинайте набирать On. Теперь вы видите события первой кнопки на которые можно сослаться. Нам конечно же нужно OnClick. У этой функции есть один параметр: Source: TObject. То есть надо указать источник события. Мы напишем Self. Таким образом, ссылка на обработчик события нажатия на первую кнопку будет выглядеть так:

button1.OnClick(self);

Проделайте тоже со пунктами меню "Шрифт" и "Сохранить". 

Теперь напишем обработчик нажатия на пункт меню "Выход". Для завершения работы программы достаточно вызвать метод Close главной формы. Поскольку форма у нас одна, она и является главной. И еще, если свойство относится к форме, то в коде можно не писать имя формы. То есть закрыть нашу программу можно так:

Form1.Close;

или так:

Close;

Если вы обратили внимание в меню правка находятся пункты Копировать, Вставить и Вырезать. Реализовать эти функции очень просто:

RichEdit1.CopyToClipboard;

RichEdit1.PasteFromClipboard;

RichEdit1.CutToClipboard;

Ну и на последок. В меню "?" есть пункт "О программе...". Сделаем, чтобы при нажатии открывалась новая форма с информацией о программе и авторе. Для этого в меню File основного меню Дельфи выберите New, а в открывшемся диалоговом окне на закладке Forms выберите AboutBox и нажмите Ok. Перед вами появиться заготовка формы "О программе...". 

Измените там информацию по своему вкусу. И в обработчик события кнопки с надписью Ok (OKButton) напишите только одно слово: Close;

Теперь перейдите к нашей основной форме, создайте обработчик события OnClick для пункта меню О программе. Туда надо написать:

AboutBox.ShowModal;

Теперь запустите программу. Перед вами появится сообщение о том, что форма AboutBox не объявлена в секции uses. Ответьте на запрос положительно.

ГОТОВО!!!

Поздравляю! Работа над вашим первым текстовым редактором окончена. Скорее сохраняйте ваш проект, компилируйте и бегите хвастаться друзьям!

Скачать готовые исходные коды этого текстового редактора можно здесь.

Привожу весь код целиком:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, ExtCtrls, Menus;

type
TForm1 = class(TForm)
RichEdit1: TRichEdit;
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
Button3: TButton;
FontDialog1: TFontDialog;
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
N6: TMenuItem;
N7: TMenuItem;
N8: TMenuItem;
N9: TMenuItem;
N10: TMenuItem;
N11: TMenuItem;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure N3Click(Sender: TObject);
procedure N9Click(Sender: TObject);
procedure N6Click(Sender: TObject);
procedure N7Click(Sender: TObject);
procedure N8Click(Sender: TObject);
procedure N11Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
RichEdit1.Lines.LoadFromFile(OpenDialog1.Filename);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if SaveDialog1.Execute then
RichEdit1.Lines.SaveToFile(SaveDialog1.Filename);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
if FontDialog1.Execute then
RichEdit1.SelAttributes.Assign(FontDialog1.Font);
end;

procedure TForm1.N2Click(Sender: TObject);
begin
button1.OnClick(self);
end;

procedure TForm1.N3Click(Sender: TObject);
begin
button2.OnClick(self);
end;

procedure TForm1.N9Click(Sender: TObject);
begin
button3.OnClick(self);
end;

procedure TForm1.N6Click(Sender: TObject);
begin
RichEdit1.CopyToClipboard;
end;

procedure TForm1.N7Click(Sender: TObject);
begin
RichEdit1.PasteFromClipboard;
end;

procedure TForm1.N8Click(Sender: TObject);
begin
RichEdit1.CutToClipboard;
end;

procedure TForm1.N11Click(Sender: TObject);
begin
AboutBox.showmodal;
end;

end.


Опубликовал admin
28 Авг, Четверг 2003г.



Программирование для чайников.