Задание 8
РАБОТА С ТЕКСТОМ
Цели:
Закрепление теоретических сведений по работе со строками
Приобретение практических навыков по выделению, копированию, удалению строк
Использование конструкций для обработки исключительных ситуаций.
Задание:
Создать новый проект. Изменить заголовок формы "Работа с текстом".
Назвать форму TextEditor и сохранить проект под именем Editor.dpr. (Не забывайте устанавливать фирменную иконку для формы, а также название и иконку для приложения и, конечно, подсказки ко всем кнопкам.)
Установить на форму компонент Panel1 и задайте его свойства (обязательно разобрать назначение этих и всех остальных свойств)
Align = alTop,
Caption = ‘’.
Установить на форму компонент Memo1 и задайте его свойства
Align = alClient,
Lines = ‘’,
WordWrap = TRUE,
ScrolBars = ssBoth,
HideSelection = False (при переходе фокуса к другому компоненту не гасится выделение выделенного текста).
Установить на форму компонент OpenDialog1 со свойствами:
DefaultExt = TXT,
Filter = Текстовые файлы \ *.txt \ Все файлы \ *.*
Title = Открытие текстового файла,
Options (установить в TRUE)
ofHideReadOnly - из окна диалога удаляется выключатель “Открыть только для чтения”
ofFileMustExist - генерируется сообщение об ошибке, если выбран несуществующий файл,
ofNoReadOnlyReturn - генерируется сообщение об ошибке, если выбран файл типа ReadOnly.
Установить на форму компонент SaveDialog1 со следующими свойствами
DefaultExt = TXT,
Filter = Текстовые файлы \ *.txt \ Все файлы \ *.*
Title = Сохранение текстового файла,
Options (установить в TRUE)
ofHideReadOnly
ofNoReadOnlyReturn
ofOverwritePrompt - . генерируется сообщение об ошибке, если выбран уже существующий файл.
Установить на панель кнопку с именем &Open и записать следующий обработчик события OnClick
With OpenDialog1 do
if Execute then begin
Memo1.Lines.LoadFromFile(FileName);
Caption:='TextEditor - '+ExtractFileName(FileName);
SaveDialog1.FileName:=FileName;
FileName:='';
end;
Установить на панель кнопку с именем &Save и с обработкой события OnClick:
Memo1.Lines.SaveToFile(SaveDialog1.FileName);
Установить на панель кнопку с именем Save&As и с обработкой события OnClick:
With SaveDialog1 do
if Execute then begin
Memo1.Lines.SaveToFile(FileName);
Caption:='TextEditor - '+ExtractFileName(FileName);
end;
Установить на панель кнопку с именем E&xit и с обработкой события OnClick:
Close
Поместить на форму компонент FontDialog1 с обработкой события OnApply:
Memo1.Font:=FontDialog1.Font
Разместить на панели кнопку с именем &Font и с обработкой события OnClick:
With FontDialog1 do
if Execute then Memo1.Font:=Font
Установить на форму компонент PrinterSetupDialog1.
Установить на панель кнопку с именем Print Set&up и с обработкой события OnClick:
PrinterSetupDialog1.Execute
Установить на форму компонент PrintDialog1
Установить на панель кнопку с именем &Print и с обработкой события OnClick:
var FileOut : TextFile;
k : Integer;
begin
if PrintDialog1.Execute then begin
AssignPrn(FileOut);
Rewrite(FileOut);
Printer.Canvas.Font:=Memo1.Font;
for k:=0 to Memo1.Lines.Count-1 do
Writeln(FileOut,Memo1.Lines[k]);
CloseFile(FileOut)
end;
end;
Процедуры работы с принтером находятся в модуле Printers. Укажите его имя в списке uses раздела interface модуля Unit1.
Поместить на панель кнопку с именем Fi&nd и с обработкой события OnClick:
FindDialog1.Execute
Поместить на панель кнопку с именем &Replace и с обработкой события OnClick:
ReplaceDialog1.Execute
Поместить на форму компоненты FindDialog1 и ReplaceDialog1 и установить в TRUE следующие общие свойства группы Options
frHideMachCase - прячет выключатель “С учетом регистра”,
frHideWholeWord - прячет выключатель “Только слово целиком”.
frHideUpDown - прячет кнопки выбора направления поиска.
Определить обработчик события OnFind компонента FindDialog1;
Таблица 8.1 – Обработчик события OnFind компонента FindDialog1
Текст обработчика |
Комментарий |
var Buff,FT,P : PChar; BuffLen : Integer; |
Описание вспомогательных переменных. |
Begin |
|
With Sender as TfindDialog do begin BuffLen:=Memo1.GetTextLen+1; GetMem(Buff,BuffLen); |
В начале процедуры указано, что используемые ниже свойства и методы будут относиться к объекту Sender (источник события), который рассматривается как объект класса TFindDialog. |
Продолжение таблицы 8.1
Текст обработчика |
Комментарий |
Memo1.GetTextBuf(Buff,BuffLen); GetMem(FT,Length(FindText)+1); |
Текст из Memo1 копируется в динамическую переменную Buff. Для этого в BuffLen заносится длина текста, под переменную Buff отводится память и выполняется копирование. |
StrPCopy(FT,FindText); |
Аналогично в динамическую переменную FT копируется содержимое строки поиска. |
P:=Buff+Memo1.SelStart+Memo1.SelLength; |
В переменную P заносится адрес начала поиска. |
P:=StrPos(P,FT); |
В переменную P заносится адрес подстроки, совпавшей с образцом для поиска. |
If P=Nil then MessageBeep(0) |
Если адрес нулевой (образец не найден), то генерируется звуковой сигнал. |
Else begin Memo1.SelStart:=P-Buff; Memo1.SelLength:=Length(FindText) end; |
Иначе, если образец найден, он выделяется в Memo1. |
FreeMem(FT); FreeMem(Buff,BuffLen); end; end; |
В завершении процедуры разрушаются динамические переменные. |
21). Для компонента ReplaceDialog1 в качестве обработчика события OnFind указать (в окне Object Inspector) обработчик этого же события компонента FindDialog1 (вот для чего в этой процедуре строка поиска FindText берется не у конкретного компонента FindDialog1 или ReplaceDialog1, а у источника события Sender).
22). Для компонента ReplaceDialog1 ввести текст обработчика события OnReplace.
Таблица 8.2
-
Текст обработчика
Комментарий
With ReplaceDialog1 do
Repeat
Организован цикл.
Продолжение таблицы 8.2
-
Текст обработчика
Комментарий
if Memo1.SelText<>FindText
then FindDialog1Find(Sender);
Если выделенный фрагмент не совпадает с образцом поиска, то вызовом обработчика события OnFind компонента FindDialog1 найти следующий совпадающий фрагмент.
if Memo1.SelLength=0 then Break;
Если фрагмент не найден, то завершить цикл.
Memo1.SelText:=ReplaceText;
Заменить выделенный фрагмент образцом для замены.
until not (frReplaceAll in Options);
Если не выбран режим “Заменить все”, то остановить цикл.
23). На панель добавить кнопку, позволяющую выполнить действия согласно варианту Таблицы 8.3
Таблица 8.3
-
Вариант
Задание
1, 6, 11, 16, 21, 26
Отсортировать текст по числу слов в строке
2, 7, 12, 17, 22, 27
Переставить строки в обратном порядке
3, 8, 13, 18, 23, 28
Отсортировать текст по числу цифр в строке
4, 9, 14, 19, 24, 29
Отсортировать текст по числу лидирующих пробелов в строке
5, 10, 15, 20, 25, 30
Переставить строки по правилу 0-1, 2-3, 4-5,…
24). На панель добавить кнопку, позволяющую сохранить в файле ‘my.txt’. Числа K и L вводятся в компоненте SpinEdit, расположенном на панели (значения в SpinEdit должны соответствовать состоянию текста).
Таблица 8.4
-
Вариант
Задание
1, 7, 13, 19, 25
Последние K строк
2, 8, 14, 20, 26
Строки с четным числом слов
3, 9, 15, 21, 27
K строк начиная с L-ой
4, 10, 16, 22, 28
Строки, в которых ровно K слов
5, 11, 17, 23, 29
Строки, в которых есть одинаковые слова
6, 12, 18, 24, 30
Строки, в которых все символы различные
25). На панель добавить кнопку, позволяющую считать из файла (имя файла определяется в окне диалога) строки из задания 2 (вариант - следующий после Вашего). Строки или заменяют существующий текст, или добавляются к нему (в начало, в конец, после N-ой строки – на выбор пользователя). Все настройки определяются на диалоговой панели, заменяющей основную на время диалога. Предусмотреть возможность отмены диалога.
26). Добавить кнопку для выбора цвета фона текста.
27). С помощью компонента TMainMenu организовать главное меню проекта, разумно расположив в нем функции всех кнопок основной панели. (Назначать уже готовые обработчики для события OnClick пунктов меню).
28). При работе приложения определять выделенную строку текста(Таблица 8.5).
29). Среди прочих компонент Memo обладает рядом свойств, доступных только во время работы приложения
30). Следующий программный код позволяет определить положение курсора в компоненте Memo1:
var X,Y : Integer;
begin
Y:=Memo1.Perform(EM_LINEFROMCHAR, Memo1.SelStart, 0);
X:=Memo1.Perform(EM_LINEINDEX, Y, 0);
Y:=Y+1;
X:=Memo1.SelStart-X+1;
end;
Таблица 8.5
Свойство |
Значение |
SelText |
Выделенный фрагмент текста |
SelLength |
Длина выделенного фрагмента |
SelStart |
Номер первого символа выделенного фрагмента начиная с начала всего текста. Если выделения нет, то позиция курсора внутри текста |
Modified |
TRUE, если текст был изменен. |
30). Следующий программный код позволяет определить положение курсора в компоненте Memo1:
var X,Y : Integer;
begin
Y:=Memo1.Perform(EM_LINEFROMCHAR, Memo1.SelStart, 0);
X:=Memo1.Perform(EM_LINEINDEX, Y, 0);
Y:=Y+1;
X:=Memo1.SelStart-X+1;
end;
31). Для отмены действий в редакторе Memo1 можно воспользоваться следующим кодом:
Memo1.Perform(EM_UNDO, 0, 0);
Проверить возможность отмены действий можно, сравнив с нулем значение функции:
Memo1.Perform(EM_CANUNDO, 0, 0);
Контрольные вопросы
Определить используемые свойства всех компонентов приложения
Представить формы обеспечения диалогов
Назвать события обработки ошибок
Определить возможности текстового редактора
Как организовать поиск
Формы определения настройки принтера