Общие указания по выполнению лабораторной работы
Цель работы
Изучение методов работы с компонентами, предназначенными для обработки многострочных текстов; получение навыков использования основных свойств, методов и событий этих компонентов.
Используемое оборудование и программное обеспечение
Для выполнения лабораторной работы требуется ПЭВМ типа IBM PC с ОС Windows 2000 и выше, среда разработки Borland Delphi 7 или Borland C++ Builder.
Домашнее задание и методические указания по его выполнению
Многострочные редакторы текста
Компонент Memo
Для
работы с многострочным текстом Delphi
и C++ Builder
предоставляют несколько компонентов.
Наиболее часто используемыми являются
Memo
и RichEdit.
Сначала рассмотрим работу с компонентом
Memo
.
Для доступа ко всему содержимому многострочного редактора используется свойство Text строкового типа. В этом случае все содержимое компонента Memo представляется одной строкой, а конец каждой строки, вставляемый при нажатии клавиши <Enter>, записывается двумя кодами #13#10.
Для работы с отдельными строками используется свойство Lines типа TStrings. Данный класс является базовым для выполнения операций со строковыми данными и предоставляет соответствующие свойства и методы.
К каждой строке многострочного редактора можно получить доступ по ее номеру в массиве Lines. Отсчет элементов списка начинается с нуля. Для обращения к первому элементу нужно указать Lines[0], ко второму - Lines[1] и т.д. При операциях с отдельными строкам программист должен контролировать номера строк в редакторе и не допускать обращения к несуществующему элементу.
При конструировании приложения изменение списка строк выполняется с помощью строкового редактора String List Editor (рис. 8). Его вызов выполняется через Инспектор объектов нажатием кнопки с многоточием в поле свойства Lines.
Свойство Count типа integer задает число элементов в списке. Поскольку первый элемент списка имеет нулевой номер, то номер последнего элемента равен Count – 1.
Например, присвоим элементам редактора Memo новые значения:
// - - - - Object Pascal - - - -
for i := 0 to Memo1.Lines.Count do
Memo1.Lines[i] := 'Строка № ' + IntToStr(i);
// - - - - - - - C++ - - - - - - -
for (int i = 0; i < Memo1->Lines->Count; i++)
Memo1->Lines->Strings[i] = "Строка №" + IntToStr(i);
Результат работы программы показан на рис. 9.
Методы Add и Insert служат для добавления строк в многострочный редактор. Функция Add(s: string): integer добавляет строку s в конец текста, а в качестве результата возвращает положение нового элемента в списке. Процедура Insert(index: integer; s: string) вставляет строку s на позицию с номером index. При этом строки, находившиеся до операции вставки в указанной позиции и ниже, смещаются вниз.
Для удаления элементов из Memo используются методы Delete и Clear. Метод Delete(index: integer) удаляет элемент с номером index.
Метод Clear очищает многострочный редактор, удаляя все его элементы.
Примеры использования методов Memo:
// - - - - Object Pascal - - - -
Memo1.Lines.Add('Новая строка');
Memo1.Lines.Delete(4);
Memo1.Clear;
// - - - - - - - C++ - - - - - - -
Memo1->Lines->Add("Новая строка");
Memo1->Lines->Delete(4);
Memo1->Clear();
Процедура Move(cur_index, new_index: integer) перемещает элемент с позиции с номером cur_index в позицию с номером new_index.
Поиск элемента в редакторе можно выполнить с помощью метода IndexOf. Функция IndexOf(s: string): integer определяет, содержится ли строка s в редакторе. В случае успешного поиска функция возвращает номер позиции найденной строки, а в случае, если строковый элемент не найден, то возвращается значение –1.
Класс TStrings имеет методы SaveToFile и LoadFromFile, позволяющие непосредственно работать с текстовыми файлами. Эти методы предоставляют возможность сохранения строк из редактора в текстовом файле на диске и последующего чтения строк из этого файла.
Процедура SaveToFile(file_name) сохраняет строковые элементы в файл file_name. В последующем сохраненные строки можно извлечь из файла, используя метод LoadFromFile.
Процедура LoadFromFile(file_name) заполняет Memo содержимым указанного текстового файла, при этом предыдущее содержимое стирается.
Например, сохраним текст из Memo1 в файл file1 и загрузим в редактор файл file2:
// - - - - Object Pascal - - - -
Memo1.Lines.SaveToFile('file1.txt');
Memo1.Lines.LoadFromFile('file2.txt');
// - - - - - - - C++ - - - - - - -
Memo1->Lines->SaveToFile("file1");
Memo1->Lines->LoadFromFile("file2.txt");
В компоненте Memo формат (шрифт, его атрибуты, выравнивание) одинаков для всего текста и определяется свойством Font. При сохранении введенного пользователем текста будет создан текстовый файл, содержащий только символы и не содержащий элементов форматирования. При последующем чтении этого файла в Memo формат будет определяться текущим состоянием свойства Font компонента Memo, а не тем, в каком формате ранее вводился текст.
Компонент
RichEdit
работает с текстом в обогащенном формате
RTF. Текст данного формата
хранит дополнительную служебную
информацию, управляющую свойствами
каждого абзаца и сменой шрифта по ходу
текста.
RichEdit использует вспомогательные объекты класса TTextAttributes для хранения атрибутов шрифта. Эти атрибуты распространяются на весь текст через свойство редактор DefAttributes или на выделенную часть текста – через его свойство SelAttributes. Класс TTextAttributes содержит следующие свойства:
Color – цвет текста;
Height – высота текста с учетом межстрочного интервала;
Name - название шрифта;
Size – размер шрифта;
Style – стиль текста; может принимать комбинации следующих значений: fsItalic – курсив, fsBold – полужирный, fsUnderline – с подчеркиванием, fsStrikeOut – с перечеркиванием.
Для каждого текстового абзаца создается объект класса TParaAttributes, в котором сохраняются атрибуты абзаца:
Alignment – выравнивание абзаца;
Numbering – наличие маркера слева от текста: nsBullet – есть маркер в виде точки; nsNone – маркера нет.
Например, для первого абзаца изменим стиль текста на курсив с подчеркиванием, второй, третий и четвертый абзацы выровняем по центру и пометим маркером, для пятого абзаца поменяем размер шрифта (рис. 10):
// - - - - Object Pascal - - - -
RichEdit1.SelAttributes.Style := [fsUnderline, fsItalic];
…
RichEdit1.Paragraph.Alignment := taCenter;
RichEdit1.Paragraph.Numbering := nsBullet;
…
RichEdit1.SelAttributes.Size := 12;
// - - - - - - - C++ - - - - - - -
RichEdit1->SelAttributes->Style =
RichEdit1->SelAttributes->Style << fsUnderline;
RichEdit1->SelAttributes->Style =
RichEdit1->SelAttributes->Style << fsItalic;
…
RichEdit1->Paragraph->Alignment = taCenter;
RichEdit1->Paragraph->Numbering = nsBullet;
…
RichEdit1->SelAttributes->Size = 12;
Компонент ListBox представляет собой стандартный для Windows список строк, с помощью которого пользователь может выбрать один или несколько элементов.
Свойство Columns определяет число столбцов, в которых будет отображаться список, если он не помещается целиком в окне компонента ListBox.
Свойство Sorted позволяет упорядочить список по алфавиту.
Комбинированный список ComboBox представляет собой комбинацию списка ListBox и редактора Edit , и поэтому большинство его свойств и методов заимствованы у этих компонентов.
Поведение ComboBox в основном определяется значением его свойства Style:
csDropDown - обычное поле со списком, которое допускает непосредственное редактирование и по запросу отображает список;
csDropDownList - поле со списком, которое не допускает редактирования;
csSimple – поле с постоянно раскрытым списком; для того чтобы список был виден, необходимо увеличить высоту (свойство Height) компонента ComboBox;
csOwnerDrawFixed – список с элементами одинаковой высоты, которую задает свойство ItemHeight;
csOwnerDrawVariable – список с элементами, которые могут иметь разную высоту.
Свойство DropDownCount типа integer определяет количество строк, которые одновременно отображаются в раскрывающемся списке. Если значение свойства меньше числа строк списка, то на раскрывающемся списке автоматически появляется вертикальная полоса прокрутки.
Свойство DroppedDown типа boolean позволяет определить, раскрыт ли список. Если свойство имеет значение true, то список отображается в раскрытом виде, в противном случае список свернут. Свойство DroppedDown действует только, если Style имеет значение, не равное csSimple.
При работе с комбинированным списком генерируются следующие события:
OnDropDown – открытие списка;
OnCloseUp – закрытие списка;
OnSelect – выбор элемента;
OnChange – изменение текста в поле редактирования.
Например, пусть надо при выборе новой строки в списке ComboBox1 записать эту строку в Edit1:
// - - - - Object Pascal - - - -
procedure TForm1.ComboBox1Change(Sender: TObject);
begin
Edit1.Text := ComboBox1.Text;
end;
// - - - - - - - C++ - - - - - - -
void __fastcall TForm1::ComboBox1Click(TObject *Sender)
{
Edit1->Text = ComboBox1->Text;
}
Переключатели (флажки) позволяют выбрать какое-либо значение из определенного множества. Они могут находиться во включенном (установленном) или выключенном (сброшенном) состояниях. Анализ состояния переключателя позволяет программисту выполнять соответствующие операции.
Компонент CheckBox представляет собой переключатель с независимой фиксацией. Данный переключатель действует независимо от других подобных переключателей.
Текст, расположенный рядом с флажком, задается свойством Caption. По умолчанию текст располагается справа от флажка, но можно расположить текст слева, изменив значение свойства Alignment.
Для определения состояния переключателя используется свойство Checked типа boolean. По умолчанию оно имеет значение false, и переключатель выключен.
Основное свойство компонента, содержащее список строк - Items. Как и свойство Lines у компонента Memo, Items имеет тип TStrings, соответственно, к строкам спискам применимы все свойства и методы данного класса (Add, Delete, Clear, Insert, Count и т.д.).
У компонента ListBox есть свойство MultiSelect, разрешающее пользователю множественный выбор в списке. Если MultiSelect = false (значение по умолчанию), то пользователь может выбрать только один элемент списка. В этом случае свойство ItemIndex хранит индекс выбранной строки. Если ни одна строка не выбрана, то ItemIndex = -1.
Для списка, допускающего множественный выбор, число выбранных строк хранится в свойстве SelCount. Чтобы узнать, выбрана строка или нет, надо проверить свойство Selected. Если Selected равно true, то строка выбрана.
Например, надо записать в список ListBox2 номера строк, выделенных в списке ListBox1. Это можно реализовать с помощью следующего кода:
// - - - - Object Pascal - - - -
for i := 0 to ListBox1.Items.Count - 1 do
if ListBox1.Selected[i]
then ListBox2.Items.Add(IntToStr(i + 1));
// - - - - - - - C++ - - - - - - -
for (int i = 0; i < ListBox1->Items->Count; i++)
if (ListBox1->Selected[i])
ListBox2->Items->Add(IntToStr(i + 1));
Результат работы программы приведен на рис. 11.