Урок 1 Тема урока: Знакомство со средой объектно- ориентированного программирования Delphi

advertisement
Урок 1
Тема урока: Знакомство со средой объектно- ориентированного программирования Delphi
Запускаем Delphi.
После запуска Delphi на экране одновременно появляются несколько окон, каждое из которых несет в себе определенную функциональность, т.е. предназначено для решения определенных
задач. Т.к. терминология необходима, чтобы было понятно, о чем идет речь, запишем названия и
назначения окон.
А) Главное окно ( с заголовком «Delphi-*- Proect1») Его закрытие ведет к завершению работы в среде программирования. В главном окне находится меню программы, ниже расположена панель горячих кнопок, которые дублируют наиболее часто используемые пункты меню. По каждой
кнопке есть всплывающая подсказка. (Кнопки можно удалить с панели или добавить новые. Чтобы
удалить кнопку с панели захватите ее левой кнопкой мыши и, не отпуская, переместите за границу
главного окна. Для добавления кнопки щелкните правой кнопкой на панели инструментов  Properties выберите нужную категорию (пункт меню) и соответствующую нужной команде пиктограмму
левой кнопкой мыши перенесите на панель горячих кнопок.) Правее горячих кнопок находится палитра компонентов . Компоненты объединены в группы, каждая из которых имеет закладку. По
названию каждого компонента также всплывает подсказка.
Б) Окно формы (с заголовком Form1) находится ниже главного окна справа. Вся рабочая область окна заполнена точками координатной сетки. В этом окне будет происходить большая часть
Вашей работы по проектированию программы.
В) Окно редактора модуля( с заголовком unit1) почти полностью перекрыто окном формы
Для перехода в него нажмите F12. Окно модуля содержит программу на Паскале, в соответствии с
которой будет себя вести тот проект, который Вы создаете. Часть этой программы пишет сама
Delphi, а часть Вы. Начав новый проект Delphi уже создала часть кода программы, как видно в окне
модуля. Для обратного перехода в окно формы, нажмите F12
Г) Окно инспектора объектов (с заголовоком Object inspector) имеет страницу свойства
(Propeties) и события ( Events). Свойства и события характеризуют используемые в программе компоненты. Каждая из страниц имеет поле названия свойства либо события (слева) и поле соответствующего значения.( справа)
Все окна в соответствии с уже известной Вам технологией Windows можно передвинуть, минимизировать, закрыть, изменить размеры.
Задание: передвиньте и измените размеры окна формы и окна модуля так, чтобы они не перекрывали друг друга.
Урок 2
Тема урока: Основы визуального программирования.
Палитра компонентов – главное богатство Delpi. Под компонентом понимают некоторый
функциональный элемент, который программист располагает в окне формы. С помощью компонентов создается видимая, интерфейсная часть программы: диалоговые окна, кнопки и т.д. Процесс программирования в некотором смысле похож на конструирование программы причем “деталями” конструктора служат компоненты
Программа на Delphi (приложение, проект) состоит хотя бы из одного компонента- формы.
Т.е. только открыв новый проект Вы уже имеете программу, которую можно запустить на исполнение ( пункт меню Run или F9). Правда после запуска мы имеем пустое окно приложения , которое
однако можно переместить, изменить его размеры и т.д., т.е. это вполне рабочая программа, которую
написала за нас Delphi Нам же предстоит наполнить ее конкретным содержанием. Закройте программу и Вы перейдете в стадию проектирования.
Для размещения компонента на форме его нужно выбрать в палитре компонентов (щелкнуть
по нему левой кнопкой мыши), после чего щелкнуть левой кнопкой мыши в нужном месте формы.
Удалить компонент можно, выделив его (один щелчок левой кнопкой) и нажав на клавиатуре
клавишу Delete.
Размеры и местоположение компонента на форме можно изменить, выделив его и захватив левой кнопкой мыши, переместить на нужное место.
Задание:
Поместите на форму компонент “кнопка”( button) , страница «Standard». Переместите кнопку в левый
верхний угол формы. Увеличьте размеры кнопки. Поместите на форму компонент Stringgrid со страницы Additional и компонент Timer со страницы System . Теперь на форме у Вас три компонента Запустите программу.
Вы видите только два компонента. Компонент Timer невидим после запуска. Таким образом компоненты делятся на видимые и невидимые. Удалите компонент Stringgrid.
Каждый компонент - и форма в том числе - характеризуется определенными свойствами. Совокупность свойств отображает видимую сторону компонента: положение, размер, текст надписи и т.д.
Человек
Кнопка
Выполнить
Свойства:
Имя
Рост
Вес
значение
Иван
190 см
90кг
Свойства:
Имя
Надпись (Caрtion)
Ширина (Width)
Высота (Height)
значение
Button1
Выполнить
50
20
Свойства компонента можно изменять двумя способами:
1. В окне инспектора объектов, выбрав страницу Properties. Свойства, которые мы видим в окне инспектора объектов – это свойства периода проектирования, т.е. свойства, которыми будет обладать компонент в момент запуска программы. Например, если мы хотим, чтобы форма имела зеленый цвет сразу после запуска, то:
 Щелкните один раз по форме, чтобы выбрать ее (т.к. в вашей программе могут находиться несколько компонентов, обладающих свойством цвета, необходимо показать тот компонент, со свойствами которого Вы хотите работать)
 в окне инспектора объектов, на странице Properties, нужно щелкнуть по названию свойства Color и справа от него установить значение этого свойства, выбрав из раскрывающегося списка (щелкните по стрелочке в правой части окна)
2. Свойства компонентов могут меняться динамически, в ходе выполнения программы. Для изменения, например цвета формы во время работы программы нужно изменить значение свойства Color
формы, присвоив ему нужное значение. Имя свойства выступает в роли переменной, которой может быть присвоено значение из области допустимых . Для свойства Color допустимыми являются
значения: clred, clblue, clgreen и т.д.
Задание: измените свойство «Caption» (заголовок, надпись) формы. Для этого щелкните в правом
поле левой кнопкой и внесите текст « моя первая программа». В Вашей программе два компонента имеют
свойство Caption: Форма и кнопка. Для того, чтобы работать со свойством данного компонента, необходимо
сначала выделить компонент, щелкнув по нему мышью.
Измените свойство «Caption» кнопки на «Пуск». Измените шрифт надписи (свойство «Font»- двойной
щелчок мышью в правом поле)
Поведение компонента, т. е то, как компонент будет вести себя во время работы программы,
определяет страница Events (события) инспектора объектов.
Запустите программу. Нажмите на кнопку. При щелчке по кнопке мышью в работающей
программе возникает событие OnClick ( по нажатию). Пока это событие никак не обрабатывается
программой, и нажатие на кнопку не ведет ни к каким результатам. Она нажимается, но ничего не
происходит. Предположим, мы хотим, чтобы по нажатию на кнопку форма перекрашивалась в синийцвет. Для того чтобы по нажатию что-то происходило, необходимо написать обработчик события
нажатия на кнопку - фрагмент программы на Паскале, который оформляется в виде специальной
подпрограммы - процедуры. Закройте приложение. Выделите кнопку. Перейдите к странице Events
окна инспектора объектов и сделайте двойной щелчок справа от названия события OnClick (по нажатию). Ваш курсор переместится в окно модуля в заготовленную Delphi процедуру обработки события. Создадим процедуру, предписывающую форме изменять свой цвет, например, на голубой, по
нажатию на кнопку. Там, где мигает курсор, напишите:
Form1.color:=clblue;
Здесь form1- имя компонента, а color – его свойство. Свойство с таким же именем могут
иметь и другие компоненты Вашей программы, поэтому, чтобы Delphi было понятно, какому из
имеющихся в Вашей программе компонентов принадлежит данное свойство, необходимо имя компонента писать до имени свойства и отделять точкой.
Запустите программу. Нажмите на кнопку. Ваша первая программа работает!
Закройте приложение. Вы вернетесь в окно модуля.
Сохраните программу в отдельной папке командой «Save as(Сохранить как)». При этом
Вам будеть предложено сохранить два файла: файл проекта (Project1) и файл модуля формы
(Unit1). Сохраните их с роазными именами.
Для выхода из программы просто закройте главное окно либо выберите команду «выход» в
пункте меню «файл».
Урок 3
Тема урока: Компоненты и их свойства.
Задание: Запустите Delphi. Поместите на форму две кнопки. На одной надпись «красный» на другой
« синий» курсивом. По нажатию на первую кнопку цвет формы меняется на красный, по нажатию на вторуюна синий.
Всякую полезную программу необходимо сохранить на диске. Для этого каждый должен завести папку с собственной фамилией, куда и записывать создаваемые программы. Любая программа
на Delphi состоит из файла проекта( файл с расширением .dpr ) и одного или нескольких модулей
(файлы с расширением.pas) . Файл проекта создается самой Delphi и не предназначен для редактирования. Файлы же модулей мы будем создавать совместно. Для сохранения программы в пункте меню файл выберите save all. Вначале Вам будет предложено сохранить файл модуля ( под именем
unit1.pas), после этого будет предложено сохранить файл проекта( под именем proect1). Оба файла
нужно сохранить в отдельной, созданной Вами папке. Папки лучше создавать на диске С:, вкладывая
их в папку Мои документы
Познакомимся с еще некоторыми свойствами компонента «кнопка». Местоположение кнопки на форме , как Вы уже знаете можно изменить, передвигая ее мышью, а можно изменяя значения
свойства «Top” и «left» ( эти свойства меняют свои значения автоматически, когда Вы передвигаете
кнопку мышью). Размеры кнопки связаны со свойствами «Width» и « height». Свойство «Visible»
имеет два значения: истина и ложь. Установка второго делает кнопку невидимой после запуска программы. Свойство Enabled также имеет значения истина или ложь и определяет, можно ли нажать на
кнопку.
Задание: 1)Создайте новое приложение( файл->new application). Разместите на форме кнопку и
установите значение enabled->false. Запустите приложение (F9). Попробуйте нажать на кнопку. Закройте приложение. Поменяйте значение свойства на True. Те же действия повторите со свойством Visible. Убедитесь,
что кнопка невидима после запуска. (результат покажите учителю)
2) Создайте новое приложение( файл->new application). При этом программа спрашивает, нужно ли
сохранять предыдущий проект, в данном случае он не нужен, поэтому можно нажать No. Разместите две
кнопки, одна из которых невидима. Напишите обработчики событий кнопок, по нажатию видимая кнопка
должна становиться невидимой, а невидимая- видимой.
3) Создайте проект, в котором по каждому нажатию на кнопку она « перепрыгивает» на другое место
формы. (значения свойств Top и Left меняются при нажатии- им присваиваются случайные значения. Функция
случайного числа- Random (n)- где n- максимально возможное значение, в данном примере оно должно быть
равно ширине формы для свойства Left и высоте формы для свойства Top)
Интересным является свойство Hint (подсказка), которое есть почти у всех компонентов. Если в качестве значения свойства вы ввели какой-то текст (короткий), то он будет «всплывать» при
подведении курсора к компоненту. Одновременно необходимо установить значение свойства
ShowHint-> true (все это в окне инспектора объектов)
Задание: Добавьте всплывающую подсказку «нажми меня» для кнопки. Запустите программу. Подведите курсор к кнопке и задержите на некоторое время. Результат покажите учителю.
Для всех используемых в программе компонентов свойство Name- это то имя, под которым
компонент известен Вашей программе на Object Pascal. ( имя переменной). Значение свойства Name
в программе не меняйте!!!
Урок 4
Тема урока: Ввод-вывод данных. Приведение типов данных.
Сформулируем принципы Delphi-программирования:
А) Процесс конструирования Delphi-программы разбивается на две фазы: фазу конструирования
формы и фазу написания программного кода.
Б) Конструирование формы осуществляется с помощью выбора компонентов из палитры и размещения их на форме.
В) Чтобы придать компоненту нужные свойства, используется страница properties Инспектора
объектов. Такими свойствами будет обладать компонент в момент запуска программы. Свойства
компонентов могут также меняться динамически в ходе работы созданного приложения. Для этого
в программном коде должны быть соответствующие команды.
Г) Чтобы компонент мог откликаться на то или иное событие, программист должен создать обработчик событий и указать его имя на странице Events инспектора объектов.
Д) Обработчик события оформляется в виде отдельной подпрограммы- процедуры, напи
санной на Object Pascal. Delphi может автоматически сформировать заголовок процедуры обработки
события. Для этого необходимо сделать мышью двойной щелчок справа от названия события на
странице Events Инспектора Объектов.
Познакомимся еще с некоторыми часто используемыми компонентами.
.Компонент «panel» предназначен для объединения нескольких компонентов. Тогда перемещение
на форме компонента «panel» ведет к автоматическому перемещению всех, расположенных на ней
компонентов установив значение свойства align= albottom, Вы можете прижать панель внизу формы. (выбрав другие значения этого свойства панель можно прижать влево, вправо, вверх) Наличие,
либо отсутствие внешней видимой кромки Вы можете задать в свойстве bevelouter.
Компонент «bitbtn» страницы Additional-кнопка с надписью и пиктограммой. Свойство
«kind” этой кнопки позволяет выбрать надпись и пиктограмму. Причем, если выбрать значение
bkClose, то по нажатию на кнопку приложение закрывается (аналогично нажатию крестика в верхнем правом углу формы)
Строка ввода (компонент edit). Свойство text данного компонента может служить для ввода-вывода строки символов либо значения переменной символьного типа. Для вывода значения переменной числового типа необходимо предварительно привести значение этой переменной к строковому типу.
Компонент “метка” (label) Свойство caption этого компонента может служить для вывода
строки символов. Если мы хотим вывести длинное текстовое сообщение, необходимо придать свойству wordwrap (перенос слов) значение true для того, чтобы если сообщение не умещается в одной
строке, оно могло автоматически переноситься на следующую. Свойство autosize при этом должно
находиться в False
Задание Поставьте на форму компонент Panel , расположите его вдоль левого края формы, поставьте на панель Edit , BitBtn и метку. Для компонентов Edit и метка поменяйте шрифт
на красный, размером 14 пт. (свойство Font). Для очистки окна ввода очистите свойство Text.
Для очистки метки очистите свойство Caption. Cвойство Kind компонента BitBtn установите в
bkOk и напишите обработчик события нажатия на данную кнопку (OnClick), по которому числа,
вводимые в окно Edit будут через запятую добавляться в метку.:
Procedure TForm1.bitbtn1click (sender Tobject);// Заголовок формируется автоматически
Begin
Label1.caption:=label1.caption+’,’+edit1.text+; // строка в метке складывается из ее прежнего
значения, запятой и значения окна редактирования
Edit1.clear; // чтобы очистить окно для ввода следующего числа
Edit1.setfocus // чтобы курсор уже стоял в окне ввода и не нужно было мышью его туда ставить
End;
Обратите внимание на так называемые комментарии в тексте программы, которые поясняют
текст программы и пишутся через два косых слеша. Набирая программу, Вам не обязательно их
писать
В своих программах Вам постоянно необходимо организовывать диалог пользователь- программа. Т.е. необходимо осуществлять ввод-вывод данных. Данные хранятся в переменных. Для
ввода данных в переменные может служить компонент Еdit .Он представляет собой строку редактирования. Исходные данные задачи, которые Вы вводите в компонент являются значением его свойства Text Если Вы хотите введенное в окно значение сохранить в переменной, то вы присваиваете ей
значение этого свойства: a:=edit1.text. Для вывода на экран результатов решения Вашей задачи или
каких то сообщений можно использовать компонент label. , свойству Caption которого и присваивается выводимое значение, например Label1.Caption:= ‘Точка находится в правой полуплоскости’
Сложность в том, что оба эти свойства имеют строковый тип. Т.к. типы левой и правой частей команды присваивания должны совпадать, то чтобы вывести числовое значение, необходимо преобразовать числовой тип данных в строковый и наоборот, чтобы ввести значение в числовую переменную необходимо вводимую строку преобразовать в число. Если нам необходимо сохранить значение
edit.text в переменной числового типа, либо наоборот присвоить значение переменной числового типа свойству Caption метки необходимо осуществить преобразование типов данных. Для этого
можно воспользоваться стандартными функциями :
inttostr(< имя переменной типа integer>)- значением функции является строка символов;
например:
….
var a:integer;
begin
a:=12;
Тогда можно далее в программе написать оператор присваивания:
Label1.caption:= inttostr(a);
strtoint(<имя переменной строкового типа>)- значением функции является целое число, причем будет выдано сообщение об ошибке, если строку нельзя преобразовать в число, например строку’123а5’
например:
var a:integer;
begin
…
a:=strtoint(edit1.text);
…
далее, т.к. в переменной а число, можно производить арифметические операции, если это необходимо в ходе программы.
Для переменных вещественного типа определены следующие функции преобразования:
Strtofloat -преобразование строки символов в вещественное число
Floattostr -преобразование вещественного числа в строку символов
Для самостоятельного выполнения предлагается следующая задача: Разработать программу пересчета веса из фунтов в килограммы.
Визуально программа должна выглядеть примерно так:
Фунты-килограммы
Компонент edit
для ввода веса в фунтах
Компонент label Для вывода веса в кг
Компонент Panel
Компоненты bitbnt
первая кнопка типа BkOk, вторая – типа BkClose.
По нажатию на первую – пересчет,
на вторую – выход из программы.
Кнопки расположены на Панели, прижатой к нижнему
краю формы. Align – alBottom
Для пересчета в кг используется коэффициэнт 0,405 т.е в 1 фунте 0,405 кг.
Расставив компоненты на форме, Вы завершаете первый этап конструирования программы. Далее
необходимо написать программный код, который будет выполняться по нажатию на кнопку BkOk
(во второй можно ничего не писать). Заготовьте обработчик события (выделите нужную кнопку.
Двойной щелчок на странице Events , справа от названия события). В обработчике должны быть
команды:



Ввода с клавиатуры в переменную значения веса в фунтах (не забудем преобразование строкового значения в числовое): а:=strtoint(Edit1.text);
Пересчета в килограммы.
Вывод значения в килограммах в метку ( преобразуя из числа в строку символов, полученное
значение не целое число): Label1. Caption:= floattostr(a)
Задание Составить программу, которая позволяет ввести два числа и выводит произведение этих чисел. В
данной программе три компонента edit- один для первого операнда, другой для второго, третий для вывода
результата. И кнопка с надписью «вычислить». После нажатия кнопки «вычислить» (обработчик события
OnClick):
 Из первого окна значение преобразуется в числовой тип и присваивается числовой переменной:
 То же происходит со значением второго окна ввода, но присваивается другой переменной, например b
 В третью переменную присваивается результат произведения переменных a и b.
 Произведение преобразуется в строковый тип и присваивается свойству Caption метки
Задачи для самостоятельного решения:
1. Найти площадь кольца, внутренний радиус которого равен R1 а внешний R2
2. Найти произведение цифр заданного четырехзначного числа.
3. Найти сумму цифр заданного трехзначного числа.
4. Скорость первого автомобиля v1 км/ч, второго-v2 км/ч, первоначальное расстояние между ними s км. Какое расстояние будет между ними через t часов, если автомобили движутся в разные
стороны.
5. Три сопротивления R1,R2,R3 соединены параллельно. Найдите сопротивление соединения.
6. Вычислить периметр и площадь прямоугольного треугольника, у которого известна длина гипотенузы и один катет вдвое длиннее другого.
7. Найти ускорение материальной точки, если известна ее начальная скорость, конечная скорость
и время, за которое произошло ускорение.
8. Определить ускорение, с которым двигается тело заданной массы, если известна действующая
на это тело сила.
9. Вычислить работу, совершенную при поднятии груза заданной массы на заданную высоту.
10. Вычислить периметр и площадь равнобедренного треугольника, у которого длина основания известна, а длина боковой стороны в 2 раза больше длины высоты, опущенной на основание.
11. определить гипотенузу прямоугольного треугольника и его площадь по двум известным катетам.
Урок 5
Тема урока: Управляющие структуры Object Pascal. Команда ветвления.
.Алгоритмы решения большинства задач не являются последовательными. Действия, которые необходимо выполнить, могут зависеть от определенного условия. Например, в программе проверки знаний сумма баллов будет зависеть от количества правильных ответов. Фрагмент алгоритма решения
подобной задачи может выглядеть так:
Получить ответ
пользователя
Нет
Сообщение
«Ошибка»
Ответ
правильный
да
Увеличить счетчик
правильных ответов на 1
Сообщение
«Правильно»
Формат команды ветвления:
If<логическое выражение> then <команда1> else<команда 2>
Если вместо одной команды необходимо выполнить несколько, эти команды должны быть заключены в операторные скобки – слова begin…end
Логическое выражение имеет левую и правую часть , объединенные знаками логических отношений:
=, <>, <=, >=.,>, < . Логическое выражение может быть истинным, либо ложным.
Примеры истинных логических выражений: 5>7, 3+2=5
Если в логическом выражении присутствуют переменные, то от их значений зависит истинность
или ложность выражения, например: s>100, истинно, если значение переменной s больше 100 и
ложно в противном случае
Примеры ложных логических выражений: 4<1 , 5=7
Из нескольких простых логических выражений при помощи логических операторов and, or и not
могут составляться сложные логические выражения. При этом нужно учитывать то, что логические операторы имеют более высокий приоритет, чем операторы сравнения, и поэтому простые
условия следует заключать в круглые скобки, например: ( a>3) and (a<10)
Значение сложного логического выражения зависит от значений простых, входящих в него и от
логической операции:
Выр1
выр2
выр1 and выр2
выр1 or выр2
not выр1
False
false
false
false
true
False
true
false
true
true
True
false
false
true
false
True
true
true
true
false
1. В качестве примера составим программу, анализирующую вес человека.
Главная форма имеет вид:
Вес
Компоненты
Edit для ввода
веса и роста
Рост
Сообщить
Кнопка, по нажатию
на которую выдается сообщение «Вам
нужно похудеть»
или «Вам нужно поправиться» в зависимости от введенных роста и веса
Сообщение, выдаваемое программой, будет одно из трех: «Вы в хорошей форме» либо «Вам
нужно поправиться» либо «вам нужно похудеть» . Вывод одного из трех сообщений будет зависеть
от величины переменной, значение которой вычисляется как (рост-100 ) . Если значение этой переменной равно весу, то выводится первый вариант сообщения. Если значение переменной больше
веса, то вес недостаточен. Для вывода сообщения воспользуемся новой для нас командой вывода:
Showmassage(‘текст выводимого сообщения’).
Все действия по вводу данных, вычислению , выбору и выводу соответствующего сообщения производятся по нажатию на кнопку , следовательно команды, реализующие алгоритм решения
задачи, находятся в процедуре обработки события нажатия кнопки.
Задачи для самостоятельного решения:
1. Составить проект, в котором по нажатию на одну и ту же кнопку форма попеременно перекрашивается то в красный, то в синий цвет. Ключевой фразой обработчика события нажатия на
кнопку является: «Если форма красная, то перекрасить в синий цвет, иначе перекрасить в красный цвет» Дополнительное задание (на «5» баллов»):Добавить к данному проекту изменение
надписи на кнопке: в то время, как форма красная на кнопке должна быть надпись «В синий», и
наоборот, когда форма синяя на кнопке должна быть надпись «в красный»
2. Реализовать решение квадратного уравнения. В качестве исходных данных вводятся коэффициэнты. Программа вычисляет и анализирует дискриминант. В зависимости от значения дискриминанта программа либо вычисляет и выводит корни уравнения , либо выводит сообщение о том,
что дискриминант отрицательный и уравнение не имеет корней.
3. Сообщить, составляют ли числа А,В и С арифметическую прогрессию
4. Даны координаты двух точек. Выяснить, какая из них находится ближе к центру координат
5. Принадлежит ли точка с заданными координатами плоскости, ограниченной окружностью
радиуса R с центром в начале координат?
6. Какой координатной четверти принадлежит точка с заданными координатами?
7. Даны два числа А и В. Сообщить, какое из них четное, какое нечетное.
8. Принадлежит ли точка с заданными координатами правой полуплоскости?
9. Даны три числа А, В, С. Сообщить, какие из них больше 1 , но меньше 10?
10.
Даны три числа А, В, С. Сообщить, составляют ли они арифметическую прогрессию?
11.
Формула серной кислоты H2SO4. Сколько молекул серной кислоты Вы можете получить имея
N1 атомов водорода, N2 атомов серы и N3 атомов кислорода?
12.
Определить, является ли треугольник со сторонами a и b равнобедренным.
13.
Из одного города в другой выехал автомобиль со скоростью v1 км/ час. Через t часов в этом
же направлении выехал второй со скоростью v2 км/ч. Выяснить, догонит ли второй автомобиль
первого через t1 ч после своего выезда.
14.
Составить программу, определяющую результат гадания на ромашке "любит-не любит” в
зависимости от заданного количества лепестков N/
Локализация имен
Каждая процедура обработки события имеет, подобно программе, исполняемую часть, заключенную
между словами Begin-end и описательную часть, расположенную после заголовка, где Вы объявляете
переменные. В Вашем проекте может быть несколько процедур и переменные, объявленные внутри
одной из них “не видны” из других процедур, говорят, что они локальные, иными словами их значения не могут быть использованы в других процедурах, а это часто бывает необходимо. Для того,
чтобы переменная была доступна всем процедурам Вашего модуля, она должна быть объявлена в
блоке описаний модуля (поднимитесь по тексту вверх и найдите блок описания переменных, начинающийся со слова Var) до слова Implementation. Такие величины будут являться глобальными
по отношению ко всем процедурам модуля.
Еще о событиях .
. До сих пор Вы писали только обработчик события нажатия на кнопку. Во время работы Вашего
приложения постоянно происходят разные события. Каждое из них имеет название. Например, когда
Вы двигаете курсором мыши на форме, происходит событие OnMouseMove формы, когда нажимаете кнопку мыши- событие OnMouseDown, когда отпускаете- событие OnMouseUp. Во время запуска
приложения (после нажатия F9) последовательно происходят события OnCreate, OnActivate, OnPaint
формы, причем в перечисленном порядке. Если Вам необходимо, чтобы какие-то команды выполнялись в момент запуска программы, их нужно писать в обработчике события OnCreate формы.
Компонент Memo
Представляет многострочный текстовый редактор. Чтобы очистить окно, очистите свойство lines
(нажмите три точки и сотрите текст в появившемся окне). Добавить строку в окно можно:
Memo1.Lines.add (‘<добавляемая строка>’). Очистить окно- Memo1.clear. Для просмотра «ушедшего»
текста можно воспользоваться полосами прокрутки, которые можно получить, установив свойство
scrollbars данного компонента.
Задание: Поставьте на форму Memo, Edit и кнопку (любую). По нажатию на кнопку строка, введенная в Edit
будет добавляться в Memo. Обработчик события нажатия на кнопку будет выглядеть:
Procedure Tform1.button1Click (sender:Tobject);
Begin
Memo1.lines.add (edit1.text);
Edit1.clear;
Edit1.setfocus;
End;
Самостоятельно выясните, на что влияет значение свойства Alignment данного компонента. (Чтобы увидеть
результат окно не должно быть пустым). Результат покажите учителю.
задание
Запрограммировать игру “Угадай число” по следующему алгоритму:





переменной присваивается случайное число в интервале до 100. (в момент запуска программы)Так как
число случайное, то мы точно не знаем, какое оно и будем отгадывать.
Играющему предоставляется возможность угадать число, вводя числа с клавиатуры в окно Edit
После ввода очередного числа нажимается кнопка, в обработчике события которой :
А) число из edit присваивается числовой переменной
Б) ее значение сравнивается с “задуманным” машиной
В) если введенное число меньше случайного, то в Memo выводится сообщение “мало”, если
вводимое число больше, выводится сообщение “много”. При совпадении чисел выводится
сообщение “ Угадано” .
Для начала новой игры должна быть кнопка с надписью “новая игра”, по нажатию на которую будет задумано новое число.
Программа должна содержать кнопку выхода.
Урок 6
Тема урока: Управляющие структуры Object Pascal. Команда выбора.
Иногда алгоритм решения задачи требует сделать выбор в зависимости от выполнения одного из
множества условий. Данный алгоритм удобно реализуется при помощи оператора выбора, формат
которого:
Case <выражение> of
<список1>: <команда1>;
<список2>:<команда2>;
…
end;
где выражение д.б. любого порядкового типа, типы констант списков того-же типа, что и выражение.
Выполняется команда следующим образом: вычисляется значение выражения, следующего за Case .Полученное значение последовательно сравнивается с константами из списков , стоящих
перед двоеточием. Если значение совпадает со значением константы одного из списков, выполняется
соответствующая данному списку команда. Если значение выражения не совпадает ни с одной константой из всех списков, выполняется команда, следующая за end.
Задание В качестве примера составим программу, имитирующую работу калькулятора. Программа вводит два операнда в окна ввода и позволяет выбрать из списка знак математического действия, после чего выводит результат. Для выбора арифметического действия удобно поместить на
форму компонент типа ComboBox –раскрывающийся список выбора. Уменьшите его щирину(там
должен помещаться лишь знак операции. Свойство Items этого компонента позволит ввести четыре
строки со знаками математических действий. (на странице Properties) Первой строке (первому знаку)
будет соответствовать константа «0», второму- «1» и . т.д. Это значение содержит свойство
itemindex. Для ввода операндов справа и слева от ComboBox разместите по компоненту edit. Очистите свойство text у всех трех компонентов. Для анализа выбранного математического действия
может, например, служить такой фрагмент обработчика событий:
Case Combobox1.itemindex of
0: z:=x+y;
1: z:=x-y;
2: z:=x*y;
3: z:=x/y;
end;
естественно, что до этого фрагмента переменные x и y должны получить значения из компонентов
Edit После фрагмента необходимо сделать вывод значения переменной z
1. Задание: Разработать программу калькулятора, имеющего вид приложения “Windows» с нажимающимися кнопками цифр, знаков и равенства. Обработчики событий пишутся для каждой кнопки.
Компонент Timer (страницаSystem)
Служит для отсчета интервалов реального времени.. Таймер включен, когда свойствоEnabled имеет
значение True. Если таймер включен, с определенной частотой происходит событие OnTimer , т.е. с
определенной периодичностью выполняются команды этого обработчика. Повторение происходит
тем чаще, чем меньше значение свойства Interval ( при значении 1000 событие происходит раз в секунду)
Задание
Реализовать программу имитирующую работу секундомера.
Форма должна иметь кнопку
«пуск/стоп» для включения/выключения секундомера, окно вывода показаний времени (лучше Memo,
т.к. у компонента Edit нет свойства Alignment, позволяющего прижать текст окна вправо) для показаний времени. Установите исходный текст окна показаний времени в момент запуска (на странице
Properties)- «0.0» Кнопка «Сброс» будет сбрасывать показания окна. Добавьте компонент Timer
(невидим, поэтому все равно куда). Установите значение свойства Interval=1000. В момент запуска
программы таймер должен быть выключен.
При запуске программы:
обнуляем переменную времени (глобальная)
При нажатии кнопки «Пуск»:
Анализируется, если таймер выключен, то включаем его (свойству Enabled присваиваем значение
True) и меняем надпись на кнопке на «Стоп» (присваиваем свойству Caption); если включен (иначе),
то выключаем его и меняем надпись на «Пуск»
По каждому тику таймера (событие OnTimer)
Переменная времени увеличивается на 1
Значение переменной выводится в окно вывода ( присваивается свойству Text компонента Memo)
Урок 7
Тема урокаГрафические возможности Delphi
Графические изображения можно создавать на поверхности объектов- формы или компонента Image.
При этом используется свойство canvas данных компонентов. Методы вывода графических примитивов рассматривают это свойство как некоторый абстрактный холст состоящий из точек (пикселей),
канаву на которой можно рисовать по точкам. Положение пиксела характеризуется его горизонтальной (х) и вертикальной(у) координатой. Пиксел левого верхнего угла компонента имеет координаты
(0,0). Значения координат правой нижней точки зависят от размера холста , им соответствуют значения свойств height и width. Применяя соответствующие методы к свойству canvas можно получить
на поверхности необходимый графический элемент, например:
команда сanvas.ellipse(x1,y1,x2,y2)- позволяет нарисовать окружность
команда canvas.rectangle(x1,y1,x2,y2)- прямоугольник
Прямоугольник при этом закрашен. Он прозрачен, если нарисовать его командой
Polyline([point(x1,y1),point(x2,y2),point(x3,y3),point(x4,y4)]);
команда lineto(x,y)- рисует линию от текущего положения пера в точку с указанными координатами
moveto( x,y)- перемещает перо без следа в точку с указанными координатами
polygon([point(x1,y1),point(x2,y2),…point(x,y)])- замкнутый многоугольник, координаты вершин которого заданы массивом точек
Для вычерчивания линий и контуров используется свойство Pen, а для закрашивания областей, ограниченных контурами, -свойство Brush. Перо может рисовать линию разной ширины и цвета: Для этого необходимы соответствующие команды в программе, например
Canvas.pen.width:=3; -устанавливает толщину линии в 3 пиксела
Canvas.pen.color:=clblue;- устанавливает цвет линии синий
Другое свойство пера( mode) позволяет ему по разному взаимодействовать с полотном , на котором
оно рисует. В обычном режиме это свойство имеет значение PmCopy. Режим pmNotXor позволяет
повторной прорисовкой линии на том же месте стереть ее. На этом может быть основана простейшая
анимация:
Соответственно можно установить цвет заливки кистью замкнутых областей.
Canvas.brush.color:=clred;
Задание: Нарисовать перекрещивающиеся в центре формы линии
Линии должны быть видны в момент за пуска программы, но обработчик события Onactivate формы
не подходит для этой цели, т.к. когда происходит данное событие форма еще не прорисована на
экране и канва не существует. После события Onactivate происходит событие прорисовки формы и
создания поверхности с канвой пиксел- Onpaint. Обработчиком данного события и можно воспользоваться для построения изображений на форме в момент запуска программы.
Проект «Траектория движения тела, брошенного под углом к горизонту»
Вопрос: Отчего зависит траектория движения тела, брошенного под углом к горизонту? ( от начальной скорости и угла)
Т.к исходные данные любой задачи задаются с клавиатуры, необходимы два окна ввода. После ввода
численных значений в эти окна нажимается кнопка и мы видим вычерчивание траектории на форме.
В обработчике события нажатия на кнопку:
1) обнуляется переменная отсчета времени.
2) перо перемещается в левый нижний угол экрана.
3) Для дальнейших вычислений.исходные данные из окон ввода присваиваются переменным
т.к. угол мы будем, видимо задавать в градусах, а в вычислениях используется только радианная мера, не забудем перевести введенное значение в радианы: a:=(a*3.14)/180
4) Запускается таймер.
Траектория движения строится из прямолинейных отрезков в обработчике событий таймера, за счет
этого будет создана иллюзия движения. Для построения отрезков необходимо вычислять координаты
положения тела в каждый момент времени и проводить линию в точку с этими координатами. Разложим скорость на две составляющие: горизонтальную и вертикальную:
V
V2
V1
V1=V*cos (a); v2=v*sin(a);
При каждом тике таймера (событие Ontimer):
1) переменная времени увеличивается. (t:=t+1)
2) Вычисляются координаты тела: горизонтальное движение равномерное, если принебречь сопротивлением воздуха и горизонтальная составляющая пути в каждый момент времени вычислится
как x= v*cos(a)*t . Вертикальное движение равнозамедленное и вертикальная составляющая пути
в момент времени t: y=v*sin(a)*t-9.8*sqr(t)/2. Не забудем, что на экране вертикальная координата
растет вниз, поэтому для построения точки вычисленное значение y нужно вычитать из максимального значения для формы.
3) Проводится отрезок в точку с вычисленными координатами.
Дополнительное задание:
Используя свойствоMode пера попробуйте смоделировать полет ядра, перемещая кружочек и стирая
каждый раз его.
Задание Смоделируйте движение математическогог маятника
Построим динамическую модель колебания математического маятника: груза на невесомом нерастяжимом стержне, отклоненного от вертикали на некоторый угол. Сила трения не учитывается.
1. Исходные данные:
 L--длина стержня
 al—угол отклонения
 V- линейная скорость=0 в момент отпускания
 W—угловая скорость=0 в момент отпускания.
 Dt-- Период дискретизации по времени
2. Математические соотношения:
 Сила тяжести, действующая на груз F=m*g
 Ее проекция на направление касательной Fкас=F*sin(al) Проекция вдоль стержня компенсируется
упругостью стержня.
 Ускорение вдоль касательной a=Fкас/m= g*sin(al)
 Новое значение угла через время dt al=al-w*dt
 Новая линейная скорость v=v+a*dt
 Новая угловая скорость w=v/l
Для повторения воспользуемся таймером.
Урок № 8
Тема урока: Управляющие структуры Object Pascal. Циклы.
Алгоритмы решения многих задач являются циклическими, т.е. для достижения результата
определенная последовательность действий должна быть выполнена несколько раз. Например, программа проверки знаний должна вывести вопрос, проветить ответ, добавить оценку за ответ к сумме
баллов, затем повторять действия, пока испытываемый не ответит на все вопросы. Такие повторяющиеся действия называются циклами.. Object Pascal для решения подобных задач имеет циклы трех
видов : for, while, repeat.
Цикл For используется в том случае, когда заранее известно число повторений, которое
необходимо произвести. В общем случае цикл выглядит так:
For <параметр цикла> :=<начальное значение>to <конечное значение> do <команда>,
Где параметр цикла- переменная порядкового типа, начальное и конечное значения- выражения того же типа. Выполняется команда следующим образом: Переменная- параметр получает
начальное значение и, если оно не превышает конечного, команда выполняется, после чего параметр
автоматически увеличивается на 1 и опять проверяется, не превышает ли он конечного и т.д.
В качестве примера рассмотрим программу, осуществляющую ввод любого целого числа и
выводящую в качестве результата сумму всех натуральных чисел в интервале до введенного. :
Procedure Tform1.button1click(sender:tobject);
Var n,i,sum:integer;
Begin
If edit1.text=’’ then exit;// если число не введено, то по нажатию кнопки завершение работы
программы.
N:=strtoint(edit1.text);
Edit1.text:=’’;
Edit1.setfocus;
Sum:=0;
For i:=1 to n do sum:=sum+i;
Label1.caption:=’сумма=’+inttostr(sum);
End;
Цикл While
Применяется, когда заранее неизвестно количество повторений, действия же должны повторяться до тех пор, пока выполняется какое- либо условие
Формат оператора:
While<лог выражение> do <команда>
Анализируется значение лог. выражения, и если это значение истина, команда выполняется, после чего снова анализируется значение логического выражения и т.д.. Если нужно повторять
выполнение группы команд, они заключаются в операторные скобки. Если выражение ложно с самого начала, то команда вообще не выполняется. Предыдущая задача выглядит следующим образом:
Procedure Tform1.button1click(sender:tobject);
Var n,i,sum:integer;
Begin
If edit1.text=’’ then exit;
N:=strtoint(edit1.text);
Edit1.text:=’’;
Edit1.setfocus;
Sum:=0;
i:=1
while i<= n do
begin
sum:=sum+i;
i:=i+1;
end;
Label1.caption:=’сумма=’+inttostr(sum);
End
Цикл Repeat
Repeat<команда>
Until<логическое выражение>
Цикл отличается от предыдущего тем, что условие выхода из цикла проверяется после выполнения команды, т.е. команда цикла выполняется хотя бы один раз. Команда будет выполняться
до тех пор, пока логическое выражение ложно.Та же задача выглядит:
Procedure Tform1.button1click(sender:tobject);
Var n,i,sum:integer;
Begin
If edit1.text=’’ then exit;
N:=strtoint(edit1.text);
Edit1.text:=’’;
Edit1.setfocus;
Sum:=0; i:=1;
repeat
sum:=sum+i; i:=i+1;
until i>n
Label1.caption:=’сумма=’+inttostr(sum);
End
Задание:
Организуйте горизонтальное движение окружности по форме.
1. Если мы хотим, чтобы движение началось по щелчку мышкой по форме, пишите обработчик события формы OnClick
2. Установите режим пера canvas.pen.mode:=pmNotXor
3. Нарисуйте кружочек в левой части формы.
4. Задержите выполнение программы, чтобы глаз успел увидеть кружочек. Это можно сделать пустым циклом, т.е циклом на большое количество(10000000) повторений, которые ничего не выполняют.
5. Нарисуйте такой же кружочек на этом же самом месте, он станет невидим.
6. Измените координаты кружочка, сместив его по горизонтали.
7. Повторяйте пункты алгоритма, начиная со второго, пока координаты кружочка не выходят за
пределы формы.
Canvas.Pen.mode:=pmnotxor;
x:=10;
repeat
canvas.ellipse(x,100,x+20,120);
for i:=1 to 10000000 do;
canvas.ellipse(x,100,x+20,120);
x:=x+5;
until x>form1.width;
Задание Нарисуйте в центре формы 10 концентрических окружностей . Радиус самой маленькой- 10 пикселей. Шаг изменение радиуса 20 пикселей.
Урок 9
Тема урока: Циклы. Практика применения.
Задание: Составить программу, проверяющую, является ли введенное число простым.
Комментарий к программе:
В обработчике события кнопки пытаемся реализовать следующий алгоритм:
Делим число последовательно на 2, 3 и т.д. до тех пор, пока не разделим нацело. Здесь возможны два варианта: либо число разделилось нацело и делитель меньше данного числа- тогда оно
непростое, либо нацело число разделилось на самого себя и тогда оно простое.
A:=2;
R:=n mod a;
.
Нет
R=0
да
A:=a+1
Нет
число непростое
А=n
да
число простое
procedure Tform1.button1click(sender:Tobject);
var n,a,r:integer;
begin
n:=strtoint(edit1.text);
a:=2;
repeat
r:=n mod a;
if r<>0 then a:=a+1;
until r=0;
if a=n then label1.caption:=’число простое’ else label1.caption:=’число непростое’
Дополнительные задачи:
1.
Сосчитать количество делителей данного введенного числа и их сумму.
2.
Выяснить, является ли данное число совершенным
3.
Начав тренировки, спортсмен пробежал 10 км. В первый день. Каждый следующий день он
увеличивал дневную норму на 10% от нормы предыдущего дня. Какой суммарный путь пробежит
спортсмен за 7 дней?
4.
На каждом дне рождения Винни Пух съедает столько же пищи, сколько на двух предыдущих.
На двух первых он съел по 100 г. Сколько кг пищи он съел на 15-м дне рождения?
5.
Царевна-лягушка съедает ежедневно на 20% комаров больше, чем в предыдущий день и еще
два комара. Через сколько дней количество съеденных комаров превысит 100, если в первый день
было съедено 12 комаров?
6.
Составить программу вывода отрицательных значений функции:
Q=3h/tg(3,9h(23,8+19h)) на отрезке s — 4,23 с шагом t
Используйте для вывода компонент memo
Урок 10
Тема урока: Процедуры и функции.
. Структурное программирование подразумевает разбиение большой задачи на отдельные, логически законченные части и написание подпрограмм , реализующих каждую часть задачи. Каждая такая
часть программы получает свое имя. Мы как бы “учим” машину новым командам. Тогда всю большую программу мы можем написать, вызывая по именам отдельные ее части ( вызываем новые команды)в нужной нам последовательности. Для пояснения вышесказанного проведем аналогию ,
например, в кулинарии: Если мы собираемся испечь торт “Наполеон”,мы возьмем кулинарную книгу
и посмотрим рецепт, который гласит, что нужно приготовить 300 г. слоеного теста, испечь из него 6
коржей. Затем приготовить 200 г. заварного крема и смазать им коржи. Эта сложная задача имеет команды: приготовить слоеное тесто и приготовить заварной крем. В рецепте они подробно не описаны. Видимо, мы откроем раздел, где описано приготовление различного рода теста и посмотрим, как
приготовить слоеное тесто . Затем в разделе “Кремы” посмотрим как приготовить заварной крем.
Очевидно, что заварной крем может использоваться и в других рецептах, например для изготовления
заварных пирожных, возможно, что лишь количество его будет другим. Также и слоеное тесто. Очевидно, что было бы просто нерационально каждый раз, где потребуется в рецептах такой крем , заново описывать его приготовление- объем кулинарной книги неоправданно бы возрос.
Возвращаясь к программированию, можно сказать, что структурированная( разбитая на части) задача имеет следующие достоинства:
1) легче читается- становится понятней
2) легче отлаживается( отдельными небольшими частями)-сокращается вероятность ошибок
3) одну задачу могут разрабатывать несколько программистов одновременно( при неиспользовании глобальных величин)
Возможность писать хорошо структурированные программы дают такие средства Object Pascal как
процедуры и функции.. Процедура- это какая-то последовательность команд, снабженная именем
и вызываемая при помощи этого имени. Процедура обычно реализует логически законченную подзадачу.
Упоминание в тексте программы имени процедуры ведет к выполнению команд, находящихся в тексте этой процедуры, после чего управление передается команде, стоящей непосредственно за именем
процедуры.. Использование процедур позволяет не писать многократно алгоритм при повторном его
использовании, а просто вызывать его по имени. Функция отличается от процедуры тем, что результат ее работы возвращается в виде значения этой функции, и , следовательно, вызов функции
может использоваться наряду с другими операндами в выражениях. Для обмена данными между основной программой и процедурой используется один или несколько параметров..(параметры могут
отсутствовать) . Если в процедуре имеются параметры, они пишутся в круглых скобках за именем
процедуры. В Object Pascal есть много стандартных процедур и функций, реализующих наиболее часто используемые операции, например функции приведения типов, случайного числа, математические функции, процедуры showmassage, exit и т.д. Это значительно облегчает работу. Но специфичные для конкретной прикладной программы действия не находят аналогов и тогда программисту
приходится разрабатывать свои, нестандартные процедуры и функции В частности, алгоритмы, описывающие действия, происходящие в программе по нажатию той или иной кнопки, Delphi оформляет
в виде отдельных процедур- процедур обработки события нажатия на кнопку. Заголовок формируется автоматически, текст же процедуры , определяющий конкретные действия, вы пишете сами.
Procedure <имя процедуры> [(список формальных параметров)]; - заголовок обязателен
в отличие от заголовка программы
<описательная часть > описаны локальные величины
begin
<команды>
исполняемая часть процедуры
end;
Процедура может иметь свой блок описаний типов, констант, переменных, процедур и функций. Все описанные в процедуре имена “не видны” из основной программы, говорят , что это локальные имена, которые “видны” только в самой процедуре или в процедурах, описанных внутри
нее, т.е в блоках более низкого уровня. Все имена, описанные в основной программе доступны для
использования всем процедурам и функциям, описанным в этой программе, они являются глобальными. Локапльные переменные освобождаются сразу после завершения работы процедуры, поэтому
использование их более грамотно и предпочтительно. Т.е. если переменная не нужна основной программе, а используется только во время работы данной конкретной процедуры, ее следует объявлять
как локальную в блоке описаний данной процедуры.
Параметры процедур
В список параметров процедуры выносятся исходные данные для работы процедуры и переменная,
в которой будет находиться результат работы процедуры. Параметры, указанные при описании
процедуры, называются формальными. При вызове они заменяются на фактические. При описании
процедуры в списке формальных параметров указываются имена переменных и их типы, причем
допускается лишь простое наименование типа( из одного идентификатора). Перед именами переменных, которые будут передавать результат работы процедуры, ставится слово var. В списке фактических параметров перечисляются лишь имена переменных. Параметры позволяют вызывать одну и ту же процедуру с разными значениями исходных данных. Число формальных и фактических
параметров должно совпадать, они должны совпадать по порядку следования и по типу
Формальные параметры
Фактические параметры
в описательной части программы
следуют за заголовком процедуры
перечислены имена переменных с
указанием типов
задают шаблон для фактических
в исполняемой части программы
следуют за именем процедуры
перечислены только имена без
указания типа
заполняют шаблон конкретными
значениями
В качестве примера рассмотрим задачу нахождения Наибольшего Общего делителя натуральных чисел
Implementation
Procedure NOD (var x,y:integer); //большее из чисел последовательно заменяется на их разность
Begin
//после работы процедуры значение любой из переменных- НОД
Wtile x<>y do
If x>y then x:=x-y else y:=y-x;
End;
Procedure button1.click (sender:Tobject);
var a,b,c:integer;
Begin
A:=strtoint(edit1.text);b:=strtoint(edit2.text);c:strtoint(edit3.text);
NOD (a,b);NOD(a,c);
Label1.caption:= ‘НОД=’+ inttostr( a);
End.
Задание Найти максимальное из 4-х заданных чисел, используя процедуру поиска максимума среди
2-х чисел.
Урок № 11
Расширенное знакомство с компонентами
Компоненты Mainmenu ,Popupmenu.
Находятся компоненты на странице Standard палитры компонентов и позволяют создать соответственно главное и локальное (его еще называют контекстным, оно вызывается щелчком правой
кнопки мыши) меню в проекте. Оба компонента невидимы.( во время работы программы)
Компонент Mainmenu
Пункты главного меню располагаются в верхней части формы и должны предоставлять возможность
вывода текста из файла в memo и рисования выбранной геометрической фигуры .Поместим на форму компонент memo. Он должен быть невидим в момент запуска программы, т. к неизвестно, какой
пункт меню будет выбран вначале и , следовательно, будет ли memo мешать. Поместим компонент
Mainmenu в любое место формы ( он все равно невидим). Для создания пунктов этого меню служит
дизайнер меню, который вызывается двойным щелчком левой кнопкой мыши по компоненту. Озаглавим первый пункт меню «Текст» ( Это значение приобретает свойство caption данного пункта меню). Обычно горизонтальные пункты главного меню имеют «выпадающие» по щелчку вниз пункты
подменю. Эти пункты автоматически предлагается создать после очередного пункта. Создайте пункты «открыть» и «очистка» в меню «текст». Если подменю не нужно, то курсорной клавишей можно
переместиться вправо и создавать очередной пункт главного меню. Добавьте в меню пункт «фигуры», в котором пунктами подменю будут «круг» и « квадрат».Если в уже созданное меню необходимо вставить пункт где-то в середине или начале, щелчком правой кнопки мыши по нужному пункту
вызывается контекстное меню, в котором предоставляется возможность удаления( delete) этого пункта меню, вставки перед ним нового пункта (insert), либо добавления в пункт меню выпадающего горизонтально следующего уровня подменю (create submenu).Все изменения в имеющееся меню вносятся в дизайнере меню, который вызывается двойным щелчком левой кнопки мыши по компоненту Mainmenu Добавьте пункт «Параметры линии» между пунктами «текст» и «фигуры». В данном пункте меню создайте выпадающие «ширина»и «цвет». Пункт «ширина» в свою очередь должен
содержать возможность выбора 2, 4 или 6 пиксел. Для этого щелкните правой кнопкой по пункту
ширина и выберите create submenu, создайте соответствующие пункты. Запустите программу. У Вас
имеется созданное Вами меню, но по выбору соответствующего пункта ничего не происходит, т.к
еще не созданы соответствующие обработчики событий. Закройте приложение.
Для создания обработчиков событий, происходящих при выборе пунктов меню, необходимо выполнить двойной щелчок левой кнопкой на соответствующем пункте меню в дизайнере меню. Опишем,
что должно происходить при выборе пункта «Открыть» меню «текст». Т.К. вывод текста из файла
должен происходить в компонент memo1, который невидим на момент запуска программы, прежде
всего необходимо написать команду, делающую видимым этот компонент. Чтение строк из текстового файла в массив строк ( lines ) компонента memo можно осуществить при помощи метода loadfromfile(‘ имя файла’). Добавьте в обработчик команду memo1.lines.loadfromfile (‘<имя текстового файла’>. В команде необходимо указать полное имя файла, лучше, чтобы файл находился в той же папке, что и создаваемый проект. Прежде всего сохраните проект, создав для него папку. Как Вы помните при этом необходимо будет сохранить два файла: файл проекта ( будет предлагаться имя project1.dpr) и файл модуля (будет предлагаться имя unit1.pas). Сложите на панель задач Delphi и при
помощи любой программы( проводник, мой компьютер или Far )скопируйте какой-либо текстовый
файл ( например autoexec.bat из корневого каталога диска С:) в папку с проектом. Можно создать
файл в текстовом редакторе, не забудьте при этом, что сохранять его нужно в формате «только
текст».Перейдите в Delphi. Запустите проект. Щелкните по пункту «открыть» меню «текст». В окне
memo должен появиться текст файла.
Задание для самостоятельного выполнения(на оценку)
1) Напишите обработчики событий для пунктов «круг» и «квадрат» меню « фигуры». По выбору
этих пунктов должны соответственно рисоваться круг и квадрат. Компонент Memo при этом
должен стать невидимым, чтобы не мешать. Напоминаю, что круг ( или эллипс) рисуется вызовом
метода ellipse(x1,y1,x2,y2) , где x1,y1,x2,y2- координаты левого верхнего и правого нижнего угла
квадрата (или прямоугольника), в который будет вписан круг (эллипс).
2) Добавьте в меню «фигуры» пункт «очистка».
3) Вставьте первым пунктом меню пункт «О программе»
Компонент Popupmenu
Создадим для компонента Memo контекстное меню, которое позволит выравнивать текст в окне. Для
этого поместим в любое место формы компонент Popupmenu. Чтобы создаваемое локальное меню
относилось именно к компоненту memo1 необходимо на странице properties инспектора объектов
свойству popupmenu компонента memo1 присвоить значение popupmenu1 (можно выбрать из списка)
Двойным щелчком по компоненту Popupmenu вызывается дизайнер и создаются пункты уже известным Вам образом. Озаглавьте их: «по центру», «влево», «вправо». В обработчиках событий, возникающих при выборе соответствующих пунктов меню нужно написать команды выравнивания текста
по центру, влево и вправо . За выравнивание текста отвечает свойство Alignment компонента в котором текст находится. Этому свойству могут быть присвоены значения «tacenter», «taleftjustify» или
«tarightjustify» соответственно. Запустите программу. Откройте текст. Правой кнопкой щелкните на
тексте, выровняйте его по центру. Сохраните приложение для дальнейшей работы с ним.
Диалоговые панели общего назначения.
В Delphi имеются компоненты, реализующие стандартные диалоговые панели Windows, позволяющие например, выбрать открываемый файл или выбрать цвет из палитры, найти файл, либо сохранить его. Эти компоненты являются невидимыми и расположены на странице Dialogs палитры компонентов. Рассмотрим некоторые из них.
Компонент Colordialog.
Предназначен для выбора цвета из палитры цветов.
Откройте Ваше приложение, если оно не открыто. Поместите на форму компонент Colordialog. Создайте обработчик события, возникающего при выборе пункта “цвет” меню “параметры линии”.
Обработчик должен содержать команду:
if colordialog1.execute then canvas.pen.color:=ColorDialog1.Color;
По этой команде выбранный в палитре цвет присваивается цвету пера. Запустите программу. Выберите сначала цвет, толщину линии, затем нарисуйте круг.
Компонент Opendialog
Позволяет выбрать открываемый файл.
Задание для самостоятельного выполнения(на оценку)
1) Измените обработчик события при выборе пункта «открыть» меню «текст», чтобы предоставлялась возможность выбрать имя открываемого файла. Для этого поместите на форму компонент
Opendialog. Аналогично выбору цвета напишите команду: Если компонент вызван (If opendialog.execute…) то в массив строк компонента memo загружается из файла (loadfromfile)…вместо
конкретного имени файла, как это было у Вас ранее необходимо указать значение свойства filename компонента opendialog1.
2) Создайте обработчик для пункта «очистка», по которому окно вывода текста очищается.
Дополнительное задание
Откройте новое приложение.
1) Поставьте кнопку, по нажатию на которую должна предоставляться возможность выбора цвета, в
который затем будет окрашена форма.
Динамическое изменение меню
Иногда необходимо, чтобы меню менялось в ходе работы программы. Например пункт «Paste»
(«Вставить») недоступен, если в буфере обмена данными нет фрагмента, или пункты «Сat” (“Вырезать”), “Copy” (“Копировать”) недоступны, если нет выделенного фрагмента. Добавьте в пункт меню
«Текст» команды «Вырезать», «Копировать», «Вставить». Обратите внимание при этом на имена создаваемых пунктов меню (значение свойства Name ), т.к. они понадобятся, чтобы присвоить свойствам «Enabed» данных пунктов меню значение False. Это можно сделать в окне инспектора объектов или динамически, командой N10.enabled:=false при запуске программы (событие OnCreate формы). Таким образом при запуске программы в пункте меню “Текст” доступен лишь пункт “Открыть”
При щелчке по пункту меню «Текст» должно проверяться, имеется ли выделенный текст в компоненте Memo1. (If Memo1.SelLength>0 then…). Если имеется, то пункты меню «Вырезать» и «Копировать» становятся доступны (свойство Enabled соответствующих пунктов меню устанавливается в
True) иначе нужно сделать их недоступными. Доступность же пункта «Вставить» определяется наличием либо отсутствием информации в буфере обмена данными (Clipboard). Для работы с этой областью необходимо добавить в список используемых модулей (Uses фраза в самом начале Вашего модуля) имя Clipbrd Команда N12.enabled:=Clipboard.hasformat(CF_text) (здесь у меня N12- имя
пункта меню «Вставить») установит значение доступности пункта «Вставить» в зависимости от
наличия информации в буфере обмена данными. Добавьте ее в обработчик пункта «Текст». При желании очистить буфер обмена можно командой clipboard.clear.
Обработчики пунктов «Вырезать», «Копировать» и «Вставить» будут выглядеть соответственно:
memo1.CutToClipboard;
memo1.CopyToClipboard;
memo1.PasteFromClipboard;
Listbox- Список строк. Каждая строка- это значение свойства Items- строковый тип. Каждое из них
имеет номер. Номер Очередной строки- значение свойства – Itemindex- целого типа Нумерация с нуля. Например: Вывести в метку выбранную строку списка можно командой label1.caption:=Listbox1.items[Listbox1.itemindex]. Загрузить строки в список можно из файла командой
listbox1.Items.LoadFromFile('c:\autoexec.bat');
Combobox (Standard)— комбинированный список, включает в себя список и строку редактирования. Значение строки редактирования (свойство Text) может быть выбрано из раскрывающегося
списка, либо введено с клавиатуры. Начальные значения списка выбора можно установить в окне инспектора объектов, введя значения свойства Items.
Radiogroup- представляет контейнер, предназначенный для размещения зависимых переключателей
Radiobutton. Добавляя новую строку в свойство Items вы добавляете новый переключатель в контейнер. Свойство Itemindex- порядковый номер выбранного переключателя. Нумерация начинается с 0
Scrollbar (Standard)- полоса прокрутки Могут использоваться как средство наглядного ввода информации. Изменяя положение бегунка, Вы изменяете значение свойства Position.
Крайние значения этого свойства зависят от значений свойств MIN, MAX компонента. Расположение
на форме( Вертикальное или горизонтальное) задается свойством Kind Например поместив на форме
панель и три полосы прокрутки и написав следующие обработчики OnChange компонентов scrollbar,
Вы сможете изменять цвет панели, передвигая ползунки.:
panel1.color:=RGB(scrollbar1.position, scrollbar2.position,scrollbar3.position);
Здесь RGB- функция, значение которой зависит от трех цифровых значений в скобках-составляющих
цвета. Чтобы использовать всю палитру, установите значение свойстваMAX компонента в значение
256.
Trackbar(Win-32) – очень похож на Scrollbar
ProgressBar(Win32)- используется для отображения прогресса выполнения операции, например сохранения файла. Обычно компонент располагается в статусной строке и не виден, появляется в момент выполнения операции, с которой связан. Например перемещение ползунка в TrackBar можно
связать с ProgressBar следующим образом:
progressbar1.position:=trackbar3.position;
Пример использования (папка RGB)
Animate (Win32) -для проигрывания Avi- файла. Существует стандартная анимация, которая задается свойством CommonAvi, при этом внешнего файла не требуется. Если же нужно проиграть aviфайл, то его имя нужно указать как значение свойства Filename. Свойство Repetitions задает число
повторов. Пример использования : Поместить на форму список выбора, заполнив его строками: копирование, удаление, поиск. Написать процедуру обработки события ListBox1Click, в которой свойству CommonAvi компонента Animate присваиваются соответственно значения avicopyfile, avideletefile, avifindcomputer в зависимости от номера выбранной строки (значение свойства
listbox1.itemindex, нумерация с 0). Чтобы файл проигрывался, необходимо, чтобы значение свойства
Active было равно True
Урок 12
Тема урока: Структуры данных Object Pascal. Одномерные массивы.
План урока:
Задача: Подсчитать среднегодовую температуру.
Если мы хотим решить эту задачу на компьютере, мы должны хранить где-то исходные данные- значения ежедневных температур. Данные хранятся в переменных. В данной задаче понадобится 365
однотипных переменных. Если мы будем называть переменные разными именами, велика вероятность, что мы в конце концов запутаемся в них. Да и складывать значения переменных придется последовательно: a+b+c+d+... т.е. такая элементарная задача становится сложной в компьютерном решении.
Имееются структурированные типы данных- т.е. данных, состоящих из какого-то количества компонент.
Массив- это структура, состоящая из фиксированного количества компонент одинакового типа
Переменная типа массив описывается в описательной части программы следующим образом:
var < имя переменной > : array [ 1.. n ] of < имя типа>
В квадратных скобках указывается количество компонент массива ( константа должна быть описана
выше, до описания массива) .В качестве типа может быть использован любой из известных типов.
Например в вышеприведенном примере можно было описать переменную, предназначенную для
хранения 365 -и чисел ( значений ежедневных температур ) следующим образом: var t : array [ 1..365 ]
of integer
При таком описании мы описали переменную целую (t) и ее компоненты-переменные составляющиеt[1], t[2],t[3],..t[365] к каждой из которой можно обратиться по имени и индексу.
Индекс указывает на местоположение данного элемента в массиве- это его порядковый номер.
Тип integer указан т.к. обычно указываются целые значения температур. Тогда операция накопления
суммы температур за год может быть организована в цикле
s:=0;
for i:=1 to 365 do
s:=s+t[i];
Для нахождения среднегодовой температуры,очевидно, необходимо разделить полученную сумму
температур на количество дней в году:
s:=s/365;
Вопрос: какого типа должна быть описана переменная s
uses crt;
var s: real;
i:integer;
t: array[ 1..365] of integer;
BEGIN
for i:= 1 to 365 do readln (t[i]); заполняем массив значениями температур
s:=0;
for i:=1 to 365 do s:=s+t[i];
складываем все элементы массива
s:=s/365;
writeln (‘средняя температура=’,s:2:1)
END.
Если попытаться ввести и запустить на исполнение данную программу, то машина будет останавливаться 365 раз и ждать ввода очередного значения температуры. Понятно, что такой способ заполнения массива числовыми значениями достаточно долог и в учебных задачах, где не важны конкретные
значения чисел массива а важен лишь способ обработки- алгоритм решения задачи мы будем заполнять массив присваиванием случайных значений его элементам. Данный алгоритм на Паскале можно
описать так:
const n= 20;
var a: array [1..n] of integer;
i: integer;
BEGIN
randomize; - используется в программе до функции random
for i:=1 to n do begin
a[i]:= random(15); присваиваем случайное число
write(a[i]:3); т.к. неизвестно конкретно что присвоено,
end;
выводим на экран в строчку
Типичные алгоритмы обработки массивов:
а) Нахождение суммы ( количества) элементов массива, удовлетворяющих условию:
Найти произведение элементов массива, имеющих четные индексы.
Найти количество элементов, находящихся в интервале а,в.
Найти сумму( количество) положительных элементов массива.
Найти сумму элементов массива, меньших, чем соседние.
б) Нахождение максимального( минимального) элемента массива.
в) Определить индекс первого элемента массива ,значением которого является 0
г) Найти среднее арифметическое отрицательных значений массива
в) Заполнение массива числами в интервале от -10 до 10
г) Заполнение массива числами, имитирующими школьные оценки.
д) Условие четности элемента массива, принадлежности инепринадлежности интервалу
Задачи для самостоятельного решения:
1. Дан массив натуральных чисел. Найти сумму элементов, кратных данному К
2. Выяснить, какое число – отрицательное или положительное, встречается в массиве раньше
3. Выяснить, будут ли числа массива возрастающей последовательностью. Заполните массив с клавиатуры.
4. Вывести на экран те элементы массива, для которых выполняется условие аi<=i
5. В заданном одномерном массиве поменять местами соседние элементы, стоящие на четных местах с элементами, стоящими на нечетных местах
6. Вывести на экран все числа массива до первого нуля.
7. Вы хотите обменять доллары на рубли. Есть информация о стоимости купли-продажи в банках
города. В городе N банков Составьте программу, определяющую, какой банк выбрать, чтобы выгодно обменять доллары на рубли.
8. Составьте программу, определяющую средний балл какого класса, «10а» или «10б», по русскому
языку выше. Считаем, что в классах одинаковое количество учащихся. Алгоритм решения
 Опишем процедуру заполнения массива случайными числами, имитирующими отметки. Массив
оценок- выходной параметр. Входных параметров нет.
 Опишем процедуру, в которой будет подсчитываться среднее арифметическое элементов массива. В данной процедуре массив оценок- входной параметр, а средний балл- выходной.
 Дважды вызовем процедуру заполнения, заменяя формальный параметр фактическимпеременной типа массив.
 Дважды вызывается процедура поиска среднего, входной параметр- массив оценок «10а» в первом вызове и «10б» во втором
 Сравним средне баллы классов Результат сравнения выводится в виде фразы ,например « 10а
учится лучше»
9. Определить, можно ли , меняя местами элементы массива А получить массив Б. Массивы очень
длинные.( сортировка предварительно)
Алгоритмы сортировки
1. Метод выбора
Заключается в том, что ищется минимальный элемент и меняется местами с первым. Затем те же
действия проводятся с оставшимися. На Паскале алгоритм выглядит так:
For i:=1 to n-1 do
For j:= i+1 to n do
If a[j]<a[i] then begin
m:=a[i]; a[i]:=a[j]; a[j]:=m;
end;
2. Метод пузырька (обмена)
Идея в многократном попарном обмене рядом стоящих элементов и перестановке их в заданном порядке. Если провести аналогию вес пузырька в резервуаре с водой- значение элемента, то каждый
проход собменом по таблице- всплывание пузырька: (обмен начинается с конца)
for i:=1 to n do
for j:=n-1+1 downto 1 do
if a[j]<a[j-1] then begin m:=a[j]; a[j]:=a[j-1];a[j-1]:=m;end;
Урок 13
Тема урока : Структуры данных. Многомерные массивы
Урок 14
Тема урока: Структуры данных Object Pascal. Файлы.
Файл- это именованная часть внешней памяти. Object Pascal позволяет работать с файлами, как с переменными. Переменная файлового типа- это структура данных одного типа, длина которой практически
не ограничена, т е число компонентов не фиксировано в отличие от массива.Емкость файловой переменной практически ограничивается лишь емкостью устройства внешней памяти. Object Pascal поддерживает следующие типы файловых переменных:
Типизированные файлы
объявляется: var < имя >: file of < имя типа>
Например: var f: file of char;
Текстовые файлы
объявляются var <имя> :Textfile;
Например: var f:textfile;
Нетипизированные файлы
var <имя> : file
Файлы становятся доступны программе после команды открытия файла.. Прежде необходимо связать
ранее объявленную файловую переменную с именем существующего или вновь создаваемого файла
при помощи команды( стандартной процедуры):
1. Assignfile (<файловая переменная>,<полное имя файла на диске>)
После этой команды все операции с переменной на самом деле будут производиться с физическим файлом на диске.
2. После этого существующий файл открывается командой:
а) Reset(<имя файловой переменной>)
Указатель при этом ставится в начало файла
Если файл вновь создается, открытие его производится командой:
б) Rewrite(<имя файловой переменной>)
Чтобы проверить, существует ли файл на диске, можно воспользоваться стандартной функцией
:Fileexists(<имя файла на диске>). Значением функции будет true, если файл на диске найден
Для текстовых файлов используется команда для установки указателя в конец файла (для расширения файла):
в) Append(<имя файловой переменной>
3. Для файловых переменных определены операции чтения из файла и запись в файл.
Чтение производится командами:
Readln(<имя файловой переменной>,<имя переменной соответствующего типа>)
Для чтения чисел из текстового файла удобно воспользоваться командой
Read(<имя файловой переменной>, <имя переменной числового типа>)
тогда при каждом очередном обращении к данной команде считывается очередное число из
файла.
Например простое заполнение массива числами из текстового файла можно организовать так:
Const n=1000;
Var a:array[1..n] of real;
I:integer;
F:textfile;
Begin
Assignfile(f,’text’); Reset(f);
I:=1;
While( not eof(f)) and(i<n) do begin
Read(f,a[i]); i:=i+1;
End;
Closefile(f)
End.
Функция eof(<имя файла>)- имеет значение true, когда достигнут конец файла.
Стандартная процедура Closefile должна заканчивать работу с файловой переменной.
4. Запись в файл производится командами:
Write(<имя файловой переменной>,<имя переменной того же типа, что и компоненты файла>)
writeln(<имя файловой переменной>,<имя переменной соответствующего типа>);
Во втором случае кроме значения переменной в файл записывается признак конца строки.
Для работы с типизированными файлами могут оказаться полезными следующие стандартные
процедуры и функции:
5. Seek(<имя файловой переменной>,n)- в указанном файле указатель смещается к компоненту с
номером n.
Filesize(<имя файловой переменной>)значением функции является количество компонентов в
файле.
Например для смещения указателя в конец типизированного файла можно воспользоваться командой: seek(<имя файловой переменной>,filesize<имя файловой переменной>)
В качестве практической работы, закрепляющей, поясняющей работу с файлами, предлагается проект по созданию на диске базы данных, хранящей сведения о температуре воздуха за определенную
дату и дополнению ее новыми записями. База данных хранится в текстовом файле.
После открытия проекта сохраняем его, создав предварительно папку со своей фамилией
Предлагается следующий алгоритм проекта:
При запуске программы (какое событие?)
связываем ф.п. с файлом на диске
если файл не сущ-ет, то создать(rewrite)
По кнопке «добавить»
По кнопке “вывести записи”
Указатель в конец(append)
добавить из edit в файл
очистка edit
курсор поставить в edit
Указ. в начало файла (reset)
пока не конец файла, читать очередную запись
из файла в переменную и добавлять ее значение
в memo
При выходе из программы ( какой обработчик?)
Закрыть файл.
25
Урок 14
Тема урока: Тип данных-запись.
Предположим, нам необходимо хранить и обрабатывать определенным образом следующую информацию:
Фамилия, год рождения, улицу, номер дома и номер квартиры. Все эти данные связаны тем,
что относятся к одному человеку. Подобные данные хранятся , например в базе данных адресного стола города. Очевидно, что подобным образом хранят большие объемы данных для автоматизированного поиска их по запросу, например по фамилии человека выдается адрес
проживания Т.к. данные разнотипны, массив не подходит для их хранения. Для объединения
разнотипных данных существует тип данных, называемый «запись».
Запись- это структура данных, состоящая из фиксированного количества компонент возможно
различного типа. ( сходство и различие с массивом и файлом).Компоненты записи называются полями. Данный тип описывается следующим образом:
type <имя>= record
<поле1>:<тип>;
<поле 2>:<тип>;
<поле 3>:<тип>;
…
end;
например для вышеупомянутых данных такой тип можно описать следующим образом:
type person= record
name:string[20];
street: string[20];
house: integer;
flat:integer;
end;
Объявив переменную
var p:person;
мы можем обратиться к отдельным ее компонентам- полям по имени переменной и имени поля,
разделенным точкой:
p.name, p.street, p.house и т.д.
С переменной типа запись недопустимы команды writeln и readln. Вводить с клавиатуры и выводить на экран можно лишь поля такой переменной (подобно тому, как невозможно применить
данные команды к массиву целиком)
Когда мы разрабатывали программу базы данных, которую мы хранили в текстовом файле, нам
трудно было организовать поиск данных в такой базе по какому-то параметру, например по фамилии учащегося или по успеваемости, т.к можно было обратиться только ко всей строке базы и
трудно было вычленить ее отдельную часть. Для решения подобной задачи удобно иметь базу
данных состоящую из записей и хранить ее не в текстовом , а в типизированном файле . Описание
переменной несколько отличается от описания текстового файла и выглядит: var <имя переменной>: file of <имя типа>
Компонентами данного файла могут быть компоненты типа, указаного в объявлении файла.
Наиболее часто используются файлы записей. Для типизированных файлов остается тот же порядок работы, что и для текстовых но команды чтения-записи используются без перевода строки т.е.
write( <ф.п>,<запись>);
read(<ф.п>,<запись>);
Поставить указатель в конец файла можно используя функцию filesize(f), значением которой является количество записей в файле ( перед ее использованием указатель должен быть вначале) и
процедуру seek(n), ставящую указатель к записи с указанным номером.: reset(f);seek(f,filesize(f));
1. Создадим проект, позволяющий хранить данные в виде записей на диске и делать выборку нужных сведений по запросу.
Создайте меню из двух горизонтальных пунктов: «файл» и «поиск». Причем в пункте меню
«Файл» выпадают команды «Создать» и «Открыть».Поставьте на форму компоненты Opendialog и
Savedialog. Они аналогичны, только второй позволяет выбрать имя файла для записи. Это имя Вы
26
укажете при создании файла( при выборе пункта «создать»). Не забудьте объявить файл записей ,
связывать его с именем файла на диске и открывать для ввода в обработчике события выбора
пункта меню «создать» ( If savedialog1.execute then и т.д.)
Пусть на диске будут храниться следующие данные: фамилия, имя, улица, где поживает, № дома и
№ квартиры. Выше было описано, как описать такой тип данных и объявить переменную. На
форме должны быть окна ввода для всех этих данных с соответствующими пояснениями над ними
и кнопка, по нажатию на которую в переменную-запись будут отосланы все введенные значения –
из каждого окна в соответствующее поле:
p.name=edit1.text; p.street:=edit2.text; p.house:=edit3.text; и т.д. после чего значение переменнойзаписи переписывается в файловую переменную : write(f,a); После этого окна ввода очищаются
для удобства ввода следующей записи.
Введите данные не менее чем о 10 объектах, причем пусть встречаются повторяющиеся названия
улиц.
В обработчике выбора пункта «Поиск» осуществляется переход на другую форму, где с клавиатуры можно ввести фамилию человека и по нажатию кнопки увидеть все сведения, хранящиеся в
базе данных о человеке с такой фамилией.
Для этого осуществляется чтение записей из базы и сравнение поля фамилии с введенным значением для поиска. Как только сравнение произойдет, будут выведены все поля соответствующей
записи.:
repeat
read(f,p)
until( eof(f)=true)or (p.name=edit1.text)
if p.name=edit1.text then label1.caption:=p.name+P.street+inttostr(p.house)+…
else label1.caption:='нет такого';
В программе должна быть кнопка выхода( или пункт меню), по которому файл закрывается,
прежде, чем будет закрыта форма. Если Ваша программа запускается повторно, когда уже создана
какая-то база, должен работать пункт меню «файл»-> «открыть», в котором предоставляется возможность открыть (reset) файл, имя которого Вы выбираете (opendialog) После чего уже можно
будет делать поиск.
Замечания по программе: При запуске приложения кнопка «Поиск» недоступна (свойство
enabled). т.к. в несуществующей базе нельзя производить поиск. Доступной она также должна
становиться и после выбора пункта меню «Открыть» либо по нажатию кнопки «добавить». По
кнопке « добавить» Можно добавлять записи в уже существующую базу. Для этого курсор должен
стоять в конце базы. Задание:
Создайте проект, позволяющий хранить на диске данные о результатах соревнований и осуществлять поиск данных по указанной стране. (Папка «Записи»)
Создайте программу- «Адресная книга»:
По нажатию на кнопки «Предыдущая»,
«Следующая» осуществляется перелистывание записей. По кнопке «Новая»
очищаются поля ввода для новых данных
и устанавливается указатель в конец файла. Отдельно опишите и используйте
процедуру переноса данных с экрана в
файл
Фамилия
Телефон
Адрес
Предыдущая
Следующая
Новая
Сохранить
27
Урок 15
Тема урока: Пакеты вычислений.
Как мы уже знаем, переменные, объявленные внутри процедуры, недоступны другим процедурам,
т.к. в буквальном смысле эти переменные существуют только во время работы данной процедуры.
Т.е данные не могут существовать отдельно от кода процедуры, а процедура не будет работать без
этих данных. Процедура таким образом представляет собой пакет вычислений, где код и данные
неразрывно связаны. Но процедуры, описанные в одной программе Вам не удастся использовать в
другой, их нужно будет заново описывать.Object Pascal идет дальше по пути объединения кода и
данных. Он предоставляет возможность создания «пакета пакетов» , включающего в себя процедуры
и переменные. Таким средством являются модули. Это как бы следующий этап упаковки. Описав
единожды в модуле процедуры и функции, Вы затем можете вызывать их по имени снова и снова в
любой программе. Изобретя «колесо», Вы можете использовать его вновь и вновь. Для этого нужно
всего лишь сослаться на имя модуля в Uses фразе ( она присутствует верхней строчкой во всех Ваших программах, ее формирует Delphi, а Вам нужно добавить имя Вашего модуля через запятую)
Модуль сохраняется как файл на диске и элементы, объявленные в нем общедоступными, могут
использоваться другими модулями Вашей программы и основной программой. Модуль – это автономно компилируемая программная единица. Последующая сборка таких частей программы производится перед выполнением программы.
1. Модуль имеет следующую структуру:
Unit <имя модуля>;
Interfaсe
<интерфейсная часть>
Type Tform1=class (Tform)
Private
{private declaration}
Public
{pablic declaration}
implementation
<исполняемая часть>
end.
Имя модуля должно совпадать с именем файла на диске. Имя модуля служит для его связи
с другими модулями и основной программой. Эта связь устанавливается при помощи фразы:uses<имя модуля>. Если в модуле используются другие модули , они подключаются сразу за
словом Interface, либо за Implementation , либо и там и там.
В интерфейсной части модуля находятся описания всех имен, которые должны быть доступны другим модулям. Процедуры при этом содержат только заголовки.
Раздел type- раздел описания типов. За ним следуют спецификаторы видимости:
В разделе private имена доступны внутри модуля, но невидимы из других; в разделе pablic
имена видимы и за пределами модуля.
В исполняемой части содержится описания тех подпрограмм, которые объявлены в интерфейсной части. В заголовках подпрограмм могут быть опущены списки формальных параметров,
т.к. они уже есть в интерфейсной части . В исполняемой части могут объявляться локальные для
модуля объекты.
Модуль может содержать другие разделы, но обычно они модуля отсутствуют.
Пример написания модуля:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
28
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
end;
end.
Текст модудя Delphi автоматически формирует, вставляя в него описания любого
добавленного к форме компонента, а также создавая заготовки для обработчиков событий- заголовки процедур. Вы же наполняете процедуры-обработчики событий конкретным содержанием, можете добавлять свои методы в ранее объявленные классы, вставлять собственные переменные, типы, константы.
Урок 16
Тема урока: Классы. Объекты.
Классами в Object Pascal называются специальные типы (записи), включающие помимо описания
данных описание процедур и функций, работающих с этими данными. Подобно тому, как тип является образцом, по которому создается переменная, так класс служит образцом, по которому создаются конкретные экземпляры реализации- объекты, объединяющие в себе данные и средства
для работы с этими данными (процедуры и функции). (Перейдите в окно модуля ) В интерфейсной
части модуля описан тип( класс) с именем tform1 и экземпляр этого класса- объект (переменная) с
именем form1. (переменная типа запись, объединяющая данные и процедуры работы с этими данными) Доступ к методам и полям класса, (аналогично полям записи) осуществляется с помощью
составных имен: Form1.show, Form1.color Класс является образцом, по которому создаются объекты, и наоборот, объект- экземпляр реализации класса Объекты, как представители класса,
объявляются в разделе var. Класс представляет собой единство трех сущностей – полей (данных), методов ( процедур и функций для работы с этими данными) и свойств. Объединение этих
сущностей в единое целое называется инкапсуляцией.. Свойства- это специальный механизм клаасов, регулирующий доступ к полям. Внешне использование свойств ничем не оличается от использования полей объекта, отличие в том, что при присвоении и чтении значений свойств автоматически вызывается процедура, выполняющая некоторую работу. Тип *( класс) Tform1 порожден от стандартного класса Tform (tform1= class(tform)), который реализует все нужное для функционирования пустого Windows- окна: его можно переместить за строку заголовка, свернуть, развернуть на весь экран, закрыть. Т.е. класс Tform инкапсулирует все методы и свойства, необходимые для работы стандартного Windows-окна( подобно тому, как класс Tмemo представляет собой
полнофункциональный текстовый редактор, и т.д.).Инкапсуляция представляет собой мощное
средство обмена готовыми к работе программными заготовками. Библиотека классов Delphi-это
, фактически, набор «кирпичиков» для построения программ. (Классы дают возможность создания
и использования затем в качестве готовых программных заготовок библиотеки классов)
Класс Tform является родительским классом для tform1, который унаследовал от родительского все возможности Свойство наследования классами- потомками свойств родительского
класса является одним из фундаментальных принципов объектно- ориентированного программирования. Когда вы создаете новую форму и накладываете на нее компоненты, вы создаете новый
класс. При этом начинаете с абстрактного класса Tform и надстроили его. Добавляем новый компонент – Delphi добавляет поле, Добавляем обработчик события—Delphi добавляет в описание
класса метод. Созданный класс Tform1 добавил к возможностям родительского класса Tform собственные в виде дополнительных компонентов, которые Вы добавили на форму. От наследника
может быть порожден новый наследник и т.д. На каждом уровне иерархии свой уровень функциональных возможностей. В результате создается ветвящаяся иерархия классов, в основе которой
располагается класс Tobject.
29
Еще одним фундаментальным понятием объектно-ориентированного программирования
является полиморфизм. ( много форм). Полиморфизм- способность классов-потомков замещать
методы родительских классов одноименными своими методами, т.е. конкретно реализовывать
общую идею.Например класс Tcontrol имеет метод Repaint для регенерации изображения экрана.
Все элементы управления классов-потомков, происходящих от Tcontrol, замещают метод своими
специальными методами Repaint, Т.е. есть идея и ее конкретная реализация. Идея предлагает что
делать, но не знает как точно. Полиморфизм подразумевает отделение идеи от ее воплощения
внутри иерархии классов объектов. Когда посылают команду группе элементов «перерисуй себя»,
это делают на общем уровне для всех компонентов.
Перечень интерфейсных кнопок различных таких (простая кнопка, радиокнопка кнопкапереключатель и т. д.) в ставляет собой хороший пример полиморфизма. Каждый тип в этом перечне представляет различный тип интерфейсной кнопки. Можно описать метод для каждои кнопки, который изображает этот объект на экране, В терминах объектно-ориентированного программирования можно сказать все эти типы кнопок имеют способность изображения самих на экране,
Однако способ (процедура), которым каждая кнопка может изображать себя на экране, является
различным для каждой кнопки. Простая кнопка рисуется на экране с помощью процедуры, «вывод
изображения простой кнопки», радиокиапка рисуется экране с помощью процедуры «вывод изображения радиокнопки»т. д. Таким образом, существует единственное для всего перечня интерфейсных кнопок действие (вывод изображения кнопки на экран), которое реализуется специфичным для каждой кнопки способом.
Объявим простой класс:
type
Tperson = class
fname:string[20];
fadress:string[35];
procedure info;
end
поля класса: fname и fadress , info – имя метода Согласно принятому соглашению имена полей
начинаются с буквы F (от слова field)
выделение памяти осуществляется при помощи специального метода- конструктора, которому
обычно присваивают имя create, а вместо слова Procedure используют слово constructor :
type
Ttperson = class
fname:string[20];
fadress:string[35];
constructor create;
procedure info;
end
Объекты как представители класса объявляютяс в разделе var, например:
var
st:tperson;
Выделение памяти происходит присваиванием значениия метода конструктора объекту:
st:=Tperson.create;
Описание метода может например выглядеть так:
procedure tperson.info;
begin
form1.label4.caption:=’имя ‘+fname+#13+’адрес ‘+fadress;
end;
В описании метода доступ к полям осуществляется без указания имени объекта.
Определим новые классы, как наследники существующего класса Тperson:
tstud=class(tperson) // производный класс
numgr:integer;//№ группы
30
procedure info; override;
end;
tprof=class(tperson) // еще производный класс
kaf:string[15];
procedure info;override;
end;
Классы наследники будут обладать всеми полями родительского класса, добавив к ним каждый
свое поле. Метод info в классах-наследниках будет замещен своим одноименным методом, те способ вывода информации для каждого класса будет свой( полиморфизм) Для этого в объявлении
метода родительского класса необходимо добавить слово virtual , а в классах-наследниках слово
override
Объявим объекты-переменные классов наследников:
var
st:tstud;
pr:tprof;
Опишем реализацию методов базового класса и классов- потомков в секции реализации: (implementation)
constructor tperson.create;
begin
fname:='';
fadress:=''; // конструктор, как правило рписваивает полям начальные значения
end;
procedure tperson.info;
begin
form1.label4.caption:='имя '+fname+#13+'адрес '+fadress;
end;
procedure tstud.info;
begin
form1.label4.font.Color:=clred;
form1.label4.font.Size:=18;
form1.label4.caption:='имя '+fname+#13+'адрес '+fadress+'№ группы'+inttostr(numgr);
end;
procedure tprof.info;
begin
form1.label4.font.Color:=clblue;
form1.label4.font.Size:=14;
form1.label4.caption:=’имя ‘+fname+#13+’адрес ‘+fadress+’кафедра ‘+kaf;
end;
Добавим на форму переключатель студент- преподаватель, окна ввода и метку для вывода объектов pr или st. По кнопке “ввод” в зависимости от состояния переключателя выделяется память под
соответствующую переменную путем вызова конструктора create и заполнение соответствующих полей содержимым окон ввода.:
if radiobutton1.checked=true then begin
st:=tstud.create; //выделение памяти
st.fname:=edit1.text;
st.fadress:=edit3.text;
st.numgr:=strtoint(edit2.text);
end else
if radiobutton2.checked=true then begin
pr:=tprof.create;
pr.fname:=edit1.text;
pr.fadress:=edit3.text;
pr.kaf:=edit2.text;
31
end;
Вывод осуществляется по нажатию на кнопку “вывод” . В зависимости от состтояния переключателя вызывается метод Info соответствующего объекта.:
if radiobutton1.checked=true then st.info else if radiobutton2.checked=true then pr.info;
Вопросы по теме:
1. Что такое классы в Delphi?
2. Отличие класса от типа данных record
3. Что такое объект?
4. Какие преимущества дает использование классов в программировании?
5. Как создать объект в модуле? Приведите пример.
6. Назовите основные принципы ООП
7. Охарактеризуйте сущность каждого из принципов ООП
8. Опишите механизм замещения родительских методов в классах-потомках.
Задание: Создайте базовый класс, имеющий два поля- координаты курсора мыши в момент нажатия и виртуальный метод прорисовки, и два класса-наследника, добавляющие к полям родительского класса собственное- размеры фигуры и перекрывающие метод родительского класса своими
(при вызовеодного, например, рисуется окружность, при вызове другого- прямоугольник).
При щелчке левой кнопкой мыши по форме ( OnMouseDown, при этом свойство Shift имеет значение mbLeft):
 создается объект одного класса- наследника
 поля- координаты получают свои значения из стандартных переменных x,y
 поле- размер получает значение из окна ввода с клавиатуры
 вызывается метод прорисовки соответствующего класса- наследника
При щелчке правой кнопкой мыши по форме ( OnMouseDown, при этом свойство Shift имеет значение mbRight) происходит то- же для другого класса- наследника
Урок 17
Тема урока: Тип данных- множество
Множество- это структура, состоящая из однотипных элементов, логически связанных
между собой, причем характер связи подразумевается, но никак не контролируется. Например
множество, в котором предполагаются все цифры:
Var a: set of 0..9; тогда переменной а может быть присвоено наппример значение
A:= [4,5] или a:=[0..3,6]
Множество, включающее буквы латинского алфавита?
Var b:set of ‘a’..’z’;
Именно непостоянством количества своих элементов множества отличаются от массивов
и записей. Два множества считаются эквивалентными, когда все их элементы одинаковы, причем
порядок их следования неважен. Количество элементов, входящих в множество не может быть более 256. Над множествами определены следующие операции:





Пересечение-* результат – множество, которое содержит элементы, общие для операндов, например: a1:=[2..7]; a2:=[4..9], тогда a3:=a1*a2, значениеv переменной a3
,будет множество [4..7]
Объединение множеств +. Результат содержит элементы первого множества, дополненные недостающими элементами второго, например a1:=[0..6] a2:=[3..9] a3:=a1+a2;
значение переменной a3=[0..9]
Разность – Результат содержит элементы из первого, которые не принадлежат второму.
Эквивалентность= Возвращает значение «Истина», если множества эквивалентны.
Принадлежность IN.<Выражение> IN<множество>Возвращает значение «Истина»,
если результат выражения принадлежит множеству.
32
Урок № 18
Динамические структуры данных
Обычно во время работы программы могут изменяться только значения переменных, в то время,
как их количество остается неизменным. Например в Вашей тестирующей программе для хранения тестовых вопросов использовался массив, количество элементов которого обычно задавалось
с избытком, что вело к неэффективному использованию памяти, а в случае увеличения количества
вопросов он мог оказаться переполненным и возникала ошибка в работе программы. Для решения
этой проблемы существуют переменные специального типа, которые называются переменными –
указателями. Такая переменная хранит не данные, а адрес другой переменной. ( Вы не можете
принести друзьям домой магазин, чтобы они посмотрели, что там продается, но Вы можете дать
им его адрес)Как и любая другая переменная указатель должен быть объявлен:
Var <имя>: ^ <тип>,
Например: var p1:^ integer; p2:^ real;
.
Выделение памяти для такой переменной осуществляется динамически, во время работы программы при помощи процедуры New, например new (p1)- выделяется память для переменной типа
integer; иными словами создается переменная целого типа(т.к. р1-имя переменной указывающей
на целый тип)
New (p2)- выделяется память для переменной типа real
У динамической переменной нет имени, поэтому обратиться к ней можно только при помощи указателя. Присвоить значение динамическойпеременной можно: p2^:=5.4
Указателю можно присвоить значение другого указателя, если они указывают на переменные одного типа, например если var a,b:^integer, то после команды a:=b a и b указывают на одну и ту же
переменную.
Для освобождения памяти служит процедура Dispose (p2)
Пример использования динамических переменных:
Var a,b,c:^ integer;
Begin
New(a); new(b); new(c);
A^:= strtoint(edit1.text);b^:=strtoint(edit2.text);
C^:=a^+b^;
Label1.caption:=’сумма=’+c^;
Dispose(a); dispose(b); dispose(c);
End;
Указатели позволяют создавать связанные списки. Каждый элемент списка представляет запись,
состоящую из информационных полей и поля- указателя на следующий элемент списка, например:
Type TPPerson=^ TPerson;
TPerson= recorg
Name:string[20];
Rost:inteegr;
Ves:real;
Next: TPPerson;
End;
Var p:TPPerson;// указатель на первый элемент списка
Тогда добавить элементы в начало списка можно следующим фрагментом:
Var person: TPPerson; //новый добавляемый элемент списка
Begin
New( person);
Person^.name:=edit1.text; Person^.rost:=edit2.text; Person^.ves:=edit3.text;
Person^.next:=p;
P:=person;
End;
Просмотреть список можно:
Begin
Person:=p;
While person<> nil do
Выводим поля
33
Урок № 19.
Еще о графических возможностях .
Битовая матрица
Использование методов свойства Canvas позволяет строить изображение из графических примитивов (окружностей, прямоугольников, линий). При работе с графикой удобно использовать переменные типа Tbitmap (битовый образ), который представляет собой находящуюся в памяти компьютера, невидимую графическую поверхность, на которой может быть сформировано изображение. Это изображение быстро может быть переведено на поверхность формы или компонента Image Порядок работы:
1. Объявить переменную: var bmp:Tbitmap
2. Создать битовую матрицу: bmp:=TbitMap.create;
3. В битовую матрицу картинка может быть загружена: bmp.loadfromfile (‘<имя bmp файла>’)
4. Чтобы фон картинки был прозрачен: bmp.transparent:=true
5. Перевести изображение на форму: form1.canvas.draw (x,y, <имя битовой матрицы>), где x,yкоординаты левого верхнего угла изображения. (пример «два самолета» папка «kultin»)
Задание: (файл Samolet)
Создайте два битовых образа, в один загрузите картинку из файла облака.bmp, в другой из файла
aplane.bmp. Сделайте прозрачным фон второй картинки. Выведите на форму битовые образы таким образом, чтобы координаты второй картинки были внутри первой. (Данные команды выполняются при активизации формы- событие OnActivate) Теперь попробуйте организовать движение
самолета по небу. Для этого поставьте на форму Timer., в обработчике события OnTimer которого
необходимо попеременно выводить изображение неба и самолета,изменяя координату х (ведь
движение горизонтальное) при выводе самолета. Т.К. небо непрозрачное (значение свойства
Transparent изначально равно false), то картинка как бы стирает изображение самолетика на прежнем месте. А так как картинки меняются часто, то нам кажется, что самолетик движется.
Создание программы простого графического редактора
1. Поставьте на форму панель. Расположите ее слева (св-воAlign). Панель будет служить контейнером для расположения кнопок- инструментов графического редактора. Для придания панели
большей выразительности воспользуйтесь свойствами Bevelinner, beveiouther,Bevelwidth, borderstyle, borderwidth.
2. На панели разместите 6 компонентов Speedbutton (стр Additional) Это кнопки с рисунком, но
без надписи. Для того, чтобы выбранный на палитре компонент поставить в нескольких экземплярах, не выбирая его повторно в палитре, необходимо при выборе компонента в палитре
держать нажатой клавишу shift. Для придания всем кнопкам одного размера также выделите их
при нажатой shift, затем установите на странице properties значения свойств width и Height
равными 40. Рисунок на каждой кнопке будет обозначать соответствующий инструмент : карандаш, ластик, кисть, графические примитивы- прямоугольник, линия, эллипс. Рисунок на
кнопке определяется значением свойства Glyph. Его можно установить в окне инспектора объектов, либо динамически в обработчике события Onactivate формы при помощи метода Loadfromfile, например: speedbtn1.Glyph.loadfromfile(‘pen.bmp’), где pen.bmp имя файла-картинки
изображения на кнопке. Файлы картинок должны быть в той же папке, где и файл проекта. (
скопируйте в свою папку с проектом файлы ‘pen.bmp’,brush.bmp’, ‘erase.bmp’, ‘rect.bmp’,
‘line.bmp’, ‘ellipse.bmp’ из папки «Мои документы» корневого каталога диска С)
3. Удобно, чтобы при подведении курсора к кнопке всплывали “подсказки”. Для этого поместите
текст подсказки в значение свойства Hint кнопки, например для карандаша слово «Карандаш.
Рисует при нажатой левой кнопке». Значение свойства Showhint нужно при этом установить в
true.
4. Для выбора цвета линии, рисуемой карандашом, поставьте на панель внизу компонент Colorgrid (cтраница Samples) Цвет выбирается щелчком левой кнопки. Выбранный цвет при этом
помечается буквами FG . Цвет карандаша меняется на значение свойства Foregroundcolor компоненита Colorgrid при нажатии левой кнопки мыши в обработчике OnMouseDown формы.
Аналогично меняется цвет кисти для закраски.
5. У Вас имеется 6 различных инструментов. Чтобы в программе различить, какой именно выбран, воспользуемся свойством down компонентов speedbutton. Каждая из кнопок может быть
34
зафиксирована в утопленном состоянии. Для этого нужно выделить все кнопки (черезShift),
установить значение свойства Groupindex = 6, значение свойства AllowAllUp установить в true.
Тогда при нажатии на кнопку она будет фиксироваться и отжиматься только при нажатии другой. Значение свойства down утопленной кнопки=true.
6. Предполагается, что карандаш будет рисовать при нажатой левой кнопке мыши. При нажатии
кнопки на форме происходит событие OnMouseDown формы. В обработчике данного события
необходимо запомнить в переменных координаты в момент нажатия, (Это значения стандартных переменных x,y. Эти переменные постоянно имеют значения, соответствующие координатам курсора мыши на форме и меняют свои значения при перемещении мыши. Объявлять их
не нужно).Переместите перо (moveto) в точку нажатия.
7. Т.К. линия рисуется во время перемещения мыши, необходимо описать обработчик OnMouseMove для формы, в котором линия строится из отрезков командой lineto(x,y), причем значения
переменных опять автоматически определены при перемещении по форме. Чтобы линия рисовалась не всегда, а только при нажатой левой клавише, можно устанавливать какую-то переменную в 1 в обработчике OnMouseDown и сбрасывать ее в 0 в OnMouseUp. Тогда команда
прорисовки линии при перемещении мыши работает только если данная переменная равна 1.
8. Опишем работу инструмента “кисть” для заливки замкнутых контуров, которые мы нарисуем
карандашом. При нажатии на кнопку “кисть”: цвет кисти ( аналогично цвету пера) устанавливается равным значению свойства backgroundcolor компонента Colorgrid (выбирается щелчком
правой кнопки мыши по нужной клетке компонента) в обработчике события OnChange компонента Colorgrid
9. Закраска должна происходить при щелчке мышью внутри замкнутого контура, следовательно
команду
заливки
удобно
добавить
в
обработчик
OnMouseDown
:
canvas.floodfill(x,y,canvas.pen.color,fsborder), причем ее выполнение нужно, только если значение свойства down для кнопки «кисть»= true, иначе при любом нажатии будет происходить заливка.
10. Резинка- это просто залитый цветом фона прямоугольник, который рисуется линией цвета фона. Размер прямоугольника- 5 пикселей во все стороны от точки нажатия (координаты- значения переменных x ,y)
11. Для того, чтобы прямоугольник, овал и линия «растягивались при нажатой левой кнопке во
время движения мыши по форме, воспользуемся стилем пера ( свойство mode) PmNotXor, при
котором изображение стирается при повторной прорисовке на том же месте. Алгоритм в обработчике события движения мыши по форме будет следующим:
если нажата кнопка «прямоугольник»: if speedbutton2.down=true ( на кнопке 2 нарисован прямоугольник)
 установить стиль пера: canvas.pen.mode:=pmnotxor;
 нарисовать прямоугольник в координатах от точки нажатия (они у вас уже сохранены) до текущих координат ( в первый момент они равны координатам точки нажатия и прямоугольник
вырожден в точку) : canvas.Rectangle(a,b,x1,y1)
 текущие координаты изменяются x1:=x;y1:=y;
 опять рисуется прямоугольник
12. Совершенно аналогично по ветви иначе реализуется в этом же обработчике рисование эллипса.
Не забудьте при отпускании кнопки мыши прорисовать фигуры в конечных координатах,
установив стиль пера PmCopy
13. Линия рисуется по тому-же принципу с той разницей, что для прорисовки- стирания линии
требуется две команды: переместить-прочертить (moveto --lineto), при этом меняются лишь координаты в торой команды
35
Урок 20
Создание справочной системы приложения
Файл справочной системы- это Rtf файл , созданный в текстовом редакторе по следующим правилам:
1. Все заголовки отметить одним из стилей «Заголовок»
2. Каждый раздел справки должен находиться на отдельной странице и заканчиваться символом
«конец страницы» (вставка- разрыв- конец страницы)
3. Заголовки должны быть отмечены сносками (вставка- сноска- обычная- другая- # - ok). После
этого ввести идентификаторы разделов справки: IDH_1, IDH_2 и т.д.
4. Если раздел содержит ссылку на другие разделы (гипертекст), подчеркиваем двойной линией
слово-ссылку и сразу за ним, без пробела, набираем идентификатор раздела, к которому должен быть переход, оформляя его скрытым текстом (выделяем фрагмент, затем: форматшрифт- эффекты- скрытый)
5. Сохраняем в формате Rtf
После загрузки Delphi:
1. Tools- HelpWorkShop (если нет, то добавьте:Configure Tools->add-> кнопка «обзор» для поиска)
2. File-> New -> Help Project
3. Выбираем папку, где уже должен быть rtf файл и вводим имя файла справочной исистемы.- сохранить
4. Files-> Add-> выбираем rtf файл
5. Windows-> Add-> Main
6. Map-> Add-> последовательно указываем идентификаторы разделов и соответствующие им
номера по порядку.
7. Save and compille
Для использования :
Свойству HelpFile формы дать значение имени файла справки, который будет вызываться по F1
Если справка должна вызываться по нажатию на кнопку, то обработчик:
WinHelp( Form1.Handle, ‘<имя файла>’Helpcontext,1)
Обработка исключительных ситуаций
В object Pascal есть средства обработки исключительных ситуаций. В данной программе исключительная ситуация может возникнуть при ошибке ввода вещественного числа, например через
точку, либо наборе символов, которые нельзя преобразовать в числовой тип, либо при попытке
разделить на 0. Обработчики событий строятся в виде следующих конструкций:
Try
<защищенный блок операторов>
exept
<обработка исключения>
end;
в нашей программе фрагмент обработки может выглядеть следующим образом:
Работа с образом формы (модуль DFM)
Файл открывается из Делфи, т.к. он не текстовый и из других сред не читается.
Изменить размер формы после запуска:
В объявление объекта форма включить строку: WindowState = wsMaximized
Убрать строку заголовка: BorderStyle = bsNone
Создать любой объект:
object a1: TPaintBox
Left = 24
Top = 456
Width = 369
Height = 33
Cursor = crHandPoint
End
При этом в модуле должно быть объявление полей объекта формы:
TForm1 = class(TForm)
36
…
a1: TPaintBox;
…
try
x::=strtofloat( edit1.text);
exept
showmassage(‘Ошибочная запись числа’);
edit1.setfocus;
exit;
end;
Использование в проекте exe файлов
Для подключения исполняемого файла добавьте ссылку на модуль Sellapi. Запуск файла производится командой: shellexecute(1,'open','ponon.exe','','',SW_SHOWMAXIMIZED); Первый параметр- ссылка на родительское окно (в дпнном случае единица.) Второй параметр- текстовая константа, определяющая выполняемую операцию (открытие файла). Третий параметр- имя исполняемого файла. Четвертый параметр может быть пустой строкой. Предпоследний параметр- строка
символов , указывающая директорию по умолчанию (если файл в текущем каталоге, то может
быть пустой строкой. Последний параметр определяет тип окна, в котором открывается исполняемый файл и может принимать значения:
SW_SHOWMAXIMIZED , SW_SHOWMINIMIZED, SW_SHOWMINNOACTIVE,
SW_SHOWNA, SW_SHOWNOACTIVATE,
SW_SHOWNORMAL.
Определить тип процессора:
si:Tsysteminfo;
….
Getsysteminfo(si);
label1.caption:=inttostr(si.dwprocessortype);
Урок 21
Создание компонентов
Для создания компонента:
1. Создать папку, куда будет сохранен модуль компонента.
2. В меню Component->new component
3. В появившемся окне задать имя базового класса ( Tbutton, Tedit и т.д.)
4. Дать имя создаваемому классу. (Tb)
5. Выбрать имя страницы палитры компонентов, куда будет помещен создаваемый компонент
6. Задать путь до созданной папки
7. Нажать Create Unit
8. Появится шаблон модуля, куда нужно внести необходимые изменения: как минимум должен
быть объявлен конструктор нового компонента: constructor create(Aowner:Tcomponent);, который в разделе реализации как минимум описан:
Constructor Tb.create(Aowner:Tcomponent); {конструктор вызывается, когда создается представитель класса}
begin
inherited create(Aowner);
end;
9. Сохраните модуль в созданной Вами папке.
10. Начните новый проект (FileNew application)
11. Компонент может быть поставлен на форму с палитры, либо создан динамически. Для динамического создания :
 В список используемых модулей (раздел uses) добавьте имя созданного (автоматически ему
дано то же имя, что и классу, только без буквы T)
 Создать объект (там же, где создается форма): var Form1: Tform1;
n:Tb;
 Для формы создать процедуру Oncreate, в которой создается компонент вызовом конструктора:
37
n:=Tb.create(form1);
n.parent:=form1;
В скобках в качестве параметра указывается имя компонента- владельца, после чего свойству parent нового компонента должно быть присвоено значение.
 После запуска программы компонент создается динамически.
Если компонент наследник имеющегося визуального- на странице появится его значок, такой же
как у родительского. Можно создать свой битовый образ компонента. Для этого:
 ToolsImage editor
 FileNewComponent resourse file
 В появившемся меню Resourse выбрать NewBitmap
 Выбрать размер (16*16 самый крупный значок компонента)
 Переименовываем Bitmap, давая ему имя класса, к которому принадлежит создаваемый компонент
 ViewZoom in
 Создав рисунок, сохраните его Filesave имя должно совпадать с именем модуля компонента
(pas)
 Componentinstall component
 Удалить
компонент
можно:
СomponentInstall
PacidgDelphi
Users
ComponentEditвыбрать нужныйRemove
unit mult;
сщздадим компонент имеет два свойства val1,val2, доступные как во время проектирования, так и
выполнения и свойство res, доступное только во время выполнения переменные для хранения
данных свойств объявлены в разделе private, поэтому только в пределах класса процедуры имеют
доступ к этим данным значения первых двух свойств перемножаются и результат становятся
значением третьего. Это происходит во время выполнения метода Domult}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
Tmult = class(Tcomponent)
private
{ Private declarations }
fval1,fval2,fres:integer;
protected
{ Protected declarations }
public
{ Public declarations }
property res:integer read Fres write Fres;{доступно только во время выполнения}
constructor create(Aowner:Tcomponent);override;
procedure Domult;
published
{ Published declarations }
property val1:integer read Fval1 write fval1;
property val2:integer read fval2 write fval2;
end;
procedure Register;
implementation
constructor Tmult.create(Aowner:Tcomponent);
begin
inherited create(Aowner);
end;
procedure tmult.Domult;
begin
38
res:=Fval1*fval2;
end;
procedure Register;
begin
RegisterComponents('Samples', [Tmult]);
end;
end.
На форме можно поставить новый компонент ( свойствам val1 и val2 на странице свойств можно
присвоить значения)метку и кнопку, в которой:
procedure TForm1.Button1Click(Sender: TObject);
begin
mult1.Domult;
label1.caption:=inttostr(mult1.res);
end;
Событие- это свойство типа Tnotifyevent, его надо добавить к имеющимся:
property onbig:TnotifyEvent read Fbig write Fbig;
не забыв объявить переменную Fbig:Tnotifyevent; в разделе private (слово var не нужно)
тогда можно вызвать это событие: mult1.onbig(sender); а уж что при этом выполняется, описывается как всегда вызовом обработчика на странице событий. Например событие выглядит:
procedure TForm1.mult1big(Sender: TObject);
begin
label1.caption:='Первое число больше 100';
end;
и вызывается в момент запуска программы, если первое поле больше 100
Модификация существующего компонента
Построим компонент кнопка-часы на базе кнопки. Компонент Timer встраивается в создаваемый,т.е. когда компонент создается конструктором, активизируется таймер, когда таймер
вызывает свое событие OnTimer, процедура Ltime обновляет запись на кнопке. Когда компонент
удаляется, вызывается деструктор и таймер тоже удаляется. Возможность вывода времени иллюстрируется следующим примером:
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := TimeToStr(Time);
end;
Для проверки компонента поместите его на форму, не забудьте таймер.
unit bclock;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls,Extctrls;
type
Tbclock = class(Tbutton)
private
{ Private declarations }
Ntimer:TTimer;
procedure ltime(sender:Tobject);
protected
{ Protected declarations }
public
{ Public declarations }
constructor create(Aowner:Tcomponent);override;
destructor destroy;override;
published
{ Published declarations }
end;
procedure Register;
implementation
constructor Tbclock.create(Aowner:Tcomponent);
39
begin
inherited Create(Aowner);{вначале выполняется код родителя}
Ntimer:=Ttimer.create(Aowner);{создается таймер}
Ntimer.enabled:=true;
Ntimer.interval:=1000;
Ntimer.ontimer:=ltime;
end;
destructor Tbclock.destroy;
begin
Ntimer.destroy; {уничтожается таймер}
inherited destroy;
end;
procedure Tbclock.Ltime(sender:Tobject);
begin
caption:=timetostr(Now);
end;
procedure Register;
begin
RegisterComponents('Samples', [Tbclock]);
end;
end.
Графический компонент
Это наследник классаTgraphcomponent, не имеющий собственного дескриптора окна. Главным
принципом создания является реализация процедуры Paint, которая вызывается всякий раз, когда
нужно перерисовать компонент
40
Download