Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ООП / Заочники / ООП_ЛабРаб_Методичка

.pdf
Скачиваний:
30
Добавлен:
08.06.2015
Размер:
770.97 Кб
Скачать

ToEnd – количество символов, которые необходимо просмотреть}

ToEnd := Length(Text) - StartPos;

if CheckBox1.Checked then // с учетом регистра символов

FoundAt := FindText(Edit2.Text, StartPos, ToEnd, [stMatchCase]) // метод поиска строки else

FoundAt := FindText(Edit2.Text, StartPos, ToEnd, []);

// FoundAt – позиция начала найденной строки в тексте if FoundAt <> -1 then

begin

//Выделение в тексте найденного фрагмента

SetFocus;

SelStart := FoundAt;

SelLength := Length(Edit2.Text);

//Активизация/деактивизация кнопок поиска

BitBtn1.Enabled:=false;

BitBtn3.Enabled:=true;

end

else begin

ShowMessage('Строка не найдена. Задайте начальную позицию и повторите поиск.'); // Активизация/деактивизация кнопок поиска

BitBtn1.Enabled:=true;

BitBtn3.Enabled:=false;

end;

end;

3.Методика выполнения

3.1.Используя меню «Пуск» или рабочий стол Windows (если на нем размещен ярлык

«Delphi 7»), запустите программу Delphi 7 (delphi32.exe).

3.2.Внимательно изучите меню, окна, панели инструментов среды разработки приложений Delphi 7.

3.3.Создайте на диске рабочий каталог для файлов проекта лаб. работы № 1.

3.4.Сохраните проект в своем рабочем каталоге, выполнив в главном меню команду File>Save Project As… Первым сохраняется модуль с именем Unit1. Выберите рабочий каталог проекта и сохраните файл, не меняя имени. Вторым сохраняется файл проекта в том же каталоге. Перед сохранением измените имя файла на LabRab1.

3.5.В окне инспектора объектов “Object Inspector” найдите в левой колонке свойство Caption формы Form1 и в соответствующую ячейку правой колонки введите текст заголовка формы из копии экранной формы.

3.6.На закладке Standard панели компонентов выберите компонент Panel, щелкните на нем левой кнопок й мышки, а затем щеклните ей же в любом месте внутри формы. На форме появится объект панель c именем Panel1. В окне инспектора объектов установите значение свойства Align панели в alTop, чтобы панель всегда занимала верхнюю часть формы. С помощью мышки установите нужную высоту панели. Попытайтесь изменить положение панели на форме. В свойстве Caption укажите название лабораторной работы. С помощью свойства Font задайте нужный стиль отображения текста. Свойство Alignment изменяет расположение текста относительно рамки панели.

3.8.На закладке Standard панели компонентов выберите компонент Button и поместите его на панель (второй раз щелкните мышкой внутри панели). Исправьте надпись на кнопке. Если объект помещен не на панель, а на форму, или был ошибочно выбран другой

компонент, то для его удаления необходимо мышкой выделить объект и нажать кнопку

Del.

3.9.На закладке Standard панели компонентов выберите компонент набора страниц PageControl и разместите его на форме. Установите значение свойства Align набора страниц в alClient, чтобы он всегда занимал все свободное простанство формы. Щелкните правой кнопкой мышки на объекте PageControl1 и в появившемся меню выберите пункт New Page. Задайте заголовок страницы TabSheet1 в свойстве Caption. Аналогичным образом создайте вторую страницу.

3.10.Разместите на страницах оставшиеся объекты пользовательского интерфейса программы.

3.11.Запустите программу и проверьте ее внешний вид. Закройте приложение.

3.12.В режиме конструирования формы щелкните два раза мышкой на кнопке с надписью «Очистить все». В окне редактора кода введите в процедуру обработки этого события текст программы, приведенный в параграфе 2.3.1. Запустите программу и проверьте ее работу. Если вы разместили на форме все элементы интерфейса и не изменяли имена объектов, то программа будет функционировать без ошибок.

3.13.Аналогично п. 3.12 создайте обработчики для кнопок «Записать» (п. 2.3.2), «>» (п. 2.3.3), «Выполнить» (п. 2.3.4), «Найти» (п. 2.3.5).

3.14.Разберите примеры и самостоятельно напишите обработчики событый для оставшихся кнопок приложения.

4. Содержание отчета

Отчет готовится один на бригаду в рукописном или печатном виде и должен содержать следующие разделы:

-задание;

-листинг программы с подробными комментариями;

-2 копии экранных форм, на которых должны быть представлены 2 закладки с указанием идентификаторов всех объектов формы.

5.Контрольные вопросы

5.1.Объясните устройство компонентов TPageControl, TListBox, TComboBox, TCheckBox, TRadioGroup и основные приемы работы с ними.

5.2.Объясните устройство компонентов TEdit, TRichEdit и основные методы для работы с ними.

5.3.Объясните устройство компонентов TButton, TBitBtn и основные методы для работы с ними.

5.4.Объясните устройство компонентов TForm, TPanel, TLabel и основные методы для работы с ними.

5.5.Что такое обработчики событий? Как работают программы, управляемые событиями?

5.6.В чем заключается визуальное программирование, его достоинства и недостатки?

Лабораторная работа № 2

Разработка приложения «Калькулятор»

Цель работы: изучение методов и приемов, применяемых при разработке приложений, состоящих из нескольких форм и имеющих главное и выпадающие меню. Использование в программах блоков обработки исключительных ситуаций и динамических массивов.

1. Задание

1.1.Разработать приложение «Калькулятор», который может выполнять операции +, -, /, * над целыми и вещественными числами, а также сохранять операнды и результаты в памяти, организованной по принципу стека.

Кнопки

B – Backspace, удаляет символ слева от курсора D – Delete, удаляет символ справа от курсора R – Read, извлечение числа из стека

W – Write, запись числа в стек.

1.2.Для контроля за операциями использовать обработку исключительных ситуаций.

1.3.Для организации стека использовать динамический массив.

1.4.Для отображения содержимого стека использовать TListBox.

1.4.Программа должна иметь главное меню, содержащее пункты:

Вид

o Показать/скрыть стек.

oОчистить.

§Очистить все

§Очистить индикатор

§Очистить стек

О программе (вызов модальной формы AboutBox).

1.5.Поле редактирования (индикатор) должно иметь выпадающее меню, содержащее пункты:

Очисть

Поместить в стек

Загрузить из стека

2. Краткая теория

2.1. TMainMenu - главное меню формы (программы)

Компонент класса TMainMenu определяет главное меню формы. На форму можно поместить сколько угодно объектов этого класса, но отображаться в полосе меню в верхней части формы будет только тот из них, который указан в свойстве Menu формы. После установки компонента на форму необходимо создать его опции (пункты меню). Для этого следует дважды щелкнуть по компоненту левой кнопкой мыши, либо нажать на нем правую кнопку и выбрать пункт Menu Designer в появившемся вспомогательном меню.

Каждая опция главного меню может раскрываться в список подопций или содержать конечную команду. В названиях опций (свойство Caption) можно указать символ «&» перед тем символом, который определит клавишу быстрого выбора опции (в терминологии Windows такие клавиши называются акселераторами). Например, если опция Файл в строке Caption Инспектора Объектов содержит текст &Файл, то ее можно выбрать сочетанием клавиш Alt+Ф. Свойства BitMap и ImageIndex позволяют связывать с опциями пиктограммы.

Если необходимо вставить разделительную черту, отделяющую группы подопций, то нужно очередной элемент меню назвать именем “-“.

Для элемента меню определено единственное событие OnClick, которое возникает при щелчке на опции или при нажатии Enter, если в этот момент данная опция была выбрана (подсвечена).

2.2. TPopupMenu - вспомогательное (локальное) меню

Компоненты класса TPopupMenu используются для создания вспомогательных (контекстных) меню, появляющихся после нажатия правой кнопки мыши. В отличие от главного меню вспомогательное меню может быть создано для любого объекта формы.

Чтобы связать щелчок правой кнопкой мыши на элементе интерфейса с раскрытием вспомогательного меню, в свойство РорирМепи элемента необходимо поместить имя объекта-меню.

Вспомогательное меню создается с помощью конструктора меню и процесс создания и свойства вспомогательного меню ничем не отличаются от TMainMenu.

2.3. Одномерные динамические массивы

Динамические массивы отличаются от обычных статических массивов тем, что в них не объявляется заранее длина число элементов. Поэтому динамические массивы удобно использовать в приложениях, где объем обрабатываемых массивов заранее неизве-

стен и определяется в процессе выполнения в зависимости от действий пользователя или объема перерабатываемой информации.

Объявление динамического массива содержит только его имя и тип элементов один из базовых типов. Например,

var A: array of integer;

объявляет переменную А как динамический массив целых чисел.

При объявлении динамического массива место под него не отводится. Прежде, чем использовать массив, надо задать его размер процедурой SetLength. В качестве аргументов в нее передаются имя массива и целое значение, характеризующее число эле- ментов. Например,

SetLength(A,10);

выделяет для массива А место в памяти под 10 элементов и задает нулевые значения всех элементов.

Индексы динамического массива всегда целые числа, начинающиеся с 0. Таким образом, в приведенном примере массив содержит элементы от А[0] до А[9].

Повторное применение SetLength к уже существующему в памяти массиву изменяет его размер. Если новое значение размера больше предыдущего, то все значения элементов сохраняются и просто в конце добавляются новые нулевые элементы. Если же новый размер меньше предыдущего, то массив усекается, и в нем остаются значения первых элементов. Например, для приведенной ниже программы размерность и значения

элементов массива при выполнении различных операторов показаны в комментариях к

тексту.

 

var

A:

array of integer;

 

N,i :

integer;

begin

N:=5;

SetLength(A,N); {массив A(0,0,0,0,0)}

for i:=0 to N do A[i]:=i+l; {массив A(1,2,3,4,5)} N:=7;

SetLength(A,N); {массив A(1,2,3,4,5,0,0)} N:=3;

SetLength(A,N); {массив А(1,2,3)} N:=4;

SetLength(A,N); {массив А(1,2,3,0)}

end;

Усечение динамического массива лучше проводить функцией Сору, присваивая ее результат самому массиву. Например, оператор

А := Сору(А, 0, 3);

усекает динамический массив А, оставляя неизменными первые три его элемента.

Если динамический массив уже размещен в памяти, к переменной этого массива можно применять стандартные для массивов функции Length длина, High наибольшее значение индекса (очевидно, что всегда High = Length — 1) и Low наименьшее значение индекса (всегда 0). Если массив имеет нулевую длину, то High возвращает -1, т.е. при этом получается, что High < Low.

Сама переменная динамического массива является указателем на начало массива. Если место под массив еще не выделено, значение переменной равно nil. Но его нельзя разыменовывать операцией ^, нельзя передать в процедуры New и Dispose.

Удалить из памяти динамический массив можно одним из следующих способов: присвоить ему значение nil, использовать функцию Finalize или установить нулевую длину. Таким образом, эквивалентны следующие операторы:

А := nil;

или

Finalize(A);

или

SetLength(A,0);

Если динамические массивы определены как переменные одного типа, например var А,В: array of integer;

и размер массива А не меньше размера массива В или А = nil, то

возможно присваивание вида

В := А;

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

 

Если динамические массивы объявлены не как переменные одного типа, т.е.

var

A:

array

of

integer;

 

В:

array

of

integer;

то присваивание

 

 

В

:= A;

 

 

 

вообще не допускается.

В операциях сравнения динамических массивов сравниваются только сами указатели, а не значения элементов массивов. Таким образом, выражение А = В вернет true только в случае, если А и В указывают на один и тот же массив. Выражение А[0] = В[0] сравнивает значения первых элементов двух массивов.

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

function CheckStrings(A: array of string): Boolean;

может работать в равной степени и со статическими, и с динамическими массивами.

2.4. Обработка исключений в блоках try ... except

При работе программы могут возникать различного рода ошибки: переполнение, деление на нуль, попытка открыть несуществующий файл и т.п. При возникновении таких

исключительных ситуаций программа генерирует так называемое исключение и выполнение дальнейших вычислений в данном блоке прекращается. Исключение это объект специального вида, характеризующий возникшую в программе исключительную

ситуацию. Он может также содержать в виде параметров некоторую уточняющую информацию. Особенностью исключений является то, что это сугубо временные объекты. Как только они обработаны каким-то обработчиком, они разрушаются.

Если исключение не перехвачено нигде в программе, то оно обрабатывается

методом TApplication.HandleException. Он обеспечивает стандартную реакцию программы на большинство исключений выдачу пользователю краткой информации в окне сообщений и уничтожение экземпляра исключения.

Наиболее кардинальный путь борьбы с исключениями обработка их с помощью блоков try ... except. Синтаксис этих блоков следующий:

try

{Исполняемый код} except

{Код, исполняемый в случае генерации исключения} end;

Операторы раздела except выполняются только в случае генерации исключения в операторах блока try. Таким образом, вы можете предпринять какие-то действия: известить пользователя о возникшей проблеме и подсказать ему пути ее решения, принять какие-то меры к исправлению ошибки (например, при делении на нуль заслать в результат очень большое число соответствующего знака) и т.д.

Наиболее ценным является то, что в разделе except вы можете определить тип

сгенерированного исключения и дифференцирование реагировать на различные исключительные ситуации. Это делается с помощью оператора:

on <класс исключения> do <оператор>;

Полная таблица классов исключений, которые вы можете использовать в этом операторе, приведена в Справочной системе.

Операторы on...do позволяют проводить выборочную обработку различных исключений. Приведем пример такой обработки:

var A : shortint;

try

С := StrToInt(Editl.text); A := В div С;

…. except

on EConvertError do // Ошибка преобразования строки в число MessageDlg('Вы ввели ошибочное число; повторите ввод',

mtWarning, [mbOk], 0);

on EDivByZero do // Целочисленное деление на 0 MessageDlg('Вы ввели нуль; повторите

ввод',mtWarning,[mbOk],0);

on EIntOverflow do // Целочисленное переполнение if (B*C) >= 0 then A := 32767 else A := -32767;

end;

Можно перехватывать не только отдельные исключения, но и группы родственных исключений. Дело в том, что, предопределенные в Delphi исключения построены по иерархическому принципу. Базовым классом исключений является класс Exception. Другие исключения являются производными или непосредственно от него, или от промежуточных производных классов. Например, имеется класс исключений EIntError,

производный от Exception и являющийся родительским для ряда исключений, связанных с ошибками целочисленных арифметических операций, например, для EDivByZero и EIntOverflow. Поэтому можно обработать сразу группу родственных исключений, используя, например, такой оператор:

on EIntError do // Все ошибки целочисленных операций

MessageDlg('Ошибка целочисленной операции', mtWarning, [rnbOk] , 0);

Этот оператор перехватит исключения всех классов, порожденных от EIntError. Помимо операторов on, обрабатывающих заданные типы исключений, в раздел

except может быть включен оператор else, в котором выполняется обработка всех не перехваченных ранее исключений, т. е. происходит обработка по умолчанию. Например:

except on .. . ; on . . . ;

else <обработчик всех не перехваченных ранее событий>; end;

Конечно, оператор else должен идти последним, так как в противном случае все обработчики, записанные после него, работать не будут, поскольку все исключения уже будут перехвачены. Внутри обработчика по умолчанию можно получить доступ к объекту исключения, воспользовавшись функцией ExceptObject.

Следует указать на некоторую опасность применения else в этом контексте. Перехват всех исключений способен замаскировать какие-то непредвиденные ошибки в программе, что затруднит их поиск и снизит надежность работы.

В раздел except могут включаться или только операторы on, или только какие-то другие операторы. Смешение операторов on с другими не допускается.

Раздел except может включаться совместно с разделом finally. Например, можно организовать блоки try следующим образом:

try

try

finally

end; except …. end;

В отличие от блока try…except операторы раздела finally выполняются всегда, независимо от того, была ошибка в разделе try, или нет. При этом исключение не обрабатывается и не разрушается.

2.5. Последовательность обработки исключений

Блоки try...except могут быть вложенными явным или неявным образом. Примером неявной вложенности является блок try...except, в котором среди операторов раздела try имеются вызовы функций или процедур, которые имеют свои собственные блоки try...except. Рассмотрим последовательность обработки исключений в этих случаях. При

генерации исключения сначала ищется соответствующий ему обработчик on в том блоке try...except, в котором создалась исключительная ситуация. Если соответствующий обработчик не найден, то поиск ведется в обрамляющем блоке try...except (при наличии явным образом вложенных блоков), и т. д. Если в данной функции или процедуре обработчик не найден или вообще в ней отсутствуют блоки try...except, то поиск переходит на следующий уровень в блок, из которого была вызвана данная функция или процедура. Этот поиск продолжается по всем уровням. И только если он закончился безрезультатно, выполняется стандартная обработка исключения, заключающаяся в выдаче пользователю сообщения о типе исключения.

Как только оператор on, соответствующий данному исключению, найден и выполнен, объект исключения разрушается и управление передается оператору, следующему за тем блоком try...except, в котором был осуществлен перехват.

Возможен также вариант, когда в самом обработчике исключения в процессе обработки возникла исключительная ситуация. В этом случае обработка прерывается, прежнее исключение разрушается и генерируется новое исключение. Его обработчик ищется в блоке try...except, внешнем по отношению к тому, в котором возникло новое исключение.

2.6. Использование общих обработчиков событий

Для кнопок, соответствующих цифрам, целесообразно использовать общий обработчик события onClick, так как реакция программы на нажатие любой из этих кнопок должна быть одинаковой. Значение соответствующей цифры лучше всего хранить в свойстве Tag каждой кнопки. В обработчике события для определения нажатой кнопки

необходимо использовать выражение

(Sender as TSpeedButton).Tag

Sender – это параметр процедуры обработки события, который показывает, какой компонент вызвал обработчик. Оператор as позволяет объект Sender класса TObject рассматривать как объект класса TSpeedButton, каковым он в данном случае и является. Такое преобразование необходимо, чтобы получить доступ к свойству Tag класса

TSpeedButton.

3.Методика выполнения

3.1.Создайте на диске рабочий каталог для файлов проекта лабораторной работы № 2 и сохраните в нем новый проект Delphi.

3.2.Разместите на форме все объекты интерфейса пользователя и настройте их размеры и положение, используя пункты Align и Size контекстного меню Position окна формы.

3.3.Добавьте в форму главное и контекстное меню. Свяжите контекстное меню с индикатором калькулятора. Добавьте в меню нужные пункты.

3.4.Используя меню File>New>Other…, откройте окно NewItems и на закладке Forms выберите шаблон формы About box. После нажатия на копнку OK новая форма будет добавлена в проект. Сохраните проект на диске.

3.5.Отредактируйте форму AboutBox. В качестве образца используйте окно About программы Delphi.

3.6.В обработчик события OnClick пункта «О программе» главного меню поместите вызов метода открытия формы в модальном режиме:

AboutBox.ShowModal;

Проверьте работу программы.

3.7.Задайте свойству Tag кнопок «0», «1», … «9», «.» значения 0, 1, … 9, 10 соответственно. Создайте для них общий обработчик события OnClick. Цифра в индикатор должна вводиться в позицию, на которую указывает маркер. В качестве образца использования позиции курсора в поле ввода используйте пример 2.3.5 из лабораторной работы № 1.

3.8.Напишите программный код обработки событий для кнопок B и D.

3.9.Напишите программный код обработки события для пункта «Показать/скрыть стек» главного меню. Для изменения размеров формы используйте свойство Width. Свойство BorderStyle формы установите в bsSingle. С помощью свойства BorderIcons уберите кнопки минимизации и максимизации размеров формы. В результате пользователь не сможет произвольно изменить размер формы. Надпись в меню должна изменяться в соответствии с тем, скрыт стек или нет.

3.10.Напишите обработчик события OnClick для очистки индикатора. Процедуру

очистки индикатора используйте в качестве обработчика для соответствующих пунктов главного и выпадающего меню.

3.11.Разработайте процедуры для записи числа в стек и извлечения числа из стека и назначьте их обработчиками событий для соответствующих кнопок и меню. Перед записью числа в стек проверьте его. Для этого в блоке try … except преобразуйте строку из индикатора (Edit1.Text) в число с помощью функции StrToFloat. В учебных целях в

качестве стека используйте одновременно динамический массив вещественных чисел и компонент TListBox. В случае массива в качестве вершины стека целессобразно использовать последний элемент массива, а для компонента TListBox – первую строку.

3.12.Напишите обработчики события OnClick для очистки стека и очистки всего (стека и индикатора).

3.13.Разработайте обработчик события OnClick для кнопок операций (+, -, /, *, =). В процедуре используйте блок try … except.

3.14.Протестируйте работу всех функций приложения. Проверьте правильность

работы при вычислении сложного выражения с использованием стека для хранения промежуточных результатов.

4. Содержание отчета

Отчет готовится один на бригаду в рукописном или печатном виде и должен содержать следующие разделы:

-задание;

-листинг программы с подробными комментариями;

-2 копии основной экранной формы и копия экранной формы «О программе», на которых должны быть указаны идентификаторов всех объектов форм.

5.Контрольные вопросы

5.1.Объясните устройство компонентов TMainMenu, основные свойства и методы, использование в программах.

5.2.Объясните устройство компонентов TPopupMenu, основные свойства и методы, использование в программах.

5.3.В чем отличие динамического массива от статического?

5.4.Основные процедуры и функции для работы с динамическими массивами.

5.5.Что такое исключение? Чем отличаются и как используются в программах блоки try...except и try…finally?

5.6.Каким образом исключения обрабатываются в программах?