Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП_ЛР3,4_A5_Часть2.doc
Скачиваний:
23
Добавлен:
08.11.2019
Размер:
557.06 Кб
Скачать

40

Лабораторная работа № 3 Обработка списков строк и исключительных ситуаций

1. Списки строк

1.1. Теоретическая часть

Очень часто при создании приложений необходимо отображать на экране не одну строку, а несколько. В Delphi для этого используются такие компоненты, как TComboBox, TListBox, TRichEdit, TNotebook, TTabSet, THeader и другие. Каждый из этих компонен­тов содержит свойство, принадлежащее типу TStrings.

TStrings является абстрактным классом и предназначен для работы с наборами строк. Набор строк технически реализуется в виде массива указателей. С помощью свойств и методов данного класса можно добавлять и удалять строки, сортировать строки, считывать и записывать строки в файл или поток и т. д. Кроме того, элементами набора могут быть пары строка-объект, в которых строка является собственно строкой символов, а объектом может быть объект любого класса Delphi (в том числе и потомок от TStrings). Эта особенность позволяет сохранять в TStrings объекты с текстовыми примечаниями, сортировать объекты, отыскивать нужный объект по его описа­нию, создавать многомерные наборы строк и т. д.

Свойства класса TStrings

Свойство Capacity определяет количество строк, которое мо­жет храниться в наборе, а абстрактное свойство Count содержит текущее количество элементов.

Если при добавлении очередного элемента Capacity окажется меньше Count, происходит автоматическое расширение массива. При этом в динамической памяти резервируется место для размещения Capacity+16 указателей, в новый массив переписывается содержимое старого массива, после чего старый массив уничто­жается. Если заранее известно количество элементов в создаваемом наборе строк, имеет смысл установить начальное значение свойства Capacity, чтобы сократить непроизводительные расходы на многократные расширения массива указателей.

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

Правила формата SDF:

  • строки разделяются запятыми или пробелами (можно так­же заключить строки в двойные кавычки);

  • если строка содержит двойные кавычки, то они удваиваются;

  • две идущие подряд запятые обозначают пустую строку;

  • все запятые и пробелы, не заключенные в двойные кавыч­ки, считаются разделителями строк.

Например, если свойство CommaText имеет значение

"Стро, ка1","Стр""ока 2",,Строка 3,Строка4

то набор состоит из строк:

Стро,ка1

Стр"ока 2

Строка

3

Строка4

Следующие два свойства используются при представлении строк в формате Name=Value (имя = значение). Свойство Names содержит набор названий строк, a Values — набор соответствующих значений. Например, если i-я строка имеет вид

Color=clGreen (в строке не должно быть пробелов ни до, ни после символа «=»),

то

Names[i]:= 'Color'; Values[i]:='ClGreen'.

Элементами набора строк могут быть пары строка-объект. Свойство Objects открывает доступ к объекту, связанному со строкой с номером Index. Нумерация строк начинается с нуля.

Абстрактное свойство Strings используется для того, чтобы получить доступ к строке с номером Index. Для объектов класса TStrings свойство Strings является свойством по умолчанию, т. е. для доступа к конкретной строке необязательно использовать свойство Strings. Например, следующие операторы выпол­няют одно и то же действие:

var

MyStrings : TStrings;

MyStrings.Strings[0]:= 'Это первая строка’;

MyStrings[0] := 'Это первая строка';

Свойство Text содержит набор строк объекта в виде одной длинной строки с символами возврата каретки и перехода на новую строку

Методы класса TStrings

function Add(const S: string): Integer; virtual; - добавляет строку в набор данных и возвращает ее индекс;

function AddObject (const S: string ; AObject: TObject) : Integer; virtual; - добавляет пару строка-объект в набор данных, возвращает индекс новой пары строка-объект;

procedure Addstrings (Strings: TStrings); virtual; - добавляет к текущему набору новый набор строк;

procedure Append (const S : string); - добавляет строку в набор данных, но не возвращает индекс новой строки;

procedure Assign (Source: TPersistent) ; override; - уничтожает прежний набор строк и загружает из Source новый набор. Если строки в новом наборе связаны с объектами, то объекты также будут загружены;

procedure Clear; virtual; abstract; - очищает набор данных и освобождает связанную с ним память;

procedure Delete (Index: Integer); virtual; abstract; - уничтожает элемент набора с индексом Index и освобождает связанную с ним память. Нумерация строк начинается с нуля;

destructor Destroy; override; - уничтожает объект класса TStrings. Рекомендуется не вызывать данный метод в приложении, а вместо него использовать метод Free;

function Equals (Strings: TStrings) Boolean; - сравнивает построчно текущий набор данных с набором Strings и возвращает True, если наборы идентичны;

procedure Exchange (Indexl, Index2: Integer); virtual; - меняет местами строки с индексами IndexlиIndex2;

function GetText: PChar; virtual; - помещает значение свойства Text в динамически создаваемый буфер;

function IndexOf(const S: string): Integer; virtual; - для строки S возвращает ее индекс или -1, если такой строки в наборе нет;

function IndexOfName (const Name: string): Integer; - возвращает индекс строки с именем Name;

procedure Insert (Index: Integer; const S: string); virtual; abstract; - вставляет строку в набор и присваивает ей индекс Index;

procedure InsertObject (Index: Integer; const S: string; AObject: TObject); - вставляет строку и объект в набор и присваивает им индекс Index;

procedure LoadFromFile(const FileName: string); virtual; - загружает набор строк из файла;

procedure LoadFromStream (Stream: TStream); virtual; - загружает набор из потока;

procedure Move(CurIndex, NewIndex: Integer); virtual; - перемещает строку из положения CurIndex в положение NewIndex;

procedure SaveToFile(const FileName: string); virtual; - сохраняет набор строк в файле с именем FileName;

procedure SaveToStream(Stream: TStream); virtual; - сохраняет набор строк в потоке;

procedure SetText (Text: PChar); virtual; - считывает строки из буфера и записывает их в набор строк.

Пример. Разработка программы «Блокнот» для хранения информации по месяцам года.

Создайте новый проект. Сохраните новое приложение в текущей папке: файл модуля под именем Main.pas, файл проекта — Notebook.dpr.

1-й этап. Создание визуального интерфейса приложения

1.1. Задайте значения свойств формы следующим образом:

Name – NotebookF;

Caption – Блокнот.

1.2. Поместите на форму компонент Notebook (блокнот) со стра­ницы Win3.1 палитры компонентов.

1.3. Создайте страницы компонента NoteBookl. Для этого в инспекторе объектов найдите свойство Pages (страницы); щелкните на кнопке с тремя точками для открытия диалогового окна редактирования значений выбранного свойства (рис. 1).

Рис. 1

Используя диалоговое окно, создайте 12 страниц, каждая из которых называется именем, соответствующим месяцу года (Январь, Февраль и т. д.). Для редактирования названия первой страницы воспользуйтесь кнопкой Edit, для добавления очередной страницы — кнопкой Add. Значение Help context можно оставить без изменения (это свойство используется при вызове контекст­но-зависимой справочной системы приложения), так как приложение не содержит справочной системы. Для завершения создания списка страниц нажмите на кнопку Close.

1.4. Поместите компонент TabSet (список закладок) со страницы Win3.1 под компонентом NoteBookl. Сделайте эти компоненты одинаковыми по ширине.

1.5. Положите на каждую из 12 страниц компонента NoteBookl компонент ListBox (окно списка) для размещения записей на каждый месяц. Для этого выполните такую последовательность действий.

Установите свойство ActivePage (активная страница) компонента NoteBook в значение, равное 'Январь'. Щелкните на выбранной странице объекта NoteBookl. В палитре компонентов на странице Standard выберите компонент ListBox и поместите его (щелкните) в компонент NoteBookl. Для свойства Align компонента ListBox1 установите значение AlClient.

Повторите эту операцию для оставшихся 11 страниц блокнота.

1.6. В правую часть формы поместите компонент Panel (страница Standard палитры компонентов), на него положите один компонент Label, один компонент Edit и три компонента Button. Поместите еще 2 компонента Button в правой нижней части формы (рис. 2).

Рис. 2

Установите следующие свойства компонентов:

Компонент

Свойство

Значение

Panel1

Caption

Label1

Caption

'Введите сообщение'

Editl

Name

RecordEdt

Editl

Text

Buttonl

Name

AddBtn

Caption

Добавить

Button2

Name

ChangeBtn

Caption

Изменить

Button3

Name

DeleteBtn

Caption

Удалить

Button4

Name

ClearBtn

Caption

Очистить

Button5

Name

CloseBtn

Caption

Закрыть

1.7. Сохраните проект. Убедитесь, что после запуска приложения форма ничем не отличается от режима проектирования.

2-й этап. Создание программного кода

2.1. Создание закладок в TabSetl и синхронизация их со страницами блокнота.

Для этого используется свойство Tabs компонента TabSet, представляющее список имен закладок. В примере список закладок соответствует списку страниц блокнота (Pages). Создайте следующий обра­ботчик события:

Procedure TNoteBookF.FormCreate(Sender: TObject);

begin

TabSetl.Tabs:=NoteBookl.Pages;

{копирование содержимого свойства Pages компонента NoteBook в свойство Tabs

компонента TabSet, т. е. создание закладок в TabSet}

TabSetl.TabIndex:=NoteBookl.Pagelndex;

{В соответствии с тем, какая страница блокнота активна во время проектирования

(свойство ActivePage), активной будет закладка с тем же именем (номером)}

end;

2.2. Используя свойства UnSelectedColor, SelectedColor, BackgroundColor, DitherBackground, StartMargin, EndMargin компо­нента TabSetl, измените внешний вид закладок.

2.3. Сохраните и запустите проект. Проверьте, имеют ли закладки на форме названия, соответствующие страницам блокнота.

2.4. Создание обработчика события OnClick для кнопки 'Добавить'.

После щелчка на кнопке содержимое окна редактирования (RecordEdt) должно добавляться в список на выбранной странице блокнота. Для операций со строками у компонента ListBox имеется свойство Items, принадлежащее классу TStrings. Чтобы добавить строку в список, используется метод Add этого класса (см. выше список методов класса TStrings). Текст обработчика события может быть создан двумя способами.

1-й способ

procedure TNoteBookF.AddBtnClick(Sender: TObject);

begin

if RecordEdt.Text <>’’ then

begin

case NoteBookl.PageIndex of

{Для того чтобы поместить запись в список на страницу блокнота, выбираем

компонент ListBox по номеру страницы блокнота}

0 : ListBoxl.Items.Add(RecordEdt.Text);

1 : ListBox2.Items.Add(RecordEdt.Text) ;

2 : ListBox3.Items.Add(RecordEdt.Text);

3: ListBox4.Items.Add(RecordEdt.Text) ;

4 : ListBox5.Items.Add(RecordEdt.Text);

5 : ListBox6.Items.Add(RecordEdt.Text);

6: ListBox7.Iterns.Add(RecordEdt.Text);

7 : ListBox8.Items.Add(RecordEdt.Text) ;

8: ListBox9.Items.Add(RecordEdt.Text);

9: ListBox10.Items.Add(RecordEdt.Text);

10: ListBoxll.Items.Add(RecordEdt.Text);

11: ListBoxl2.Items.Add(RecordEdt.Text);

end;

RecordEdt. Text: =’’; {введенный текст затираем}

end;

end;

2-й способ

В Object Pascal имеется функция:

function FindComponent(const AName: string): TComponent;

Функция возвращает ссылку на компонент, имя которого задано параметром AName.

Эту функцию можно использовать в коде обработчика события OnClick кнопки ‘Добавить' следующим образом:

procedure TNoteBookF.AddBtnClick(Sender: TObject);

var TempComponent: TListBox; {вспомогательная переменная}

begin TempComponent:=TListBox(FindComponent('ListBox'+

IntToStr(NoteBook1.PageIndex+1)));

{TListBox(<компонент>) используется для преобразования к типу TListBox}

if RecordEdt.Text <>’’ then

TempComponent.Items.Add(RecordEdt.Text);

RecordEdt.Text:=’’;

end;

2.5. Сохраните, запустите проект и добавьте строки на разные страницы блокнота. В данном варианте программы они должны записываться только на страницу, которая была открыта при запуске приложения. Это объясняется тем, что закладки Tabset1 не синхронизированы со страницами NoteBook1, т. е. при выборе закладки соответствующая страница блокнота не активизируется.

Чтобы устранить этот недостаток, следует создать обработчик события OnClick для закладок Tabset1:

procedure TNoteBookF.TabSetlClick(Sender: TObject);

begin

NoteBook1.PageIndex:=TabSet1.TabIndex;

{страница блокнота и страница набора закладок должны совпадать}

end;

2.6. Сохраните проект и проверьте правильность работы приложения, т. е внесение записей на различные страницы блокнота.