На этом уроке мы с вами продолжим писать
текстовый редактор MyEdit. Последнюю версию можно
посмотреть в уроке №9 и скачать здесь. Если вы
самостоятельно писали эту программу по урокам,
но настоятельно рекомендую скачать именно мою
версию, поскольку у нас может не совпадать
названия пунктов меню.
Итак, наша программа уже обладает почти всеми
стандартными функциями работы с простым текстом.
Напишем еще процедуры сохранения текста на диск.
Если редактируемый файл новый, то вместо
сохранения будет предложено файл "сохранить
как...", где пользователь должен указать имя
файла.
Для начала изменяем свойство Caption для окна ChildForm
на 'НОВЫЙ'. Это можно сделать и программно. Для
этого для реакции на событие OnCreate для этого
дочернего окна создаем процедуру.
procedure TChildForm.FormCreate(Sender: TObject);
begin
Caption:='НОВЫЙ'; // Заголовок окна нового файла
содержит название "НОВЫЙ"
end;
Теперь пишем процедуру нажатия на меню "Сохранить
как...". Для этого в главную форму MainForm
устанавливаем компонент TSaveDialog ,
находящейся на странице Dialogs палитры
компонентов. Поскольку фильтр отображаемых
файлов в диалоговых окнах открытия и сохранения
файла одинаков, то копируем строчку свойства Filter
для компонента OpenDialog1 в аналогичное
свойство для компонента SaveDialog1. Дальше с
помощью Object Inspector создаем процедуру реакции на
нажатие кнопки "Сохранить как...".
procedure TMainForm.N5Click(Sender: TObject);
begin
if MDIChildCount=0 then Exit; //если нет MDI
дочерних окон, то выйти из процедуры
SaveDialog1.Title:='Сохранить файл как...'; // заголовок
диалогового окна сохранения файла
if SaveDialog1.Execute then // если
пользователь выбрал название файла
begin
(ActiveMDIChild as
TChildForm).Memo1.Lines.SaveToFile(SaveDialog1.FileName); // сохранение
(ActiveMDIChild as TChildForm).Caption:=SaveDialog1.FileName; //
заголовок окна
end;
end;
Строка "ActiveMDIChild as TChildForm" позволяет
получить доступ из главного окна к активному
дочернему. Эта строка равноценна ChildForm,
только выполняется она только для активного окна.
После сохранения файла заголовок дочерн3о окна
содержит полный путь и название редактируемого
файла.
Делаем процедуру сохранения файла для пункта "Сохранить".
Следует при этом помнить, что если файл новый и
название не определено, то вместо этого
необходимо вызывать процедуру "Сохранить как..."
procedure TMainForm.N4Click(Sender: TObject);
begin
if MDIChildCount=0 then Exit; //если нет MDI
дочерних окон, то выйти из процедуры
if (ActiveMDIChild as TChildForm).Caption='НОВЫЙ'
then // если заголовок окна "НОВЫЙ", то
выполнять 1, иначе выполнять 2
N5Click(Sender) // 1. Идти в процедуру "Созранить как..."
else (ActiveMDIChild as
TChildForm).Memo1.Lines.SaveToFile((ActiveMDIChild as TChildForm).Caption); // 2.
Сохранить файл с именем, указанным в заголовке
end;
Получилась немного сложноватые строки даже для
специалиста. Но не пугайтесь этого. Все команды с
параметрами можно мысленно разбить на части, что
упрощает просмотр.
Если текст в текстовых редакторах меняется, то
обычно при выходе программа делает запрос на
сохранение измененных данных. Если ответить "Да",
то файл сохраняется. Если файл новый и не был ни
разу сохранен, то будет предложен диалог
сохранения файла под именем, или проще "Сохранить
как...". Если ответить "Нет", то файл (окно)
закроется без сохранения. Если нажать "Отмена",
то ничего с окном не произойдет и пользователь
продолжит редактирование.
Для окон есть событие OnCloseQuery, которое
следует применять именно в этих случаях. Оно
вызывается именно тогда, когда пользователь
пытается закрыть окно и в качестве вносимого
параметра CanClose определяет, может ли
продолжаться закрытие окна или нет.
У каждого компонента в Delphi есть свойство Tag. Оно
имеет тип Integer и является свойством, которым
пользуются только программисты. Tag в программе ни
на что не влияет. По умолчанию принимает нулевое
значение.
В нашей программе я предлагаю использовать его
для флага состояния редактирования. Если текст
изменяется, то он в последствии подлежит запросу
на сохранение.
Если свойство Tag для компонента Memo1
установлен в 0, то файл закрывается без
запросов, иначе - 1.
Событие OnChange для компонента Memo1:
procedure TChildForm.Memo1Change(Sender: TObject);
begin
Memo1.Tag:=1; // Текст изменен и подлежит запросу на
сохранение
end;
Тогда нам нужно убрать запрос на сохранение в
случае "ручного" сохранения файла, когда
пользователь сам выбрал необходимый пункт меню.
Изменяем следующие процедуры сохранения файла.
Процедура "Открыть"
procedure TMainForm.N3Click(Sender: TObject);
begin
if OpenDialog1.Execute then
begin
ChildForm:=TChildForm.Create(Self);
ChildForm.Memo1.Lines.LoadFromFile(OpenDialog1.FileName);
ChildForm.Caption:=OpenDialog1.FileName;
ChildForm.Memo1.Tag:=0; // добавить
end;
end;
Процедура "Сохранить как..."
procedure TMainForm.N5Click(Sender: TObject);
begin
if MDIChildCount=0 then Exit;
SaveDialog1.Title:='Сохранить файл как...';
if SaveDialog1.Execute then
begin
(ActiveMDIChild as
TChildForm).Memo1.Lines.SaveToFile(SaveDialog1.FileName);
(ActiveMDIChild as TChildForm).Caption:=SaveDialog1.FileName;
(ActiveMDIChild as TChildForm).Memo1.Tag:=0; // добавить
end;
end;
Процедура "Сохранить"
procedure TMainForm.N4Click(Sender: TObject);
begin
if MDIChildCount=0 then Exit;
if (ActiveMDIChild as TChildForm).Caption='НОВЫЙ' then
N5Click(Sender) else
begin // добавить
(ActiveMDIChild as TChildForm).Memo1.Lines.SaveToFile((ActiveMDIChild as
TChildForm).Caption);
(ActiveMDIChild as TChildForm).Memo1.Tag:=0; // добавить
end; // добавить
end;
Добавленные строки отделены комментарием "//добавить".
А теперь непосредственно создаем процедуру
OnCloseQuery для окна ChildForm.
procedure TChildForm.FormCloseQuery(Sender:
TObject;
var CanClose: Boolean);
Var Res:Integer; // переменная для хранения
результата выбора действия
begin
if Memo1.Tag=0 then // если не сохранять,
то 1, иначе - 2
begin // 1:
CanClose:=true; // можно закрыть окно
end else
begin // 2:
Res:=Application.MessageBox('Вы желаете сохранить изменения?','Вопрос',MB_YESNOCANCEL
+ MB_ICONQUESTION);
// вопрос на сохранение
if Res=IDYES then // нажата кнопка "Да"
begin
ChildForm.BringToFront; // Расположить данное окно выше всех
(сделать активным)
MainForm.N4Click(Sender); // Вызвать процедуру "Сохранить"
if Memo1.Tag=1 then CanClose:=false;
// если пользователь все-таки не сохранил файл, то
окно не закрывать
end;
if Res=IDNo then CanClose:=true; // если "Нет", то можно
закрыть
if Res=IDCANCEL then CanClose:=false; // если "Отмена", то не
закрывать
end;
end;
Находясь в редакторе кода в файле ChildUnit
необходимо подключить модуль главной формы MainUnit
через пункт меню "UseUnit".
Аналогом команды MessageBox в Delphi есть
команда MessageDLG. Более подробную
информацию как по этой, так и по другой можно
прочитать в справочной системе. Старайтесь
всегда при неизвестных командах пользоваться
подсказкой в справочной системе. Надо, чтобы
указатель (курсор) находился на интересующем вас
слове, и нажать комбинацию клавиш Ctrl+F1.
Архив примера текстового редактора с
сегодняшними изменениями вы можете забрать тут.
© www.nmarket.ru - при перепечатке прямая ссылка обязательна