Учебный центр "ANIT Texno Inform"
Опубликован: 25.06.2014 | Доступ: платный | Студентов: 24 / 0 | Длительность: 24:39:00
Специальности: Программист
Лекция 13:

Коллекции (массивы) строк и компоненты для них

< Лекция 12 || Лекция 13: 12 || Лекция 14 >
Аннотация: В лекции рассматривается тип TStrings, который является базовым типом массивов строк, а также компоненты TMemo, TListBox и TComboBox, которые используют этот тип. Изучаются основные возможности TStrings. Материал подкрепляется практической работой, в которой учащиеся знакомятся со способами обработки строк: их редактированием, сохранением в текстовый файл, считыванием из файла и прочее.

Цель лекции

Изучение типа TStrings и компонентов TMemo, TListBox и TComboBox.

Компонент TMemo

До сих пор для предоставления пользователю возможности ввести текст мы использовали компоненты вроде TEdit, с помощью которых можно ввести только одну строку текста. Компонент TMemo - это, по сути, целый текстовый редактор! Не верите? Давайте посмотрим. Откройте Lazarus с новым проектом. Сразу же переименуйте форму в fMain (свойство Name), в свойстве Caption напишите Мой Блокнот. Сохраните проект как MyNotebook в папку 14-01, а модулю дайте имя Main. Установим некоторые другие параметры формы. Прежде всего, форма будет содержать редактор текстов, поэтому она не должна быть маленькой. Давайте сделаем следующие установки в свойствах формы:

Height = 450
Width = 750
Position = poDesktopCenter
    

Далее, на вкладке Standard Палитры компонентов найдите компонент TMemo:

Компонент TMemo

Рис. 14.1. Компонент TMemo

Установите его на форму. Теперь давайте рассмотрим, как следует, свойства компонента TMemo - уже известные по другим компонентам свойства мы рассматривать не будем, остановимся только на новых и специфичных для TMemo (компонент должен быть выделен).

BorderStyle - Включает/отключает обрамление вокруг компонента, и может быть:
  • bsNone - нет обрамления
  • bsSingle - есть обрамление (по умолчанию)
CharCase - задает регистр выводимых в компоненте символов. Может быть:
  • ecLowerCase - все символы строчные
  • ecNormal - символы такие, какими их вводит пользователь (по умолчанию)
  • ecUppercase - все символы прописные
Color - цвет текстового поля. Вы можете задавать цвет как текстового поля, так и шрифта, однако имейте в виду, что серьезные программы не делаются с яркими попугайскими расцветками, поэтому желательно компонентам оставлять их стандартные цвета.
Font - шрифт текста в компоненте. Свойство имеет кнопку "", с помощью которой его можно раскрыть и настроить шрифт: название шрифта, его размер, начертание, цвет и видоизменение. Насчет расцветок шрифта здесь справедливо то же замечание, что и для свойства Color. Начертание (простой шрифт, курсив, полужирный, полужирный курсив) тоже без нужды изменять не стоит. А вот что касается названия шрифта и его размера - их изменить можно. Дело в том, что по умолчанию в компоненте установлен мелкий шрифт, а у некоторых пользователей может быть слабое зрение. Чтобы пользователь зря не напрягал глаза, я обычно устанавливаю шрифт Times New Roman (он выглядит привлекательней) 12-го размера. Шрифт получается достаточно крупным. Вы можете поэкспериментировать с разными шрифтами и размерами и подобрать то, что нравится лично вам. Только еще одно замечание: если вы полагаете, что ваша программа будет работать и на других компьютерах, то желательно выбирать стандартные шрифты. Если вы установите какой-то экзотический шрифт, которого у пользователя может и не быть, то программа у него не будет работать нормально. Пользователю придется дополнительно искать и устанавливать ваш шрифт, а они обычно не терпят таких неудобств, и скорее предпочтут какую-то другую, аналогичную программу.
HideSelection - включает или выключает выделение текста, когда компонент теряет фокус. Если равно True, то выделение текста скрывается, когда активным становится другой компонент. При False выделение остается. Обычно оставляют значение по умолчанию - True.
Lines - коллекция (массив) строк. Позволяет обращаться как ко всему тексту, так и к его отдельным строкам. Это сложное свойство, которое имеет свои свойства, методы и события. Методы - это то, что компонент умеет делать. Это те же самые процедуры и функции. Lines это свойство, но и у него есть методы, с помощью которых можно сохранять текст в файл, считывать его из файла, делать еще много других полезных вещей. Имеет тип TStrings. Мы вернемся к нему чуть позже, фактически, вся эта лекция посвящена работе с типом TStrings.
MaxLength - максимальная длина вводимого пользователем текста. По умолчанию, свойство равно нулю. Это означает, что ограничений на размер текста нет.
ReadOnly - переводится как "Только для чтения". По умолчанию, равно False - пользователь может как читать, так и редактировать текст. Если установить в True, пользователь не сможет изменять текст. Так делают, когда нужно вывести для пользователя многострочный текст, например, текст лицензии или описание программы в окне "О программе". Мы оставим False, так как сейчас нам нужно, чтобы пользователь мог редактировать текст.
ScrollBars - полосы прокрутки компонента. Может быть:
  • ssNone - нет полос прокрутки.
  • ssHorizontal - горизонтальная полоса прокрутки, располагается по нижнему краю компонента. Неактивна, пока текст строки умещается на экране. Когда он становится больше, полоса становится активной, и пользователь может прокрутить текст по горизонтали.
  • ssVertical - вертикальная полоса прокрутки, располагается по правому краю компонента. Неактивна, пока все строки умещаются на экране. Когда строк больше, полоса прокрутки становится активной, и пользователь может прокручивать текст вверх-вниз.
  • ssBoth - присутствуют как вертикальная, так и горизонтальная полосы прокрутки.
  • ssAutoHorizontal - отличается от ssHorizontal тем, что пока текст умещается в окне, полоса прокрутки невидима. По крайней мере, так задумывалось разработчиками. На деле же, ssAutoHorizontal ведет себя так же, как и ssHorizontal - полоса видима, но неактивна, пока текст умещается в окне. Будем надеяться, что в будущем разработчики Lazarus исправят эту ошибку.
  • ssAutoVertical - то же, что и ssAutoHorizontal, но для вертикальной полосы прокрутки.
  • ssAutoBoth - то же, что и ssAutoHorizontal, но для обеих полос прокрутки.
WantReturns - тоже недоработанное свойство. По идее, если его установить в False, пользователь не сможет клавишей <Enter> вставлять разрывы строк. Однако новые строки по-прежнему вставляются клавишей <Enter> вне зависимости от установок этого свойства.
WantTabs - вот это свойство работает. Если оно установлено в False (по умолчанию), то пользователь не сможет клавишей <Tab> вставлять знаки табуляции - эта клавиша будет переключать фокус с TMemo на другой компонент, если он есть. Если же свойство установить в True, то пользователь сможет вставлять знаки табуляции. Разрешать ему вставку табуляции или нет, зависит от назначения компонента. Если вам нужно простое поле, чтобы пользователь мог ввести несколько строк текста, то табуляцию можно и не разрешать. Если же вам нужно сделать полноценный текстовый редактор, то табуляция необходима.
WordWrap - разрешает или запрещает перенос текста на новую строку. Если установлено True (по умолчанию), то когда текст достигает края, происходит автоматический переход на новую строку. Если установлено False, то строка будет продолжаться, пока пользователь не нажмет <Enter>. Обычно свойство оставляют в True и устанавливают вертикальную полосу прокрутки. Если вам захочется установить False, позаботьтесь о том, чтобы была установлена и горизонтальная полоса прокрутки.

В Инспекторе объектов отсутствует еще одно важное свойство: Text. Это свойство имеет тип String и содержит весь текст, все строки разом, включая символы перехода на новую строку.

Итак, займемся настройкой компонента TMemo. Имя оставим по умолчанию: Memo1. Свойства Left и Top установите в 5. Свойство Height установите равным 400, а Width - 740. Компонент занял почти всю форму, оставив небольшие бордюры и место для кнопок снизу. Теперь нам нужно привязать компонент к сторонам, чтобы он автоматически изменял размер при изменении пользователем размеров окна. Для этого разверните свойство Anchors (якоря) и установите в True все его четыре подсвойства.

Далее, нам как-то нужно убрать текст "Memo1" из компонента, который был добавлен в поле автоматически. Для этого выделите свойство Lines и щелкните по её кнопке "". Это приведет к открытию окна диалога ввода строк. Сотрите там весь текст и нажмите "ОК" - текст в компоненте пропал.

Теперь установите вертикальную полосу прокрутки (ScrollBars = ssVertical) и убедитесь, что в WordWrap установлено True - компонент будет автоматически переносить текст на новые строки.

Вот, собственно, и все настройки. Теперь нам нужно добиться от компонента трех вещей: чтобы он сохранял текст в файл, чтобы он считывал текст из файла, и чтобы он очищал весь текст. Для этого нам придется воспользоваться некоторыми методами свойства Lines компонента. И еще нам потребуются три простых кнопки, для которых внизу как раз осталось место. Давайте первую кнопку назовем bSave (в свойстве Name), вторую - bRead, и третью - bClear. Маленькая буква b означает кнопку (button), хотя вы можете изобрести и свои правила наименования компонентов. Нам потребуется изменить и свойство Caption у этих кнопок: в первой кнопке напишите Сохранить, во второй - Читать, а в третьей - Очистить. Чтобы текст умещался на кнопках просторней, свойство Width (ширину) кнопок поставьте в 90. Теперь вот еще что: по умолчанию, все компоненты "привязываются" к верхней и левой границам формы. Если пользователь будет изменять размеры окна, то кнопки будут находиться на таком же расстоянии от левого и верхнего края, что и при проектировании. А так как наш Memo привязан ко всем сторонам, и будет увеличиваться, то закроет собой кнопки. Чтобы этого избежать, выделите все кнопки, откройте их свойство Anchors, akTop переведите в False, а akBottom наоборот, в True. Теперь наши кнопки привязаны к левому и нижнему краю, и всегда будут на одинаковом расстоянии от Memo.

У вас должна получиться такая форма:

Форма редактора текстов

увеличить изображение
Рис. 14.2. Форма редактора текстов

Осталось запрограммировать события OnClick для этих кнопок. Сгенерируйте их, дважды щелкая по кнопкам. Вот код этих событий:

procedure TfMain.bSaveClick(Sender: TObject);
begin
  Memo1.Lines.SaveToFile('MyText.txt');
end;

procedure TfMain.bReadClick(Sender: TObject);
begin
  if FileExists('MyText.txt') then
    Memo1.Lines.LoadFromFile('MyText.txt')
  else ShowMessage('Файл MyText.txt не существует');
end;

procedure TfMain.bClearClick(Sender: TObject);
begin
  Memo1.Lines.Clear;
end;
    

Как видите, события очень просты, в двух из них всего по одной строке. Так, в строке

  Memo1.Lines.SaveToFile('MyText.txt');
    

мы обращаемся к компоненту Memo1, его свойству Lines, и вызываем метод этого свойства SaveToFile().

Давайте разберемся с методами свойства Lines компонента TMemo.

SaveToFile() - сохранить текст в указанный файл, в нашем случае, это файл MyText.txt. Расширение *.txt традиционно используется для текстовых файлов, так что его лучше указывать, хоть это и не является обязательным. В примере мы указали просто имя файла, без адреса. Файл будет создан в текущей папке, там же, где и программа. Если вы хотите указать какое то конкретное место, то указывайте имя файла вместе с адресом, например:

  Memo1.Lines.SaveToFile('C:\MyText.txt');
    

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

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

  if FileExists('MyText.txt') then
    Memo1.Lines.LoadFromFile('MyText.txt')
  else ShowMessage('Файл MyText.txt не существует');
    

Если указанный файл существует, функция FileExists() вернет True. Если же файла по какой-то причине нет, то никакого чтения не будет. Вместо этого выйдет сообщение, что файл не существует, и процедура завершит работу.

Clear - очищает текст в Memo. В примере мы обратились к свойству Lines, но можно обратиться и к самому компоненту, так как у него тоже есть метод Clear. Вместо

Memo1.Lines.Clear;
    

можно написать просто

Memo1.Clear;
    

Результат будет одинаков. Сохраните проект, запустите, и опробуйте его в работе. Не забудьте поэкспериментировать с изменением размера окна, чтобы посмотреть, как будут выглядеть "привязанные" к сторонам формы компоненты.

Кроме вышеперечисленных инструментов, TMemo имеет и некоторые другие полезные методы. Сейчас мы говорим о методах именно компонента TMemo, а не его свойства Lines, имейте это в виду!

CopyToClipboard - копирует выделенный в компоненте текст в Буфер обмена. Пример:
Memo1.CopyToClipboard;
        
CutToClipboard - вырезает выделенный текст и помещает его в Буфер обмена. Пример:
Memo1.CutToClipboard;
        
PasteFromClipboard - вставляет в компонент текст из Буфера обмена в позицию, где находится курсор. Пример:
Memo1.PasteFromClipboard;
        
SelectAll - выделить весь текст. Пример:
Memo1.SelectAll;
        
Undo - отменить последние изменения в тексте. Пример:
Memo1.Undo;
        

Отдельно стоит сказать и о событиях компонента TMemo. Выделите его, и в Инспекторе объектов перейдите на вкладку События. Нас интересуют только основные события, которые могут нам пригодиться в работе. Примеры я приводить не буду, события генерируются так же, как OnClick, которым мы неоднократно пользовались.

OnChange - событие происходит, когда текст в компоненте изменен. Например, пользователь ввел или наоборот, удалил символ, загрузил текст из файла или еще каким то образом изменил содержимое Memo.
OnClick - событие происходит, когда пользователь щелкает по компоненту мышью.
OnDblClick - событие происходит, когда пользователь дважды щелкает по компоненту мышью.
OnEnter - событие происходит, когда компонент становится активным. Или, как говорят, получает фокус ввода.
OnExit - событие происходит, когда компонент теряет фокус ввода (активным становится другой компонент).
OnKeyDown - событие возникает, когда пользователь нажимает, но еще не отпускает клавишу на клавиатуре. Обработчик обычно используют для распознавания нажимаемой клавиши.
OnKeyPress - событие возникает, когда пользователь нажал и отпустил клавишу на клавиатуре. Обработчик обычно используют для распознавания нажатой клавиши. Если пользователь ввёл недопустимый символ, его можно запретить или заменить другим символом.
OnKeyUp - событие возникает, когда пользователь отпускает клавишу на клавиатуре. Обработчик обычно используют для распознавания нажатой клавиши.
OnUTF8KeyPress - то же, что и OnKeyPress, но не для ANSI-, а для UTF8-символов. При работе с русскими символами нужно использовать это событие.

Сохраните проект, скомпилируйте и запустите его. Опробуйте редактирование, сохранение текста в файл, чтение его из файла.

< Лекция 12 || Лекция 13: 12 || Лекция 14 >
Инга Готфрид
Инга Готфрид
Александр Скрябнев
Александр Скрябнев

Через WMI, или используя утилиту wmic? А может есть еще какие более простые пути...