Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
[1] Оглавление [2] Оглавление
[2.1]
[2.2]
[2.3]
[2.4]
[2.5]
[2.6]
[2.7]
[2.8]
[2.9]
[2.10]
[2.11]
[2.12]
[2.13]
[2.14]
[2.15]
[2.16] [2.17] Лабораторная работа № 13 «Графика в Дельфи».
[2.18] [2.19] Лабораторная работа № Светофор [2.20] Лабораторная работа № Летающий шарик.
[2.21] [2.22] Цель научиться строить графика с использованием специальных средств среды Дельфи Для примера построим график функции y=10*sin(x), аналог Excel диаграммы приведен на рисунке.
[2.23]
[2.24]
[2.25]
[2.26] |
Объекно-ориентированное программирование (ОПП) это технология, основанная на представление программ в виде совокупности объектов, каждый из которых является реализацией собственного класса, которые в свою очередь образует иерархию на принципе наследования.
Две важнейшие характеристики Delphi: визуальное конструирование формы и богатый набор библиотек визуальных компонентов(Visual Component Library VCL). Визуальное конструирование формы избавляет от разработки интерфейса программы, так как Delphi автоматически создает необходимые программные заготовки и соответствующие файлы ресурсы. Для этого используется окно формы как прототип будущего окна программы которое наполняется объектами, реализующие нужные интерфейсные свойства.
Основное базовое понятие в языке Delphi является понятие объекта. Каждый объект имеет набор свойств, которые можно изменять как в процессе визуального проектирования так и в работающем приложении. Совокупность объектов с определенными свойствами образуют класс объектов. Каждый класс имеет свои, присущие только ему, свойства. Основной (базовый) класс называется родительским классом, порождающий все остальные классы. Наследники основного родительского классы, наследуют свойства своего родителя.
Каждый класс имеет свои методы, которые определяет поведение объектов этого класса. Методами являются функции и процедуры. Процедура представляет собой обработчик некоторого события, например щелчка мыши. Функция также представляет собой обработчик событие, но в отличие от процедуры при этом возвращает некоторое, вычислительное значение. Процедуры и функции создаются с помощью операторов, написанных на языке Object Pascal. Объект имеет определенный набор событий. События указывают на метод, используемый при наступлении этого события.
Основные понятия.
Класс (class) это категория объектов, обладающих одинаковыми свойствами и поведением. Класс имеет поля (свойства), свойства и методы. Имя класса может быть любым допустимым идентификатором. Принято идентификаторы большинство классов начинать с символа «T». Например TButton содержит все для создания кнопки.
Объект (odjeict) конкретный, существующий в памяти компьютера, экземпляр класса. Объект всегда находится в определенном состоянии, которое определяет его свойства. Свойства бывают статическими и динамическими изменяемые во время выполнения программы. Идентифицирует объект поле хранящее его уникальные данные. Поле (field) инкапсулированные (содержащиеся) в классе данные. Обращение к полям производится посредствам свойств и методов. У каждого объекта обязательно присутствуют два метода: «создать объект» и «уничтожить объект». Во время создания объекта происходит выделение памяти для хранения необходимых свойств, и заполняются значения по умолчанию. Во время уничтожения объекта происходит освобождение выделенной памяти. Метод для создания объекта называется конструктором (constructor). Метод для уничтожения объекта называется деструктором (destructor).
Объекты взаимодействуют друг с другом, воздействуют на другие объекты и подвергаются воздействию других объектов. Объект совокупность свойств, методов и событий. Свойства это простые переменные, которые влияют на состояние объекта. Например, ширина, высота это свойства объекта. Методы это те же процедуры и функции, т.е. это то, что объект умеет делать (вычислять). Например, объект может иметь процедуру для вывода какого-то текста на экран. Эта процедура и есть метод объекта. События это те же процедуры и функции, которые вызываются при наступлении определённого события. Например, если изменилось какое-то свойство объекта, может быть сгенерировано соответствующее событие и вызвана процедура для обработки реакции на это событие.
Свойство (property) представляет собой механизм, регулирующий доступ к полям. Свойства определяют внешний вид формы или компонента (объекта на форме) и поведение формы или компонента. Различают несколько видов свойств.
Простые свойства это свойства, значения которых являются числа или строками.
Перечисляемые свойства это свойства, которые могут принимать значение из предопределенного набора (списка).
Вложенные свойства это свойства, которые поддерживают вложенные значения. (Отмечается в ИСР знаком «+»). Свойство это атрибут объекта, определяющий то как объект выглядит или как он может себя вести
Метод (method) это процедура или функция, которая определена как часть инкапсулирована (содержится) в нем. Методы манипулируют полями и свойствами классов (могут работать с переменными) и имеют автоматический доступ к любым полям и свойствами своего класса.
Поведение объекта определяется тем, какие имеет обработчики и для каких событий. Создание приложение в среде программировании Delphi состоит из настройки свойств используемых объектов и создание обработчиков событий (event handler). Функции и процедуры являются методами, которые применяются для создания обработчиков событий
События (event) свойство процедурного типа. Значением события является указатель на метод
Достоинства ООП
ООП дает возможность создавать расширяемые системы. Это одно из основных достоинств ООП, и именно оно отличает данный подход от традиционных методов программирования. Расширяемость означает, что существующую систему можно заставить работать с новыми компонентами, причем без внесения в нее каких-либо изменений. Компоненты могут быть добавлены на этапе исполнения программы.
Полиморфизм оказывается полезным преимущественно в следующих ситуациях.
Часто многоразового использования программного обеспечения не удается добиться из-за того, что существующие компоненты уже не отвечают новым требованиям. ООП помогает этого достичь без нарушения работы уже имеющихся компонентов, что позволяет извлечь максимум из многоразового использования компонентов.
Недостатки ООП
Документирование классов - задача более трудная, чем это было в случае процедур и модулей. Поскольку любой метод может быть переопределен, в документации должно говориться не только о том, что делает данный метод, но и о том, в каком контексте он вызывается. Ведь переопределенные методы обычно вызываются не клиентом, а самим каркасом. Таким образом, программист должен знать, какие условия выполняются, когда вызывается данный метод. Для абстрактных методов, которые пусты, в документации должно говориться о том, для каких целей предполагается использовать переопределяемый метод.
В сложных иерархиях классов поля и методы обычно наследуются с разных уровней. И не всегда легко определить, какие поля и методы фактически относятся к данному классу. Для получения такой информации нужны специальные инструменты, вроде навигаторов классов. Если конкретный класс расширяется, то каждый метод обычно сокращают перед передачей сообщения базовому классу. Реализация операции, таким образом, рассредотачивается по нескольким классам, и чтобы понять, как она работает, нам приходится внимательно просматривать весь код.
Методы, как правило, короче процедур, поскольку они осуществляют только одну операцию над данными, зато их намного больше. В коротких методах легче разобраться, но они неудобны тем, что код для обработки сообщения иногда "размазан" по многим маленьким методам.
Инкапсуляцией данных не следует злоупотреблять. Чем больше логики и данных скрыто в недрах класса, тем сложнее его расширять. Отправной точкой здесь должно быть не то, что клиентам не разрешается знать о тех или иных данных, а то, что клиентам для работы с классом этих данных знать не требуется.
Многие считают, что ООП является неэффективным. Как же обстоит дело в действительности? Мы должны проводить четкую грань между неэффективностью на этапе выполнения, неэффективностью в смысле распределения памяти и неэффективностью, связанной с излишней универсализацией.
Среда Delphi - это сложный механизм, обеспечивающий высокоэффективную работу программиста. Визуально она реализуется несколькими одновременно раскрытыми на экране окнами. Окна могут перемещаться по экрану, частично или полностью перекрывая друг друга.
Запуск Дельфи обычным путем :
После запуска на экране в стандартной настройке появится 5 окон (рис. 1)
Рис1.
Главное окно осуществляет основные функции управления проектом создаваемой программы. Это окно всегда присутствует на экране и упрямо занимает его самую верхнюю часть. Не пытайтесь его распахнуть на весь экран: даже в максимизированном состоянии его размеры и положение практически не отличаются от обычных. Главное меню содержит все необходимые средства для управления проектом. Все опции главного меню представляют собой опции-заголовки, открывающие доступ к выпадающим меню второго уровня. В главном окне находится меню команд, панель инструментов и палитра компонентов. (рис 2) Строка заголовка главного окна содержит имя приложения Delphi 7 и имя текущего проекта
Рис 2.
Панель инструментов (Toolbars) располагается ниже меню в левой части экрана и содержит кнопки быстрого доступа пиктограммы команд, используемые в процессе создания проекта. Для управления панелью инструментов достаточно в области кликнуть левой кнопкой мыши. В появившемся окне достаточно против названия панели кликом правой кнопки мыши поставить галочку. Пиктограмма на которой изображен зеленый треугольник позволяет запустить приложение на выполнение. Пиктограмма позволяет переключаться между окном Form и окном редактора.
Палитра компонентов (Component Palette) содержит вкладыши страниц с расположенными на них пиктограммами, используемые при создании проекта. Каждая страница содержит характерные для нее компоненты.
Разделы меню. Если название пункта меню заканчивается многоточием, то при выборе этого пункта откроется диалоговое окно. Если название пункта меню содержит стрелку, то при выделение этого пункта меню открывается его подменю. Неактивная команда меню отображается серым цветом. Для многих команд справой стороны указаны сочетания клавиш (горячие клавиши).
Рис 4. |
Окно форм (Form1) представляет собой заготовку главного окна разрабатываемого приложения (прикладную программу). Форма имеет вид стандартного окна операционной системы Windows (рис.4). В верхней части формы расположена строка заголовка, кнопки управления окном. Форме автоматически присваивается имя Form1.
Рис. 5 |
Окно инспектор объектов (Object Inspector) окно редактора свойств объектов предназначено для редактирования значений свойств объектов. В терминологии визуального проектирования объекты диалоговые окна и элементы управления. Каждая страница окна Инспектора объектов представляет собой двухколончатую таблицу (рис.5), левая колонка которой содержит название свойства или события, а правая - конкретное значение свойства или имя подпрограммы, обрабатывающей соответствующее событие. В окне инспектор объектов есть две вкладки Propertion (собственно свойства) и Events (обработчик событий). Включается окно в меню Veiw командой Object Inspector или клавишей F11. Соответственно в том же меню команда Object TreeView включает одноименное окно или сочетание клавиш Shift+Alt+F11.
Любой размещаемый на форме компонент характеризуется некоторым набором параметров: положением, размером, цветом и т. д. Свойство компанента это характеристики, определяющие вид, положение и поведение объекта. Например, свойство Width и Height задают размер (ширину и высоту) формы и т.п. Часть этих параметров, например, положение и размеры компонента, программист может изменять, манипулируя с компонентом в окне формы. Для изменения других параметров предназначено окно Инспектора объектов.
Рис. 6 |
Окно редактора кода предназначено для создания и редактирования текста программ. Первоначально открывается состоящим из двух частей: окна проводника кода (Code Explorer) и самого редактора кода, содержащего две страницы Code и Diagram. Окно редактора кода мощный редактор для создания и редактирования кода модулей программы в окне набирается текст программы. В начале работы над новым проектом окно редактора кода содержит сформированный Delphi стандартный шаблон программы, а название окна имеет стандартное имя Unit1. Страница Diagram окна редактора предоставляет визуальный инструментарий для определения логических взаимоотношений между визуальными и невизуальными компонентами, отображаемые в окне (Object TreeView)
Сохранение проекта. Каждый создаваемый вами проект следует сохранять в отдельной папке, которую следует создавать в каталоге Projects. Сохранить проект можно в любой момент времени. Для этого можно воспользоваться кнопкой быстрого доступа панели инструментов кликнув на ней правой кнопкой мыши или выбрать команду Save Project… или Save All. В появившемся диалоговом окне следует записать имя сохраняемого проекта и нажать на кнопку «Сохранить». Сразу за первым окном появиться второе диалоговое окно в котором следует ввести имя проекта и нажав на кнопку «Сохранить» в той же папке.
Открытие нового проекта.
Для открытия нового проекта используют меню File New Application если данный пункт выключен то File New Other Application
1. Запустите Delphi
2. На форму поместите компонент Button (кнопка), который находится на вкладке Standard (Стандартные) палитры компонентов. Сделать это можно двумя способами:
1. Щелкните по кнопке . Затем кликнуть в том месте формы, где будет находиться кнопка:
2. Двойной клик по компоненту Button приведет к появлению объекта на форме.
Далее выделив объект перетащите его в нужное место на форме. Кнопка добавлена.
Рис. 1 |
Мы создали объект - Button1 (Кнопка1)(рис.1), однако нужных нам свойств этого объекта пока нет - их тоже нужно создать. Для этого познакомимся с Инспектором Объектов. Окно имеет две вкладки. Каждая вкладка имеет вид таблицы с двумя столбцами. Первый столбец содержит свойство, а второй конкретное значение свойства. Различают несколько видов свойств.
Простые свойства это свойства, значения которых являются числа или строками. Например: свойство Height числовое значение -41
Перечисляемые свойства это свойства, которые могут принимать значение из предопределенного набора (списка). Например: свойство ShowHint имеет список из двух значений: False и True.
Вложенные свойства это свойства, которые поддерживают вложенные значения. (Отмечается в ИСР знаком «+»). Например: Font
Все объекты имеют свойства. Для различных объектов многие свойства совпадают, но есть и различия, присущи только этому объекту. Пока мы не задали свойства кнопки, считается, что содержание надписи совпадает с именем объекта. Именно поэтому мы и видим на экране надпись Button1. Изменим стандартный заголовок объекта Button на другой. Для объекта выберем свойство Caption (заголовок) и в поле параметр введем другое название кнопки «Выход». Название кнопки изменяется одновременно с вводимой вами надписи.
Работают с панелью Инспектор Объекта по следующему алгоритму:
3. Запустите программу: кнопка на клавиатуре F9 или пункт меню “RUN” или на панели инструментов пиктограмму . Попробуйте нажать на кнопку. Кнопка нажимается, но нечего не происходит.
4. Закройте окно формы, щелкнув по крестику, чтобы опять попасть в режим редактирования.
5. Выберите объект Button. Сделать это можно следующим образом: 1. В окне Form кликнуть на объекте кнопкой мыши. 2. в окне дерева объектов (Object TreeView) выбрать нужный объект. 3. В окне Инспектор Объекта нажав на треугольник в списке объектов выбрать нужный.
6. Далее в окне Инспектор Объекта выбрать вкладку Evets и выбираем событие, реакцию приложения нажатие на кнопку. В нашем случаи это событие OnClick.
Двойной клик правой мышки приведет к открытию в окне редактора кода процедуры. Между словами begin … end; впишите метод команду Close.
7. Запустите программу. Проверьте, работает ли кнопка.
8. Чтобы поместить на форму надпись следует воспользоваться компонентом Label. Для этого сначала кликните пиктограмму на вкладке Standard, а затем кликнете на форме.
9. Измените свойство Caption компонента Label присвоив значение: «Проверка кнопки».
10. Поставьте на форму еще один компонент вторую кнопку. Измените свойство Caption на «Проверка».
11. Создайте обработчик события кнопки «Проверка».
12. В процедуре между словами Begin … end; наберите: Label1 и поставьте точку. Немного подождав, Вы увидите еще одно достоинство Delphi: через мгновение появится окно с подсказкой, какие команды можно набрать
Вы можете листать этот список, выбирая нужную команду. Если Вы начнете набирать по одной букве, Delphi попытается угадать, какую команду Вы желаете ввести. Если появилась нужная команда, просто нажмите Enter, и команда окажется в тексте программы.
13. Наберите следующий текст:
14. Запустите программу. Проверьте, как работают обе кнопки. Вы набрали всего 2 строки кода, а у Вас готовое функционирующее приложение.
Познакомимся с некоторыми свойствами.
Многие свойства объектов можно изменять используя мышку. Например: изменить размеры установленной нами кнопки можно непосредственно на форме. Для этого надо выделив объект «зацепить» мышкой за любой угол и придать нужный размер. Также можно легко изменить местоположение кнопки на форме. Но те же самые манипуляции можно выполнить и с помощью свойств в окне инспектора свойств.
Самостоятельно изучите свойства формы.
Посмотрим, какими свойствами обладает наша форма - Form1. Для этого щелкните на форме. Затем, в окне инспектора объектов (см. рисунок выше) перейдите на закладку Properties (свойства). Рассмотрим наиболее часто используемые прилагаемые ниже свойства формы, button и label заполнив приведенные ниже таблицы
Таблица №1 Form
Caption |
Образец: Текст формы, отображается в строке заголовка. По умолчанию, Delphi присваивает этому свойству то же значение, что и свойству Name. |
Color |
|
Cursor |
|
Enabled |
|
Hint |
|
Left |
|
Name |
|
ShowHint |
|
Tag |
|
Top |
|
Visible |
|
Width |
Таблица №2 Button
Свойство |
|
Caption |
|
Cursor |
|
Height |
|
Hint |
|
Left |
|
ShowHint |
|
Top |
|
Width |
Таблица №2 Label
Итак, мы научились изменять свойства компонентов во время проектирования программы. Но иногда бывает нужно что-то изменить уже в процессе работы программы. Например, поменять название на кнопке, изменить размер и цвет формы и т.п.?
1. Свойства компонентов можно изменять во время работы приложения, т.е. программно. Для этого надо написать строку, в которой свойству с помощью оператора := присваивается нужное значение.
рис 1. |
Откройте Delphi. Поместите на форму две кнопки Button1 и Button2. Кнопке Button1 поставьте свойство left= 50. В результате, кнопка окажется на расстоянии 50 пикселов слева от начала формы. Кнопку Button2 поместите ниже.
Два раза щелкните по кнопке Button2 и между строками begin ... end введите: button1.Left :=250;
Составное имя button1.Left необходимо для указания компилятору, о каком объекте идет речь: в нашем примере используются 3 компонента (форма и 2 кнопки) и каждый из них имеет свойство Left; префикс Button2 заставляет изменить это свойство у кнопки с именем Button2.
Запустите программу. Так изменяются свойства объекта не с помощью Инспектора Объектов, а в режиме выполнения, программно.
Закройте программу. Вы вернетесь в режим проектирования. Откройте модуль программы- это то окно, которое находится позади формы, щелкнув по нему мышью или нажав F12.
Давайте внимательно посмотрим на это окно код вашей программы. Наш файл, пока не сохраненный называется Unit1:
В программе используются 3 объекта: форма с именем Form1 и 2 кнопки с именами Button1 и Button2.
В программе используется только одна процедура- процедура обработки щелчка второй кнопки.
Текст самих процедур записывается после раздела implementation и заключается в конструкцию begin...end.
Самостоятельно:
измените программу так, чтобы при нажатии на первую кнопку форма приобретала красный цвет, а при нажатии на вторую кнопку: синий и посмотрите как меняется окно кода.
Написать программу "Нажималка".
2. Создать программу, на экране которой изображена кнопка. При нажатии на нее кнопка должна перепрыгивать на 100 пикселов вправо.
Откройте Delphi. Поместите на форму кнопку.
Теперь давайте рассуждать. Надо чтобы при нажатии на кнопку она перемещалась на 100 единиц вправо, т. е. реагировала на щелчок. Следовательно, надо написать обработчик нажатия клавиши.
В Object Inspector (инспекторе объектов) перейдите на вкладку Events (События) и щелкните 2 раза напротив поля OnClick (при нажатии).
За положение компонента на форме отвечает свойство Left. Следовательно, его и необходимо изменить: В процедуре: procedure TForm1.Button2Click(Sender: TObject)
Между begin и end напишите: button1. Left := 100;
Напомню в информатике приходится иметь дело с выражениями типа: x := x+1; С точки зрения математики тождество ложное, в информатике же это значит, что нужно взять из переменной х число, прибавить к нему 1 , и результат опять поместить в эту переменную. (Переменная играет роль ящика, в который складывают или берут числа).
Запустите программу, проверьте, работает ли кнопка.
Оказывается, работает, если нажать один раз. Во второй раз она уже не двигается. Чтобы передвинуть кнопку еще на 100 пикселов надо написать button1.Left := 200;
Попробуйте. Запустите программу, проверьте. Кнопка переместилась сразу на 200 пикселей. Программа сделает эти два оператора, но ВЫ не увидите, потому что скорость выполнения огромна. Нужно придумывать что-либо другое.
Сотрите предыдущие операторы и на их месте наберите: Button1.left:= Button1.left+200;
Программа должна взять из переменной button1.left число, прибавить к нему 200 и результат опять поместить в эту переменную.
Запустите программу, попробуйте. Программа должна работать как надо.
Запомните этот прием. Он применяется очень часто.
3. Одно из самых используемых свойств любого компонента- видимость. С помощью него можно до поры спрятать какой-либо элемент. Задача: написать программу, в которой кнопка при нажатии на нее скачет по периметру формы, перемещаясь по часовой стрелке.
Наша задача создать такую же программу.
рис 1. |
Начните новый проект и сохраните его под названием lab_3.
На форму поместите 8 кнопок, как на рис.1
Надпись и размеры кнопок должны быть одинаковыми. Для этого нужно выделять кнопки по очереди и изменять их свойство Caption. Но придется 8 раз делать одно и тоже. Процедура займет некоторое время. Есть другой способ. Выделите все кнопки и измените необходимые значения. Нажмите клавишу SHIFT и щелкайте мышкой по очереди все кнопки.
Выберите в Object Inspector свойство Caption и измените его на такое: Нажми меня.
Свойство Visible для всех кнопок поставьте равным False (Их не будет видно в начале).
Снимите выделение со всех кнопок, щелкнув на любом месте формы.
Выделите 1-ую кнопку, щелкнув по ней мышью, и свойство Visible этой кнопки поставьте True. Именно первая кнопка будет видна после загрузки.
Запустите программу. Если на вашей форме видна только одна первая кнопка, значит все сделано верно.
Закройте программу и вернитесь в режим проектирования.
Теперь дело за программированием.
Создадим имитацию прыжка. Сделаем видимой кнопку 2, а кнопку 1 спрячем.
Двойным щелчком по кнопке 1 войдите в обработчик события.
Допишите между begin … end; следующее:
procedure TForm1.Button1Click(Sender: TObject);
begin
button1.Visible:=false;
button2.Visible:=true;
end;
Запустите программу. Проверьте. После щелчка на кнопке, кнопка 1 исчезает, а 2-ая кнопка появляется, а создается ощущение, что прыгнула 1-ая кнопка.
Для второй кнопки обработчик такой: 2-ую кнопку прячем, 3-ью показываем. И т.д…
Сделайте это самостоятельно.
Цель: Познакомиться с объектом edit. Изучить функцию перевода целых чисел в текст и наоборот.
Программу которую мы будем создавать, должна выполнять следующие действия: она должна обеспечивать ввод двух целых чисел с клавиатуры компьютера (ввод будет отображаться в двух текстовых окнах) и выводить в третьем окне сумму этих двух чисел. На примере такой несложной задачи мы освоим основные приемы разработки программ вычислительного характера.
Правила использование переменных в языке Objekt Pascal аналогично Turbo Pascal. Для имени переменных должны использоваться только английские буквы и цифры, переменные должны быть описаны в разделе Var. Все переменные делятся на глобальные, которые могут использоваться во всей программе и локальные, которые используются только внутри определенной процедуры. Необходимо придерживаться следующего простого правила: в программе должно быть как можно меньше глобальных переменных, т.к. для устранении ошибки придется анализировать весь текст программы довольно большой по объему.
В Turbo Pascal ввод значений присваиваемые переменным происходить с клавиатуры в числовом виде. Нам предстоит числовые величины ввести с клавиатуры в текстовые окна а затем использовать их для вычислений. Для того чтобы перевести текстовую информацию в числовую, необходимо использовать стандартную функцию StrtoInt. (Str сокращение от английского string (строка), Int от integer (целое)). Данная функция «преобразовать строку в целое число». Аргументом данной функции является текстовая величина, а значением соответствующая числовая величина.
Пример: X:= StrtoInt (t); где t - текстовая переменная преобразуется в числовую величину X.
В нашей программе в качестве аргумента будет выступать свойство Text объекта Edit. Поэтому операция преобразования введенного пользователем в текстовое окно Edit1 текста в числовую величину будет выглядеть так:
X:= StrtoInt(edit1.text);
После выполнения операции сложения перед нами встанет обратная задача перевести полученный результат из числовой величины в тестовую. Для этого можно воспользоваться другой стандартной функцией, обратной операции StrtoInt InttoStr. Опрератор выполняющий это действие , будет выглядеть так:
Edit3.Text:=InttoStr(z);
У вас должно получиться как на рис 1
Рис 1 |
Переходим к написанию кода программы.
7. Введем в программу три переменные, значением каждой из которых будет числовое значение текстовой информации, отображаемой в одном из текстовых окон. Дадим переменным имена e1, e2, e3 (в соответствии с окнами Edit1, Edit2, Edit3). Действия с данными будут производиться при нажатии экранной кнопки «Сложи» Поэтому описание этих (локальных) переменных мы вставим в процедуру Tform1.Button1Clik. Данная процедура описывает реакцию кнопки на щелчок мыши по ней. Для создания этой процедуры достаточно в форме Button1, выделить вкладку Events (события) и дважды щелкнуть мышью справа от события OnClick. Описание переменныхбудет следующтм:
Var
e1,e2,e3 :integer;
и находиться сразу после заголовка процедуры Tform1.Button1Clik.
Переменным e1, e2 будут присваиваться значения первого и второго слагаемых, вводимых в текстовые окна Edit1, Edit2. Для преобразования текста, вводимого в эти окна, в числовые значения переменных е1,е2, воспользуйтесь стандартной функцией StrtoInt. Преобразование выполнится с помощью операторов:
e1:= StrtoInt(Edit1.Text);
e2:= StrtoInt(Edit2.Text);
Далее оператор сложения двух чисел и преобразование числового значения в текстовое.
Edit3.Text:= InttoStr;
Целиком процедура должна выглядеть так:
procedure TForm1.Button1Click(Sender: TObject);
var
e1,e2,e3 :integer;
begin
e1:= StrtoInt(Edit1.Text);
e2:= StrtoInt(Edit2.Text);
e3:=e1+e2;
Edit3.Text:= InttoStr(e3);
end;
8. Запустите программу.
Самостоятельно:
Измените программу следующим образом, чтобы можно было производить не только сложение но и вычитание и умножение.
программа "Test"
Цель: Научиться составлять программы с оператором ветвления. Познакомится и объектами панель, радиокнопка.
Программист, ложась спать, ставит возле кровати 2 стакана:
один с водой, если захочет пить, а другой пустой, если не захочет.
Из программистского юмора
Наша жизнь полна неожиданностей и условностей. Каждый день приходится решать тысячи мелких задач, делая выбор. Реальная задача - переход улицы, на которой работает светофор.
Вот как выглядит эта задача на языке блок-схем:
рис. 1 |
На естественном языке такая конструкция выглядит так:
Если горит зелёный, то иду, иначе стою.
Или, в общем виде:
Если <условие>
то <ветвь "Да">
иначе <ветвь "нет">
А оператор называется Если…то… иначе…. На языке программирования этот оператор звучит следующим образом: IF…THEN…ELSE….
IF <условие>
THEN <ветвь "Да">
ELSE <ветвь "Нет">
А поскольку в любой ветви может быть не один, а несколько шагов, то их необходимо оформить в виде отдельной подпрограммы (записать между begin и end), т.е.
IF <условие> |
Если горит зелёный |
THEN |
То |
Begin |
Begin |
<ветвь "Да"> |
иди |
End |
End |
ELSE |
ELSE |
Begin |
Begin |
<ветвь "Нет"> |
стой |
End |
End |
Оказывается, ни одна серьезная программа не обходится без этого оператора. А как с ним работать, мы разберемся на примере решения следующей задачи: напишем вариант шаблон для теста, т.е. как работает обычный тест
Запустите Delphi.
Сделайте вашу по ниже приведенному образцу форму используя на вкладке Standard (Стандартные) палитры компонентов объекты Button, Label, GroupBox кнопка и RadioButton кнопка .
рис. 2 рис. 3
Чтобы слова в компонентах Label располагались не в одной, а в нескольких строчках нужно прежде, чем набирать текст, свойство объекта WordWrap сделайте равным True.
Начинаем программирование.
Пользователь выбирает ответ из предложенных, затем нажимает кнопку Проверить. Программа проверяет, правильно ли выбраны ответы. Если дан правильный ответ - выводим ответ «Верно» и отключаем кнопку "Проверка", Иначе - соответствующий ответ и даем возможность продолжить тест. Значит, программировать необходимо кнопку Проверить.
Дважды щелкните на кнопке «Проверить» и откройте окно редактора кода.
рис. 5
Для этого оператора есть правило: если между begin…end стоит один оператор, то строки begin…end можно опустить. В нашем случае, по ветви "ДА" - 2 оператора, по ветви "НЕТ"- 1 оператор, следовательно, во втором случае begin…end можно убрать. И тогда код будет выглядеть следующим образом:
procedure TForm1.Button1Click(Sender: TObject);
begin
if radioButton3.Checked
then
Begin
label1.Caption:='Верно';
button1.Enabled:=False;
End
else
label1.Caption:=' Ошибка';
end;
Самостоятельно:
Сделайте тест, состоящий из трех вопросов, например, такой:
Цель: Закрепить навыки написания программ ветвления, познакомиться с элементом ShowMessage.
Создадим программу-пароль. Она будет работать следующим образом: При загрузке программа попросит ввести пароль, если Вы введете пароль правильно, программа напишет "Добро пожаловать", если пароль неверен ответ будет "Посторонним вход воспрещен".
1. Откройте Delphi или создайте новый проект.
Для данной программы потребуются следующие элементы: компонент Label (для вывода надписей на экран), компонент Edit (для ввода пароля), 2 кнопки (подтвердить ввод и выход).
2. Поместите данные элементы на форму:
рис.1 |
рис. 2 |
3. Измените свойства Caption объектов. В объекте Edit это свойство Text)
Логика программы: что мы хотим, как будет работать программа. При загрузке необходимо будет ввести пароль. При нажатии на кнопку ОК, программа проверяет, правильно ли был введен пароль (сравнивает строку в Edit со строкой в памяти компьютера), и если пароль верен, то выводит надпись "Добро пожаловать", а строку Edit прячет; если неправильно, то выводит на экран окно с сообщением, что пароль неверен.
4. Пишем обработчик события для клавиши ОК (2 раза щелкните по кнопке, и Вы окажетесь в редакторе кода в нужном месте:
рис. 3
5. Запустите программу клавишей F9. Проверьте, как ведет себя программа. Введите правильный и неправильный пароль. Ели пароль неверный то на экране должно появиться окно рис 4.
Вы не находите в нем ничего странного? Ведь мы написали оператор edit1.Text:='';, который должен был очистить строку ввода, а у меня там введенный пароль. На самом деле, все верно. Наш оператор стоит после строки ShowMessage значит, он должен выполняться после него. И хотя компьютер вывел на экран сообщение (т.е. данное окно), работа оператора еще не завершилась. Оператор завершится, когда Вы нажмете ОК. И, действительно, как только Вы нажмете ОК, строка ввода очистится.
Рис. 4 |
Счетчик.
Давайте усовершенствуем программу так, чтобы пользователь мог лишь несколько раз ввести пароль, например, 3 раза. Чтобы решить данную проблему, нам понадобится счетчик. Счетчик это специальная переменная, которая увеличивается на 1 при нужном событии.
8. Счетчиком будет переменная k. Значение переменной k должно увеличиваться когда введен неверный пароль, следовательно должно нужно обрабатывать события кнопки ОК по ветви "нет". Измените код кнопки, добавив в него строку: k:= k+1;
Далее нужно проверить, совершено ли данное событие 3 раза, т.е. k=3 или нет, и если так, то закрыть форму. Записать данную процедуру можно следующим образом:
if k=3 then form1.close;
Посмотрите, ваша процедура должна быть похожа на следующую:
procedure TForm1.Button1Click(Sender: TObject);
begin
if edit1.Text='qqq'
Then
begin
Label1.Caption:=' Добро пожаловать ';
edit1.Enabled:=false;
end
Else
begin
ShowMessage (' Посторонним вход воспрещен ');
edit1.Text:='';
edit1.SetFocus;
k:= k+1;
if k=3 then form1.close;
end;
end;
9. Теперь необходимо объявить новую переменную. Делается это в редакторе кода после раздела implementation. В разделе VAR:
10.Последнее, что нужно сделать, это присвоить начальное значение переменной. Зададим начальное значение при запуске программы, т.е. при рождении формы.
11. В Инспекторе объектов выберите Form1, перейдите в раздел Events, и дважды щелкните напротив строки OnCreate (при создании). Откроется соответствующая процедура.
12.Введите оператор в открывшуюся процедуру :
procedure TForm1.FormCreate(Sender: TObject);
begin
k:=0;
end;
Самостоятельно:
Доделайте программу, чтобы она при неправильном пароле выводила надпись: У вас осталась 1 попытка ( или 2 или 3).
Цель: познакомится с приемом обработки вещественных чисел, изучить объект Images.
Результатом разработки должна стать программа решения квадратного уравнения вида:
По введенным с клавиатуры исходным данным программа должна либо находить корни квадратного уравнения, либо выдавать сообщение о том, что данное уравнение не имеет решения. Вспомним алгоритм решения данного уравнения. В начале следует вычислить дискриминант уравнения, который определяется по формуле:
d=b2-4ac.
Затем в зависимости от величины дискриминанта определяется возможность нахождения решения данного уравнения. Если дискриминант положителен или равен нулю, то уравнение имеет решение и можно найти два его корня х и х2 (в случае равенства дискриминанта нулю два корня будут равны между собой). Вычисление корней производится по следующим формулам:
В случае же, если найденный дискриминант отрицателен, уравнение вообще не имеет решения.
Как видно из сказанного ранее, данный алгоритм хорошо подходит для реализации с помощью условного оператора if.
Как всегда, работу над проектом начинают с разработки интерфейса программы.
Основное окно программы должно содержать три текстовых окна: для ввода исходных данных коэффициентов а, b и с квадратного уравнения. Слева от каждого из этих окон должна находиться надпись, которая поясняет, какой именно коэффициент вводится в то или иное окно. Таким образом, количество надписей в основном окне должно быть равно трем. Ниже текстовых окон для ввода исходных данных должны находиться два текстовых окна для вывода решения (конечно, в том случае, если такое решение имеется). Над этими текстовыми окнами также должна располагаться поясняющая надпись.
Между окнами с исходными данными и окнами с результатами в основной форме расположите две экранные кнопки. Слева должна находиться кнопка, нажатие на которую приводит к решению уравнения. Назовите эту кнопку «Найти решение». Правее расположите кнопку «Сброс», щелчок на которой должен очищать как текстовые окна с исходными данными, так и текстовые окна с результатами. Эта кнопка должна имеет двоякое предназначение. Во-первых, она может понадобиться в том случае, если пользователь допустил ошибку при вводе исходных данных. Во-вторых, решение квадратного уравнения при других значениях коэффициентах.
Для того, чтобы немного оживить программу, вставим в форму иллюстрация юмористического характера, в правой части окна. Рис 1.
1. Измените заголовок формы на «Решение квадратного уравнения». Кроме этого, измените цвет формы, сделав его бледно-зеленым.
2. Создайте три текстовых окна Edit1, Edit2 и Edit3 для ввода исходных данных. В окнах недолжно быть информации, для этого свойства Text должно быть очищено. Шрифт полужирным и равным 10 пунктам (свойство Font).
3. Создайте окна Label1, Label2 и Label3 соответствующими надписями «Введите коэффициент» (свойство Caption) расположите около текстовых окон. Шрифт (свойство Font) измените, сделав его полужирным и увеличив его размер до 10 пунктов.
4 Создайте два текстовые окна Edit4 и Edit5, которые будут использоваться для вывода корней уравнения x1 и х2. Настройте эти объекты аналогично предыдущим. Так как ответ может быть как числовой так и текстовой, то изначально эти окна необходимо спрятать. Для свойства Visible установите значение False (ложно).
5. Надпись Label4 должна содержать информацию об итогах решения уравнения (как при наличии корней, так и при их отсутствии). Поскольку эта надпись в любом случае должна появляться только после ввода исходных данных и щелчке на кнопке «Найти решение», сделайте ее изначально невидимой. (Свойство Visible данного объекта должно быть False). Заголовок данной надписи измените на «корни уравнения», а шрифт заголовка сделайте полужирным и равным 10 пунктам. При отсутствии решения заголовок надписи будет иным, но соответствующее изменение заголовка производятся при написании программного кода.
6. Между верхней и нижней группой надписей расположите две экранные кнопки: Button1 и Button2. Для кнопки Button1 измените заголовок на «найти решение». Размеры кнопки увеличьте таким образом, чтобы данный заголовок был полностью виден. Шрифт заголовка сделайте полужирным и равным 12 пунктам. Аналогичные настройки шрифта произведете и для расположенной правее кнопки Button2. Заголовок на этой кнопки «сброс».
7. Для размещения иллюстрации воспользуйтесь объектом Panel1 щелкнув на кнопке панели Standard и растяните его справа от созданных ранее объектов. Свойство Caption очистите.
8. В объект Panel1 поместите объект Image1. щелкнув на кнопке панели Additional, при этом совместите верхний левый угол объекта Image1 с левым верхним углом фоновой панели Panel
9. Выделите в окне формы объект Image1. В инспекторе объектов свойство Tор установите значение 2. Данное свойство определяет положение рисунка относительно верха панели, на которой он расположен (верх рисунка будет на два пиксела ниже верха панели, для того чтобы не закрывать фаску).
10. В инспекторе объектов свойство Left установите значение 2. Данное свойство определяет положение рисунка относительно левого края панели, на которой он расположен.
11. Задержать указатель мыши на панели Panel1 на несколько секунд. В появившемся небольшом окне будут отображены основными характеристиками объекта, включая и его размеры. В этом окне будет информация следующего вида:
12. На форме объект image1 свойства width (ширина) устанавите значение 237 (на 4 меньше чем окно Panel1), а для свойства Height (высота) значение 341.
13. Свойство stretch (растянуть) установите TRUE. При данном значении произойдет автоматическая подгонка рисунка под размеры Panel1.
14 Нажмите на слово Image1 свойств Name. В открывшемся диалоговом окне Picture Editor нажми кнопу Load и выберите картинку.
15. Нажмите 2 раза на объекте «Найти решение» (кнопка Buttonl). В процедуре TForml.Buttonlciick. опишите следующие переменные: а, b и с, для дискриминанта d, и для хранения полученных корней уравнения xl и х2. Исходные данные и результаты имеют вещественные значения тип real:
var a,b,c,d,xl,x2:real;
16. В основной части процедуры произведите преобразование вводимых в текстовые окна исходных данных строковых величин в соответствующие им числовые величины вещественного типа. Это преобразование осуществляется с помощью стандартной функции StrtoFloat:
a:=StrtoFloat(Edit1.Text);
b:=StrtoFloat(Edit2.Text);
c:=StrtoFloat(Edit3.Text);
17. Вычислите дискриминанта с помощью полученных в результате преобразования вещественных величин:
d:=sqr(b)-4*a*c;
Дальнейший ход решения задачи зависит от вычисленного значения дискриминанта. Если дискриминант неотрицателен, то необходимо произвести следующие действия:
1. Вычислить по известным формулам корни уравнения X1 и X2.
2. Сделать видимыми текстовые окна Edit4 и Edits, в которых будут выведены вычисленные корни.
3. Преобразовать полученные вещественные корни с помощью стандартной функции Fioattostr в текстовые величины, годные для вывода в текстовых окнах.
4. Вывести надпись, поясняющую полученные результаты, предварительно сделав ее видимой.
Вся перечисленная последовательность действий может быть реализована в программе с помощью следующих операторов:
x1:=(-b-sqrt(d))/(2*a);
x2:=(-b+sqrt(d))/(2*а);
Edit4.Text:= FloattoStr (xl);
Edit4.Visible:=True;
Edit5.Text:=FloattoStr(x2);
Edit5.Visible:=True;
Label4.Visible:=True;
Label4.Caption:='Kopни уравнения'
В том случае если найденный дискриминант отрицателен, требуемые действия сводятся к тому, чтобы:
1. Вывести на экран надпись, говорящую об отсутствии решения уравнения, сделав надпись перед этим видимой.
2. Сделать невидимыми текстовые окна для вывода результатов, т. к. в этом случае необходимость в них отсутствует.
Перечисленные действия реализуются с помощью операторов:
Label4.Visible:=True;
Label4.Caption:='ypaвнение не имеет решения';
Edit4.Visible:=False;
Edit5.Visible:=False
В целом условный оператор будет выглядеть следующим образом:
if d>=0 then
begin
xl:=(-b-sqrt(d))/(2*a);
x2:=(-b+sqrt(d))/(2*a);
Edit4.Text:=FloattoStr(xl);
Edit4.Visible:=True;
Edit5.Text:=FloattoStr(x2);
Edit5.Visible:=True;
Label4.Visible:=True;
Label4.Caption:='Корни уравнения'
end
else
begin
Label4.Visible:=True;
Label4.Caption:='Уравнение не имеет решения';
Edit4.Visible:=False;
Edit5.Visible:=False
end
Процедура в целом будет выглядеть так:
procedure TForml.ButtonlClick(Sender: TObject);
var a,b,c,d,xl,x2:real;
begin
a:=StrtoFloat(Editl.Text);
b:=StrtoFloat(Edit2.Text);
c:=StrtoFloat(Edit3.Text);
d:=sqr(b)-4*a*c;
if d>=0 then
begin
xl:=(-b-sqrt(d))/(2*a);
x2:=(-b+sqrt(d))/(2*a);
Edit4.Text:=FloattoStr(xl);
Edit4.Visible:=True;
Edit5.Text:=FloattoStr(x2);
Edit5.Visible:=True;
Label4.Visible:=True;
Labe14.Capti on: ='Корни уравнения'
end
else
begin
Label4.Visible:=True;
Label4.Caption:='Уравнение не имеет решения';
Edit4.Visible:=False;
Edit5.Visible:=False
end
end;
18. В процедуре Сброс (кнопка Button2), опишите реакцию на нажатие этой экранной кнопки. Двойное нажатие приведет к открытию TFormi.Button2ciick в которой должны быть выполнены следующие действия:
1. Очистка текстовых окон, в которые вводятся исходные данные.
2. Превращение окон с результатами и поясняющей надписи в невидимые окна.
В итоге процедура будет выглядеть следующим образом:
procedure TForml.Button2Click(Sender: TObject);
begin
Edit1.Text:='';
Edit2.Text:=" ;
Edit3.Text:='';
Edit4.Visible:=False;
Edit5.Visible:=False;
Label4.Visible:=False
end;
19. Двойное нажатие на клавишу «Выход» откроет процедуру TForml.Button3Click(Sender: TObject).
В которой следует записать только одну команду Close.
Цель: Познакомится с объектом Memo. Изучить объект меню и научиться создавать меню.
Создадим программу вычисления факториала числа. Дайте новому проекту название Faktorial. Работу над проектом начинаем с создания и сохранения графического интерфейса программы. Интерфейс будет включать в себя следующие основные компоненты:
• строка меню, содержащая разделы Файл и Справка;
• текстовое окно для ввода исходных данных, слева от которого будет расположено поле комментария, поясняющее содержание данного окна;
• кнопка «Ввод», нажатие которой должно приводить к вычислению искомого результата;
• текстовое окно с результатом, дополненное поясняющей надписью;
• экранная кнопка «Сброс», используемая для очистки текстовых окон, и кнопка «Выход», используемая для закрытия окна программы;
• панель с рисунком юмористического содержания.
Начнем работу над интерфейсом с создания строки меню.
1. Найдите на панели компонентов вкладке Standard компонент MainMenu, который имеет иконку . Выделите данный компонент, щелкнете мышью в верхней части формы, в результате чего такой же значок появляется на форме, т. е. получили заготовку для создания будущего меню.
2. Для заполнения меню разделами и пунктами дважды щелкните значок (расположенный в форме), в результате чего на экране компьютера появляется диалоговое окно Form1.MainMenu 1. Это диалоговое окно используется для создания разделов и пунктов будущего меню.
3. Для создания первого раздела меню щелкните в окне инспектора объектов справа от свойства caption.
4. Ввести название раздела (Файл) и подтвердить ввод нажатием клавиши Enter. В диалоговом окне Forml.MainMenul, появиться пункт с именем Файл. В списке объектов проекта появился новый объект с именем N1 созданный раздел меню. Справа от раздела Файл появилась заготовка для создания следующего раздела меню.
5. Выделите эту заготовку. В окне инспектора в свойстве Caption, введите название нового раздела (Справка). Получится еще один раздел меню с именем N2.
Теперь необходимо дополнить существующие разделы соответствующими пунктами.
6. Чтобы добавить пункт в раздел «Файл», нужно выделить раздел «файл» и щелкнуть мышью заготовку, расположенную снизу от слова «Файл». Затем щелкнете свойство Caption, введите имя раздела «Выход» Получится в проекте еще один объект с именем N3.
7. Аналогичным образом в разделе меню Справка создайте пункт «Об авторах». Этот пункт становится объектом по имени N4.
8. Закройте диалоговое окно Forml.MainMenul. На этом создание графического интерфейса строки меню завершается.
9. Поместите и настройте необходимые элементы программы, разместив их в форме программы по следующему образцу.
10. Присвойте форме заголовок (Факториал) и измените цвет формы на светло-зеленый.
11. Создайте компонент формы текстовое окно Editi. Слева от него расположите окно комментария Memo1 . Для того чтобы данное окно не выделялось на общем фоне формы цвет окна сделайте светло-зеленым, как и у самой формы, а свойству Borderstyle присвойте значение None, т. е. границу делаем невидимой. Текст поля Memo1 вводится в окне StringList Editir, которое вызывается двойным кликом около команды Lines.
12. Под текстовым окном расположите экранную кнопку (объект Buttonl), которой присвойте заголовок «Ввод».
13. Под кнопкой «Ввод» расположите второе текстовое окно для вывода результатов (объект Edit2), а слева от него надпись о содержимом данного окна (объект Label1)
14. Внизу экрана расположите две экранные кнопки. Это кнопка «Сброс» (объект Button2) и кнопка «Выход» (объект Button3). Назначение этих кнопок следует из их заголовков.
15. В правой части формы разместите объект Panel1, а на этом объекте поместите иллюстрацию (объект image1).
16. Создайте вспомогательную форму со сведениями о себе и программе и создайте ее интерфейс. На этом создание графического интерфейса программы завершается (рис. 1).
Следующий этап работы над программой является написание кода для пунктов меню и экранных кнопок.
1. Пункт меню N3 закрывает окно формы, поэтому соответствующий код будет содержать только оператор close. Для пункта меню N4 нужно написать оператор Form2.show, который выводит на экран компьютера дополнительную форму со сведениями об авторе и программы. При этом нужно предварительно создать новую форму с помощью раздела меню системы программирования File | New (Файл | Новый), а также описать подключение дополнительного модуля для этой формы Unit2 в разделе основного модуля unit1, который начинается со служебного слова uses.
2. Написание кода для пунктов меню следует производит так же, как и для прочих объектов. Для напоминания вначале выделяется объект (например, пункт меню N3, с помощью которого программа закрывается), затем выбирается вкладка Events (События) в инспекторе объектов. На вкладке находится событие onclick. Дважды щелкается мышью в поле справа от названия события. Автоматически открывается соответствующую процедуру, которая для пункта N3 будет называться TForml.N3click. Для закрытия программы в процедуру нужно вставить единственную команду close, а процедура целиком будет выглядеть так:
procedure TForml.N3Click(Sender: TObject);
begin
close
end;
Далее самостоятельно напишите коды для всех объектов. Тексты процедур приводятся ниже
procedure TForml.N4Click(Sender: TObject);
begin
Form2.Show
end;
procedure TForml.ButtonlClick(Sender: TObject);
var i,f,n:integer;
begin
n:=StrtoInt(Editl.Text);
f:=l;
for i:=l to n do
f:=f*i;
Edit2.Text:=InttoStr(f)
end;
Далее самостоятельно процедуры Объекта кнопки «Сброс» и кнопки «Выход»
Задание. Использование циклических структур программа "Вклад". С помощью данного проекта вкладчик, положивший деньги в банк, сможет рассчитать, какую сумму он должен получить по окончании срока действия договора с банком, если по условиям договора вклад положен в банк на определенное количество лет под определенный процент, который не должен изменяться до окончания срока действия договора.
Таким образом, данный проект должен иметь в качестве входных параметров начальную сумму вклада, срок действия договора (для упрощения решения поставленной задачи мы считаем, что количество лет, в течение которых будет действовать договор, является целым числом) и процент по вкладу. Выходным параметром данного проекта будет сумма вклада, накопившаяся после окончания договора. Исходя из сказанного интерфейсе программы должен включать в себя следующие элементы:
Создание графического интерфейса программы мы, начинается с разработки формы. Для этого Цвет формы стандартный бледно-зеленый цвет. Заголовок формы «Банк». В форме создаем три текстовые окна Editl, Edit2 и Edit3 для ввода исходных данных. Над каждым из окон для надписей, создайте три объекта Label1, Label2 и Label3. Под окнами ввода расположите две экранные кнопки: Button1 и Button2. Первая используется для подтверждения ввода исходных данных «Ввод», а вторая для очистки текстовых окон «Очистить».
Ниже в форме расположите два текстовых окна Edit4 и Edit5, которые будут использоваться для вывода результатов. Окно Edit4 отображает количество получаемых вкладчиком рублей, а окно Edit5 копеек. Над кнопками расположите общую пояснительную надпись, которая реализуйте в виде окна комментария Memo1. Справа от каждого из двух текстовых окон расположите небольшие надписи, указывающей единицу измерения для данного окна (объекты Label4 и Label5).
В правой верхней части формы расположите иллюстрацию к проекту в виде рисунка (объекты Panel1 и image1). В нижней правой части формы будет расположите кнопку «Выход» (Button3), которая закрывает форму и завершает работу всего проекта.
Создание программного кода начнем с написания процедуры для экранной кнопки «Ввод» (Buttonl). В данной процедуре мы будем использовать ряд локальных переменных целого и вещественного типа. К целому типу относятся:
переменная srok количество лет, на которые заключается договор,
rub количество рублей, которое должен получить клиент банка по окончании срока действия договора,
кор количество копеек, которое должен получить клиент,
i вспомогательная переменная цикла.
К вещественному типу относятся:
vki общая сумма вклада,
pro проценты по вкладу,
drob и drobl вспомогательные переменные.
В начале работы процедуры преобразуйте содержимое текстового окна с указанием суммы вклада (Editl) в вещественную величину vki, содержимое окна Edit2 с указанием срока действия договора в целую величину srok, содержимое окна Edit3 с указанием процентов по вкладу в вещественную переменную pro. Преобразование выполняется следующими операторами:
vkl:=StrtoFloat(Editl.Text);
srok:=StrtoInt(Edit2.Text);
pro:=StrtoFloat(Edit3.Text);
Далее в процедуре вычислите общую сумму вклада по окончании срока действия договора, для чего используйте оператор с заранее известным числом повторений. При каждом повторении тела цикла высчитывается прибавка к вкладу за очередной год, для чего сумма, накопившаяся за предыдущий год, умножается на процент по вкладу и делится на 100. Затем получившаяся прибавка добавляется к сумме за прошедший год. Указанные действия реализуйте в процедуре следующим образом:
for i:=l to srok do
vkl:=vkl+vkl*pro/100 ;
В полученной таким образом общей сумме вклада необходимо вначале выделить целое количество рублей. Для этой цели используем стандартную фунцию trunc, которая находит целую часть числа, отбрасывая дробную. Получившуюся величину нужно преобразовать из числовой в строковую, а затем это строковое значение присвоить текстовому окну Edit:
rub:=trunc(vkl);
Edit4.Text:=InttoStr(rub);
Из целой части вклада вычитаем количество рублей, получаем дробную часть drb, соответствующую количеству копеек. Для того чтобы преобразовать величину drb в количество копеек, нужно умножить эту величину на 100, значение переменной drbi. Найденное количество копеек переменная drbi, содержит целую и дробную часть. Для выделения целого числа копеек кор, используют функцию round, которая округляет вещественную величину до ближайшего целого по математическим правилам. Эти действия описываются с помощью следующих операторов:
drb:=vkl-rub;
drbi:=drb*100;
kop:=round(drbi);
Целиком же процедура, описывающая работу кнопки Button1, будет выглядеть следующим образом:
procedure TForml.ButtonlClick(Sender: TObject);
var i,srok,rub,kop:integer;
vkl,pro,drb,drbi:real;
begin
vkl:=StrtoFloat(Edit1.Text);
srok:=StrtoInt(Edit2.Text);
pro:=StrtoFloat(Edit3.Text);
for i:=l to srok do
vkl:=vkl+vkl*pro/100;
rub:=trune(vkl);
Edit4.Text:=InttoStr(rub);
drb:=vkl-rub;
drbl:=drb*100;
kop:=round(drbi);
Edit5.Text:=InttoStr(kop)
end;
Процедуру для кнопки Button2, которая очищает при сбросе все текстовые окна, и процедуру для кнопки Button3, которая закрывает окно программы написать самостоятельно. В целом же программный модуль будет выглядеть следующим образом:
Листинг 16.2. Текст программы "Вклад" !
unit Unitl;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls?????????
?????????????????????????????
?????
??????????????????????
????????????????
????????????????
????????????????
??????????????
????????????????
??????????????
????????????????
??????????????
??????????????
??????????????????
??????????????
??????????????????
??????????????????
????????????????
??????????????
????????????????
?????????????????????????????????????????
?????????????????????????????????????????
?????????????????????????????????????????
????????
?????????????????????????
???????
????????????????????????
?????
????
???????????????
???????????????
???????????
????????????????????????????????????????????????
????????????????????????????
???????????????????????
???????
?????????????????????????????
????????????????????????????
?????????????????????????????
????????????????????
??????????????????????
?????????????????
???????????????????????????
??????????????
???????????????
???????????????????
??????????????????????????
?????
????????????????????????????????????????????????
??????
??????
?????
????????????????????????????????????????????????
??gin
Editl.Text:=;
Edit2.Text:=;
Edit3.Text:=;
Edit4.Text:=;
Edit5.Text:=
end;
end.
Результат работы программы для клиента, который положил 5000 рублей банк сроком на 3 года под 15%, показан на рис. 16.4.
1 Этап. Работу над проектом начинаем с создания визуального интерфейса приложения.
1. Откройте новую форму. Свойство Caption:='Калькулятор'. Name := TMainF; Установите на форму компонент Edit. Установите значения следующих свойств:
Enabled:=False; для предотвращения ввода символов которые не могут присутствовать в числе;
Name := NumEd;
2. Поместите на форму компонент Panel, для логического объединения компонентов в группы. Придайте установленному компоненту объемный вид свойства:
BevelInner bvLowered
BevelOuter bvRaised.
bevelWidth :=1;
borderStyle:=bsSingle;
3. Поместите на панель 5 компонентов Button. Для этого удерживая клавишу Shift, щелкните на компоненте Button в палитре компонент компонент выделится. Щелкните на панели пять раз. Должно появиться 5 кнопок.
4. Установите размер кнопок, равный 50 пикселей по ширине и 40 по высоте. Выделите все помещенные на панель кнопки. Выполните команду Size меню Edit. В появившемся диалоговом окне Size установите размер объектов.
примечание. Значение No Change - не изменяет размеров объектов;
Shrink to smallest - выравнивает размер по ширине (высоте) наименьшего из выделенных объектов;
Grow to Largest - выделенных объектов;
Width (Height) - устанавливает ширину (высоту) отмеченных объектов в указанных значениях.
5. Выравните кнопки по верхней стороне относительно друг друга выполнив команду Align... меню Edit.
примечание. Значение No Change - не изменяет выравнивание компонентов;
Left sides (Right sides, Tops, Button) - выравнивает левые (правые, верхние, нижние) границы выделенных компонентов;
Space equally располагает компоненты на равном расстоянии друг от друга;
Center in widdows выравнивает компоненты по центру формы;
Centers выравнивает центры компонентов.
6. Скопируйте выделенные пять кнопок в буфер обмена, выполнив команду Copy меню Edit. На панели Panel1 поместите еще пять кнопок, для этого выделите компонент Panel1 и выполните команду Paste меню Edit. Не снимая выделения, разместите эти кнопки как показано на рис.
7. В нижней части формы разместите еще один компонент Panel. На котором разместите семь компонентов Button. Выравнивание компонентов как описано выше.
8. Измените свойства Caption и Name в соответствии с таблицей.
Caption |
Name |
Caption |
Name |
Caption |
Name |
0 |
ZBt |
5 |
FivBt |
+ |
AddBt |
1 |
OBt |
6 |
SBt |
- |
SubBt |
2 |
TwBt |
7 |
SevBt |
* |
MulBt |
3 |
TBt |
8 |
EBt |
Div |
DivBt |
4 |
FBt |
9 |
NBt |
mod |
ModBt |
= |
EqBt |
C |
ClBt |
9. Измените шрифт установленных объектов, для этого выделите все компоненты и измените значение свойства Font.
2 этап. Создание программного кода.
10. При нажатии на клавиши «0», «1». и т.д. формируется число к содержимому окна редактирования справа добавляется цифра, отображенная на кнопке. Создайте обработчик события OnClik копки OneBn:
procedure TMainF.OneBnClik (Sender:TObject );
begin
NumFd.text:=NumFd.Text + OneBn.Caption;
end;
11. При щелчке на любой из оставшихся 9 кнопок происходит то же самое действие. Чтобы не писать много одинаковых процедур обобщим выше написанный обработчик событий.
procedure TMainF.OneBnClik (Sender:TObject );
begin
NumFd.text:=NumFd.Text + (sender as Tbutton).Caption;
end;
Для справки параметр Sender представляет объект который получил сообщение, например, при нажатии на клавишу «1» параметр Sender. несмотря на указанный в заголовке типа Tobject, является ссылкой на объект OneBn типа Tbutton. Оператор As используется для приведения объектных типов, т.е. параметр Sender будет преобразован к типу TВutton.
Таким образом, если после щелчка на кнопке TwoBt обратиться к методу-обработку, то значение (Senter as Tbutton).Caption будет равняться «2». Чтобы связать этот обработчик события с обработкой события OnClik компонента TwoBt, необходимо в левом столбце Инспектора объектов компонента TwoBt из списка методов-обработчиков событий события OnClik выбрать OneBtClik. Выполните аналогичные действия для каждой из оставшихся 8 кнопок.
12. При щелчке на кнопках «+, -, *, Div, Mod» необходимо запомнить первый операнд арифметического выражения и знак операции. Введите переменную op1 типа Integer для хранения значения первого операнда и опишите ее в разделе private класса TMainF.
13. Для определения арифметической операции (знака) воспользуемся свойством Tag. Каждый компонент обладает свойством Tag, назначение которого устанавливается программистом. Воспользуемся этим свойством для запоминания (определения) знака арифметической операции. Установите значение свойства Tag компонентов в соответствии с таблицей
Name |
Tag |
AddBt |
1 |
SubBt |
2 |
MulBt |
3 |
DivBt |
4 |
ModBt |
5 |
14. При выборе знака действия запомните Tag соответствующей кнопки в свойстве Tag формы. Обработчик события OnClik компонента AddBt приобретет вид:
procedure TMainF.AddBtClik (Sender:TObject );
begin
Op1:=StrtoInt(NumEd.Text);
NumEd.text:='';
Tag:=(Sender as TButton).Tag
end;
15. Соедините данный обработчик события с обработчиками событий OnClik оставшихся четырех знаков действий.
16. При нажатии на клавишу «=» вычисляется результат арифметических операций:
procedure TMAinF.EgBtClik(Sender:TObject);
var Op2,res :integer;
begin
op2:=StrtoInt(numed.Text);
case tag of
1: res:=op2+op2;
2: res:=op1 - op2;
3: res:=op1 * op2;
4: res:=op1 div op2;
5: res:=op1 mod op2;
end;
NumEd.Text:=IntToStr(res);
end;
17. Напишите процедуру очисти окна редактора при нажатии на клавишу «С».
18. Написанная программа реагирует на манипулятор мышь. Внесем изменения в программный код чтобы калькулятор мог реагировать на клавиатуру. Для того чтобы послать события клавиатуры сначала форме, а потом активному компоненту следует установить свойство формы KeyPreview равным True. Это может обезопасить пользователя от введения ошибочных символов.
19. Создайте обработчик события OnKeyPress формы:
procedure TMainF.FormKeyPress(Sender: TObject; var Key: Char);
begin
case key of
'0'..'9' :NumEd.Text:=NumEd.Text+key;
'+' :AddBt.Click;
'=' :EqBt.Click;
end;
end;
Допишите обработчик событий OnKeyPress.
Вы узнаете о том, какие возможности есть в Delphi для создания приложений, использующих графику; как использовать компоненты для отображения картинок; какие средства есть в Delphi для оформления программы. Кроме того, познакомитесь с важным свойством Canvas, которое предоставляет доступ к графическому образу объекта на экране.
Графические компоненты
В стандартную библиотеку визуальных компонент Delphi входит несколько объектов, с помощью которых можно придать своей программе совершенно оригинальный вид. Это - TImage (TDBImage), TShape, TBevel.
TImage позволяет поместить графическое изображение в любое место на форме. Этот объект очень прост в использовании - выберите его на странице Additional и поместите в нужное место формы. Собственно картинку можно загрузить во время дизайна в редакторе свойства Picture (Инспектор Объектов). Картинка должна храниться в файле в формате BMP (bitmap), WMF (Windows Meta File) или ICO (icon). (TDBImage отображает картинку, хранящуюся в таблице в поле типа BLOB. При этом доступен только формат BMP.)
При проектировании следует помнить, что изображение, помещенное на форму во время дизайна, включается в файл .DPR и затем прикомпилируется к EXE файлу. Поэтому такой EXE файл может получиться достаточно большой.
Важными являются свойства объекта Center и Stretch - оба имеют булевский тип. Если Center установлено в True, то центр изображения будет совмещаться с центром объекта TImage. Если Stretch установлено в True, то изображение будет сжиматься или растягиваться таким образом, чтобы заполнить весь объект TImage.
TShape - простейшие графические объекты на форме типа круг, квадрат и т.п. Вид объекта указывается в свойстве Shape. Свойство Pen определяет цвет и вид границы объекта. Brush задает цвет и вид заполнения объекта. Эти свойства можно менять как во время дизайна, так и во время выполнения программы.
TBevel - объект для украшения программы, может принимать вид рамки или линии. Объект предоставляет меньше возможностей по сравнению с TPanel, но не занимает ресурсов. Внешний вид указывается с помощью свойств Shape и Style.
Объект Canvas
У ряда объектов из библиотеки визуальных компонент есть свойство Canvas (канва), которое предоставляет простой путь для рисования на них. Эти объекты - TBitmap, TComboBox, TDBComboBox, TDBGrid, TDBListBox, TDirectoryListBox, TDrawGrid, TFileListBox, TForm, TImage, TListBox, TOutline, TPaintBox, TPrinter, TStringGrid. В свою очередь, свойство canvas это объект типа TCanvas. Методы этого типа обеспечивают вывод графических примитивов (точек, линий, окружностей, прямоугольников и т. д.), а свойства позволяют задать характеристики выводимых графических примитивов: цвет, толщину и стиль линий; цвет и вид заполнения областей; характеристики шрифта при выводе текстовой информации.
Методы вывода графических примитивов рассматривают свойство Canvas как некоторый абстрактный холст, на котором они могут рисовать (canvas переводится как "поверхность", "холст для рисования"). Холст состоит из отдельных точек пикселов. Положение пиксела характеризуется его горизонтальной (X) и вертикальной (Y) координатами. Левый верхний пиксел имеет координаты (0, 0). Координаты возрастают сверху вниз и слева направо (рис. 10.1). Значения координат правой нижней точки холста зависят от размера холста. Размер холста можно получить, обратившись к свойствам Height и width области иллюстрации (image) или к свойствам формы: ClientHeight и Clientwidth.
Canvas является в свою очередь объектом, объединяющим в себе поле для рисования, карандаш (Pen), кисть (Brush) и шрифт (Font). Canvas обладает также рядом графических методов : Draw, TextOut, Arc, Rectangle и др. Используя Canvas, Вы можете воспроизводить на форме любые графические объекты - картинки, многоугольники, текст и т.п. без использования компонент TImage,TShape и TLabel (т.е. без использования дополнительных ресурсов), однако при этом Вы должны обрабатывать событие OnPaint того объекта, на канве которого Вы рисуете. Рассмотрим подробнее свойства и методы объекта Canvas.
Методы вычерчивания графических примитивов
Любая картинка, чертеж, схема могут рассматриваться как совокупность графических примитивов: точек, линий, окружностей, дуг и др. Таким образом, для того чтобы на экране появилась нужная картинка, программа должна обеспечить вычерчивание (вывод) графических примитивов, составляющих эту картинку.
Вычерчивание графических примитивов на поверхности компонента (формы или области вывода иллюстрации) осуществляется применением соответствующих методов к свойству Canvas этого компонента.
Рассмотрим часть методов, при помощи которых можно создавать простые рисунки.
Arc метод Arc рисует дугу окружности или эллипса с помощью текущих параметров пера Pen (эти параметры мы рассмотрим чуть ниже). Точки (x1,y1) и (x2,y2) определяют прямоугольник, описывающий эллипс. Начальная точка дуги определяется пересечением эллипса с прямой, проходящей через его центр и точку (x3,y3). Конечная точка дуги определяется пересечением эллипса с прямой, проходящей через его центр и точку (x4,y4). Дуга рисуется против часовой стрелки от начальной до конечной точки.
Формат метода: Arc(x1,y1,x2,y2,x3,y3,x4,y4: Integer)
Пример.
Image1.Canvas.Arc(0,0, 200,200, 200,0, 0,0);
Image2.Canvas.Arc(0,0, 200,200, 0,0, 200,0);
Chord метод Chord рисует заполненную замкнутую фигуру, ограниченную дугой окружности или эллипса и хордой, с помощью текущих параметров пера Pen. Фигура заполняется текущим значением Brush (рассмотрим чуть ниже). Точки (x1,y1) и (x2,y2) определяют прямоугольник, описывающий эллипс. Начальная точка дуги определяется пересечением эллипса с прямой, проходящей через его центр и точку (x3,y3). Конечная точка дуги определяется пересечением эллипса с прямой, проходящей через его центр и точку (x4,y4). Дуга рисуется против часовой стрелки от начальной до конечной точки. Хорда соединяет точки(x3,y3) и (x4,y4).
Формат метода: Chord (x1,y1,x2,y2,x3,y3,x4,y4:Integer);
Пример
Image1.Canvas.Chord(0,0, 200,200, 200,0, 0,0);
Image2.Canvas.Chord(0,0, 200,200, 0,0, 200,0);
Draw Метод Draw рисует изображение, содержащееся в объекте, указанном параметром Graphic, сохраняя исходный размер изображения в его источнике и перенося изображение в область канвы объекта TCanvas, верхний левый угол которой определяется параметрами x и y. Источник изображения может быть битовой матрицей, пиктограммой или метафайлом.
Формат метода: Draw (x,y:Integer;Graphic:TGraphic);
Пример.
Form1.Canvas.Draw(10,10,Bitmap1);
Рисует на канве формы Form1 изображение из компонента Bitmap1 в область с координатами левого верхнего угла (10,10).
Ellipse метод Ellipse рисует окружность или эллипс с помощью текущих параметров пера Pen. Фигура заполняется текущим значением Brush. Точки (x1,y1) и (x2,y2) определяют прямоугольник, описывающий эллипс.
Формат метода: Ellipse (x1,y1,x2,y2:Integer);
Пример.
With Image1.Canvas do //в операторных скобках перед каждой строкой добавляет Image1.Canvas.
Begin
Brush.Color := clRed;
Brush.Style := bsDiagCross;
Ellipse(0, 0, Image1.Width, Image1.Height);
End;
FillRect Метод FillRect заполняет прямоугольник канвы, указанный параметром Rect, используя текущее значение Brush. Заполняемая область включает верхнюю и левую стороны прямоугольника, но не включает правую и нижнюю стороны.
Формат метода: FillRect(const: TRect);
Пример.
Image1.Canvas.FillRect(Rect(0,0,Width,Height));
Очищает всю канву компонента Image1, заполняя ее фоном, если он установлен в свойстве Brush.
FloodFill Метод FloodFill закрашивает текущей кистью Brush замкнутую область канвы, определенным цветом и начальной точкой закрашивания (x,y). Точка с координатами x и y является произвольной внутренней точкой заполняемой области, которая может иметь произвольную форму. Граница этой области определяется сочетанием параметров Color и FillStyle. Параметр Color указывает цвет, который используется при определении границы закрашиваемой области, а параметр FillStyle определяет, как именно по этому цвету определяется граница. Если FillStyle = fsSurface, то заполняется область, закрашенная цветом Color, а на других цветах метод останавливается. Если FillStyle = fsBorder, то наоборот, заполняется область окрашенная любыми цветами, не равными Color, а на цвете Color метод останавливается.
Type TFillStyle = (fsSurfase, fsBorder);
Procedure FloodFill (x,y:Integer;Color:TColor;FillStyle:TFillStyle);
Пример1.
With Image1.Canvas do
begin
Brush.Color:=clWhite;
FloodFill(X,Y,Pixels[X,Y],fsSurface);
End;
Приведенные операторы закрашивают белым цветом на канве компонента Image1 все пиксели, прилегающие к пикселю с координатами (x,y) и имеющие тот же цвет, что и этот пиксель.
Пример2.
With Image1.Canvas do
begin
Brush.Color:=clWhite;
FloodFill(X,Y,clBlack, fsBorder);
End;
Приведенные операторы закрашивают белым цветом на канве компонента Image1 все пиксели, прилегающие к пикселю с координатами (x,y) и имеющие цвет, отличный от черного. При достижении черной границы области закраска останавливается.
FrameRect Метод FrameRect рисует на канве прямоугольную рамку вокруг области Rect, используя установку текущей кисти Brush. Толщина рамки 1 пиксель. Область внутри рамки кистью не закрашивается. Отличается от метода Rectangle тем, что рамка рисуется цветом кисти (в методе Rectangle цветом пера Pen) и область не закрашивается (в методе Rectangle закрашивается).
Формат метода: FrameRect(const Rect:TRect);
Пример.
With Form1.Canvas do
Begin
Brush.Color:=clBlack;
FrameRect(Rect(10,10,100,100));
End;
Рисует на канве формы Form1 черную рамку.
LineTo Метод LineTo рисует на канве прямую линию, начинающуюся с текущей позиции пера PenPos и кончающуюся точкой (x,y). Текущая позиция пера PenPos перемещается и кончающуюся точкой (x,y), исключая саму точку (x,y). Текущая позиция пера PenPos перемещается в точку (x,y). При рисовании используются текущие установки пера Pen. Вид линии (цвет, толщина и стиль) определяется значениями свойств объекта Реп графической поверхности, на которой вычерчивается линия.
Формат метода: LineTo (x,y:Integer);
Пример.
Form1.Canvas.MoveTo(x1,y1);
Form1.Canvas.LineTo(x2,y2);
Form1.Canvas.LineTo(x3,y3);
Рисует кусочно-ломаную прямую, соединяющую точки (x1,y1), (x2,y2) и (x3,y3).
MoveTo Метод MoveTo изменяет текущую позицию пера на заданную точкой (x,y). Это эквивалентно непосредственной установке свойства PenPos. При перемещении пера методом MoveTo ничего не рисуется.
Формат метода: MoveTo(x,y:Integer);
Pie Метод Pie рисует замкнутую фигуру сектор окружности или эллипса, с помощью текущих параметров пера Pen. Фигура заполняется текущим значением Brush. Точки (x1,y1) и (x2,y2) определяют прямоугольник, описывающий эллипс. Начальная точка дуги определяется пересечением эллипса с прямой, проходящейчерез его центр и точку (x3,y3). Конечная точка дуги определяется пересечением эллипса с прямой, проходящей через его центр и точку (x4,y4). Дуга рисуется против часовой стрелки от начальной до конечной точки. Рисуются прямые, ограничивающие сегмент и проходящие через центр эллипса и точки (x3,y3) и (x4,y4).
Формат метода: Pie (x1,y1,x2,y2,x3,y3,x4,y4:Longint);
Пример.
Image1.Canvas.Pie(0,0, 200,200, 200,0, 0,0);
Image2.Canvas.Pie(0,0, 200,200, 0,0, 200,0);
Polygon Метод Polygon рисует на канве замкнутую фигуру (полигон, многоугольник) по множеству угловых точек, заданному массивом Points. Первая из указанных точек соединяется прямой с последней. Этим метод Polygon отличается от метода Polyline, который не замыкает конечные точки. Рисование проводится текущим пером Pen. Внутренняя область фигуры закрашивается текущей кистью Brush.
Формат метода: Polygon (Points: array of TPoint);
Пример1
Form1.Canvas.Polygon([Point(10,10),Point(30,10),Point(130,30),Point(240, 120)]);
Рисует на канве формы четырехугольник по точкам, заданным функциями Point.
Пример2
Form1.Canvas.Polygon(PointArray);
Рисует на канве формы многоугольник по точкам, хранящимся в массиве PointArray, который может быть объявлен, например, следующим образом:
Var PointArray:array[1..100] of TPoint;
Пример3
Form1.Canvas.Polygon(Slice(PointArray, 10));
Рисует на канве формы многоугольник по первым 10 точкам, хранящимся в массиве PointArray из предыдущего примера.
Polyline Метод Polyline рисует на канве кусочно-линейную кривую по множеству точек, заданному массивом Points. Отличие метода Polyline от метода Polygon заключается в том, что метод Polygon замыкает конечные точки, а метод Polyline нет. Рисование проводится текущим пером Pen. Метод не изменяет текущей позиции PenPos пера Pen.
Формат метода: Polyline(Points: array of TPoint);
Метод позволяет рисовать кусочно-линейный график функции, хранящийся в массиве типа TPoint. Если желательно использовать для рисования только часть точек массива, это можно сделать с помощью функции Slice. Если надо нарисовать кривую всего по нескольким точкам, то передавать их в метод Polyline удобно с помощью функции Point.
Пример
Form1.Canvas. Polyline([Point(10,10),Point(30,10),Point(130,30),Point(240, 120)]);
Рисует кусочно-линейную кривую по четырем точкам, заданным функциями Point.
Rectangle метод Rectangle рисует на канве текущим пером Pen прямоугольник, верхний левый угол которого имеет координаты (x1,y1), а нижний правый (x2,y2). Прямоугольник закрашивается текущей кистью Brush. Рисование прямоугольника без рамки можно осуществить методом FillRect.
Формат метода: Rectangle(x1,y1,x2,y2:Integer);
Пример
Image1.Canvas.Rectangle(10,10,210,110);
RoundRect метод RoundRect рисует на канве прямоугольную рамку со скругленными углами, используя текущие установки пера Pen и заполняя площадь фигуры текущей кистью Brush. Рамка определяется прямоугольником с координатами углов (x1,y1) и (x2,y2). Углы скругляются с помощью эллипсов с шириной x3 и высотой y3.
Формат метода: RoundRect(x1,y1,x2,y2,x3,y3:Integer);
Если задать ширину эллипса x3 x2-x1, то верхняя и нижняя границы рамки окажутся целиком скругленными (без прямолинейной части). Если y3 y2-y1, то же самое произойдет с левой и правой границами рамки. Если же оба измерения эллипса не меньше размеров рамки, то будет рисоваться просто эллипс. Но, конечно, для рисования эллипса лучше использовать метод Ellipse. Если один из размеров эллипса задать нулевым, то будет рисоваться прямоугольная рамка, а для получения такой рамки лучше использовать метод Rectangle.
Пример.
with Image1.Canvas do
begin
RoundRect(10,10,110,210,50,100);
RoundRect(160,10,260,210,100,100);
RoundRect(310,10,410,210,50,200);
RoundRect(460,10,560,210,100,200);
end;
Методы для вывода картинок на канву - Draw и StretchDraw, В качестве параметров указываются прямоугольник и графический объект для вывода (это может быть TBitmap, TIcon или TMetafile). StretchDraw отличается тем, что растягивает или сжимает картинку так, чтобы она заполнила весь указанный прямоугольник (см. пример к данному уроку).
Вывод текста
Для вывода текста на поверхность графического объекта используется метод TextOut. Инструкция вызова метода TextOut в общем виде выглядит следующим образом:
Объект.Canvas.TextOut(x, у, Текст)
где:
Рис. 10.3. Координаты области вывода текста |
Шрифт, который используется для вывода текста, определяется значением свойства Font соответствующего объекта canvas. Свойство Font представляет собой объект типа TFont. В табл. 10.7 перечислены свойства объекта TFont, позволяющие задать характеристики шрифта, используемого методами TextOut и TextRect для вывода текста.
Таблица 10.7. Свойства объекта TFont
Свойство |
Определяет |
||
Name |
Используемый шрифт. В качестве значения следует использовать название шрифта, например Arial |
||
Size |
Размер шрифта в пунктах (points). Пункт это единица измерения размера шрифта, используемая в полиграфии. Один пункт равен 1/72 дюйма |
||
Style |
Стиль начертания символов. Может быть: нормальным, полужирным, курсивным, подчеркнутым, перечеркнутым. Стиль задается при помощи следующих констант: fsBold (полужирный), fsltalic (курсив), f sUnderline (подчеркнутый), f sStrikeOut (перечеркнутый). |
Область вывода текста закрашивается текущим цветом кисти. Поэтому перед выводом текста свойству Brush.Color нужно присвоить значение bsClear или задать цвет кисти, совпадающий с цветом поверхности, на которую выводится текст.
Следующий фрагмент программы демонстрирует использование функции Textout для вывода текста на поверхность формы:
with Form1.Canvas do begin
// установить характеристики шрифта
Font.Name := 'Tahoma';
Font.Size := 20;
Font.Style := [fsltalic, fsBold] ;
Brush.Style := bsClear; // область вывода текста не закраши-
TextOut(0, 10, 'Borland Delphi 7');
end;
После вывода текста методом TextОut указатель вывода (карандаш) перемещается в правый верхний угол области вывода текста.
Иногда требуется вывести какой-либо текст после сообщения, длина которого во время разработки программы неизвестна. Например, это может быть слово "руб." после значения числа, записанного прописью. В этом случае необходимо знать координаты правой границы уже выведенного текста. Координаты правой границы текста, выведенного методом TextОut, можно получить, обратившись к свойству PenPos.
Следующий фрагмент программы демонстрирует возможность вывода строки текста при помощи двух инструкций Textout.
with Form1.Canvas do begin
TextOut(0, 10, 'Borland ') ;
TextOut(PenPos.X, PenPos.Y, 'Delphi 7');
end;
Методы для вывода текста - TextOut и TextRect. При выводе текста используется шрифт (Font) канвы. При использовании TextRect текст выводится только внутри указанного прямоугольника. Длину и высоту текста можно узнать с помощью функций TextWidth и TextHeight.
Карандаш и кисть
Художник в своей работе использует карандаши и кисти. Методы, обеспечивающие вычерчивание на поверхности холста графических примитивов, тоже используют карандаш и кисть. Карандаш применяется для вычерчивания линий и контуров, а кисть для закрашивания областей, ограниченных контурами.
Карандашу и кисти, используемым для вывода графики на холсте, соответствуют свойства Реn (карандаш) и Brush (кисть), которые представляют собой объекты типа треп и TBrush, соответственно. Значения свойств этих объектов определяют вид выводимых графических элементов.
Кисть
Кисть (canvas.Brush) используется методами, обеспечивающими вычерчивание замкнутых областей, например геометрических фигур, для заливки (закрашивания) этих областей. Кисть, как объект, обладает двумя свойствами, перечисленными в табл. 10.5.
Таблица 10.5. Свойства объекта TBrush (кисть)
Свойство |
Определяет |
|
Color Style |
Цвет закрашивания замкнутой области Стиль (тип) заполнения области |
Область внутри контура может быть закрашена или заштрихована. В первом случае область полностью перекрывает фон, а во втором сквозь незаштрихованные участки области будет виден фон.
В качестве значения свойства Color можно использовать любую из констант типа TColor (см. список констант для свойства Pen.color в табл. 10.2).
Константы, позволяющие задать стиль заполнения области, приведены в табл. 10.6.
Таблица 10.6. Значения свойства Brush, style определяют тип закрашивания
Константа |
Тип заполнения (заливки) области |
|
bsSolid |
Сплошная заливка |
|
bsClear |
Область не закрашивается |
|
bsHorizontal |
Горизонтальная штриховка |
|
bsVertical |
Вертикальная штриховка |
|
bsFDiagonal |
Диагональная штриховка с наклоном линий вперед |
|
bsBDiagonal |
Диагональная штриховка с наклоном линий назад |
|
bsCross |
Горизонтально-вертикальная штриховка, в клетку |
|
bsDiagCross |
Диагональная штриховка, в клетку |
В качестве примера в листинге 10.1 приведена программа Стили заполнения областей, которая в окно (рис. 10.2) выводит восемь прямоугольников, закрашенных черным цветом с использованием разных стилей.
Рис. 10.2. Окно программы Стили заполнения областей |
Карандаш
Карандаш используется для вычерчивания точек, линий, контуров геометрических фигур: прямоугольников, окружностей, эллипсов, дуг и др. Вид линии, которую оставляет карандаш на поверхности холста, определяют свойства объекта треп, которые перечислены в табл. 10.1.
Таблица 10.1. Свойства объекта треп (карандаш)
Свойство |
Определяет |
|
Color |
Цвет линии |
|
Width |
Толщину линии |
|
Style |
Вид линии |
|
Mode |
Режим отображения |
Свойство Color задает цвет линии, вычерчиваемой карандашом. В табл. 10.2 перечислены именованные константы (тип TCoior), которые можно использовать в качестве значения свойства color.
Таблица 10.2. Значение свойства Color определяет цвет линии
Константа |
Цвет |
Константа |
Цвет |
|
clBlack |
Черный |
clSilver |
Серебристый |
|
clMaroon |
Каштановый |
clRed |
Красный |
|
clGreen |
Зеленый |
clLime |
Салатный |
|
clOlive |
Оливковый |
clBlue |
Синий |
|
clNavy |
Темно-синий |
clFuchsia |
Ярко-розовый |
|
clPurple |
Розовый |
clAqua |
Бирюзовый |
|
clTeal |
Зелено-голубой |
clWhite |
Белый |
|
clGray |
Серый |
Свойство width задает толщину линии (в пикселах). Например, инструкция Canvas. Pen. width: =2 устанавливает толщину линии в 2 пиксела.
Свойство style определяет вид (стиль) линии, которая может быть непрерывной или прерывистой, состоящей из штрихов различной длины. В табл. 10.3 перечислены именованные константы, позволяющие задать стиль линии. Толщина пунктирной линии не может быть больше 1. Если значение свойства Pen.width больше единицы, то пунктирная линия будет выведена как сплошная.
Таблица 10.3. Значение свойства Реn. туре определяет вид линии
Константа |
Вид линии |
|
psSolid |
Сплошная линия |
|
psDash |
Пунктирная линия, длинные штрихи |
|
psDot |
Пунктирная линия, короткие штрихи |
|
psDashDot |
Пунктирная линия, чередование длинного и короткого штрихов |
|
psDashDotDot |
Пунктирная линия, чередование одного длинного и двух коротких штрихов |
|
psClear |
Линия не отображается (используется, если не надо изображать границу области, например, прямоугольника) |
Свойство Mode определяет, как будет формироваться цвет точек линии в зависимости от цвета точек холста, через которые эта линия прочерчивается. По умолчанию вся линия вычерчивается цветом, определяемым значением свойства Pen.Color.
Однако программист может задать инверсный цвет линии по отношению к цвету фона. Это гарантирует, что независимо от цвета фона все участки линии будут видны, даже в том случае, если цвет линии и цвет фона совпадают.
В табл. 10.4 перечислены некоторые константы, которые можно использовать в качестве значения свойства Pen.Mode.
Таблица 10.4. Значение свойства Реп. Mode влияет на цвет линии
Константа |
Цвет линии |
|
pmBlack |
Черный, не зависит от значения свойства Pen. Color |
|
pmWhite |
Белый, не зависит от значения свойства Pen. Color |
|
pmCopy |
Цвет линии определяется значением свойства Pen . Color |
|
pmNotCopy |
Цвет линии является инверсным по отношению к значению свойства Pen. Color |
|
pmNot |
Цвет точки линии определяется как инверсный по отношению к цвету точки холста, в которую выводится точка линии |
Листинг 10.1. Стили заполнения областей
unit brustyle_; interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, ExtCtrls;
type
TForm1 = class(TForm)
procedure FormPaint(Sender: TObject);
private
{ Private declarations}
public
{ Public declarations )
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
// перерисовка формы
procedure TForm1.FormPaint(Sender: TObject);
const
bsName: array[1..8] of string =
('bsSolid','bsClear','bsHorizontal',
'bsVertical','bsFDiagonal','bsBDiagonal',
'bsCross','bsDiagCross');
var
x,y: integer; // координаты левого верхнего угла прямоугольника
w,h: integer; // ширина и высота прямоугольника
bs: TBrushStyle;// стиль заполнения области
k: integer; // номер стиля заполнения
i,j: integer;
begin
w:=40; h:=40; // размер области(прямоугольника)
у:=20;
for i:=l to 2 do
begin
х:=10;
for j:=1 to 4 do
begin
k:=j+(i-1)*4; // номер стиля заполнения
case k of
1: bs = bsSolid;
2: bs = bsClear;
3: bs = bsHorizontal;
4: bs = bsVertical;
5: bs = bsFDiagonal;
6: bs = bsBDiagonal;
7: bs = bsCross;
8: bs = bsDiagCross; end;
// вывод прямоугольника
Canvas.Brush.Color := clGreen;
// цвет закрашивания зеленый
Canvas.Brush.Style := bs;
// стиль закрашивания
Canvas . Rectangle (x, y, x+w, y-t-h) ;
// вывод названия стиля
Canvas.Brush.Style := bsClear;
Canvas.TextOut(x, y-15, bsName[k]);
// вывод названия стиля
x := x+w+30;
end;
у := y+h+30;
end;
end;
end.
Проект 1. Нарисовать снеговика.
procedure TForm1.Button1Click(Sender: TObject);
begin
canvas.Pen.Color:=claqua;
canvas.Brush.Color:=clAqua;
canvas.Ellipse(200,200,400,400);
canvas.Ellipse( . . . );
. . .
canvas.Pen.Color:=clRed;
canvas.Brush.Color:=clRed;
canvas.Rectangle(280,30,320,60);
canvas.MoveTo(260,120);
canvas.LineTo(200,100);
canvas.MoveTo(340,120);
canvas.LineTo(400,100);
. . .
canvas.MoveTo(290,75);
canvas.LineTo(250,77);
canvas.LineTo( . . . );
. . .
canvas.FloodFill(285,77,clred,fsborder);
end;
Нарисовать круглую мишень.
На форме разместите три визуальных компонента: Label, Edit и Button.
Используем оператор цикла:
for k:=1 to k do begin
. . .
end;
где n - количество кругов.
Цвет зададим случайным образом, например так:
canvas.Brush.Color:=random(10000000);
Для рисования мишени используем метод Ellipse. Рассмотрим два подхода в рисовании мишени, отличающиеся выбором точки относительно которой будет выполняться построение.
Например так: 400-r,200-r - левая верхняя вершина, 400+r,200+r - правая нижняя вершина квадратной области. Здесь r радиус круга, который затем уменьшаем r:=r-15;
То есть тело цикла будет следующим:
canvas.Brush.Color:=random(10000000);
canvas.ellipse(x-r,y-r,x+r,y+r);
r:=r-15;
Тело цикла будет иметь вид:
canvas.Brush.Color:=random(100000);
canvas.Ellipse(x,y,x+n,y+n);
n:=n-t;
x:=x+t div 2;
y:=y+t div 2;
Самостоятельная работа. Для всех заданий количество графических элементов не должно превышать 10.
1. Нарисовать квадратную мишень.
2. Нарисовать столбчатую диаграмму.
3. Нарисовать гирлянду. Шары должны размещаться целыми
Проект 3. Нарисовать кучу шаров.
Количество шаров зададим 300.
Радиус r , координаты x, y зададим случайным образом:
r:=random(100)+5;
x:=random(200)+220;
y:=random(100)+120;
Кроме того, нам понадобится задержка (замедление):
for i:=1 to 10000000 do;
Дополнительно: сделать шары на весь экран.
Задержку (замедление) можно убрать.
Цель:
На форме создайте три компонента button и 1 компонент label. Во вкладке Dialogs выбираем пиктограмму ColorDialog и перетаскиваем его на форму. Данный объект относится к так называемым псевдовизуальным т.е. эти элементы при запуске программы не отображаются, а появляются только после обращения к этим компонентам. Как правило размеры этих компонентов строго фиксированы, то есть на этапе визуального проектирования компонент будет отображается только пиктограммой. Основное свойство компонента ColorDialog Color. Это свойство соответствует тому цвету, который выбрал в диалоге пользователь. Компонент ColorDialog вызывает диалоговое окно выбора цвета, представленное В нем пользователь может выбрать цвет из базовой палитры или, нажав кнопку Определить цвет, раскрыть дополнительную панель, позволяющую синтезировать цвет, отличный от базовых. Синтезированный цвет можно добавить кнопкой «Добавить» в набор в палитру дополнительных цветов на левой панели и использовать его в дальнейшем. Форма должна иметь приблизительно такой вид как на приведенном рисунке. Компонент ColorDialog может располагаться в любом месте формы.
if ColorDialog1.Execute then Canvas.Pen.Color := ColorDialog1.Color;
Canvas.MoveTo (pX,pY);
Canvas.LineTo (X,Y);
pX:=X;
pY:=Y;
Наша программа должна не только рисовать линии но и подсчитывать общую длину нарисованных линий. Для этого на каждом этапе рисовании линии будем вычислять ее длину и суммировать с длиной линии построенной ранее. Для реализации этого следует в программу добавить следующие строки кода, но поставить их нужно обязательно перед строками, в которых происходит перераспределение координат: Функция STR превращает числовой величину длины в строку текста с общей длиной 10 символов из которых на дробную часть будет потрачено 2 позиции.
Len:=Len+sqrt(sqr(Px-X)+sqr(pY-Y));
pX:=X;
pY:=Y;
Str(Len:10:2,s);
Label1.Caption:=s;
pX:=0;
pY:=0;
Len:=0;
Самостоятельно:
Проект 6. Летающий шарик.
Для начала пусть летает влево вправо отражаясь от соответствующих границ формы.
В качестве шарика используем компонент shape - фигура (см. Вкладку палитры компонентов Дополнительно). Причем, одноименное свойство shape в инспекторе объектов настроим на значение stCircle окружность.
Для движения шарика установим компонент Timer (см. вкладку Система - часы).
Это не визуальный компонент (невидимый после запуска).
Выполняет функцию регулярного прерывания программы через определенный интервал времени (см. свойство interval) для выполнения определенных пользователем действий (см. процедуру обработки таймера procedure TForm1.Timer1Timer(Sender: TObject);).
Объявим глобальные переменные:
var x, hx: integer;
В процедуре FormCreate включим таймер:
timer1.Enabled:=true;
Зададим начальное положение шарика
x:=shape1.Left;
Шаг движения:
hx:=10;
Интервал прерывания таймера:
timer1.interval:=20;
Двойным щелчком по часам переходим в процедуру:
procedure TForm1.Timer1Timer(Sender: TObject);
где изменяем координату :
x:=x+hx;
Проверяем границы и меняем направление:
if (x>=536-shape1.width) or (x<=0) then hx:=-hx;
И рисуем по новым координатам (старое положение фигуры стирается автоматически):
shape1.Left:=x;
Дополнительно1: шарик должен летать по диагонали.
Подсказка: координату y определяем как shape1.top.
Дополнительно2: Сделать два шарика, летающих по диагонали не зависимо друг от друга (фигуры shape1 и shape2).
Проект 7. Броуновское (хаотичное) движение шарика.
Выбираем случайно одно из восьми направлений:
Для этого в процедуре обработки события связанного с таймером пишем:
procedure TForm1.Timer1Timer(Sender: TObject);
var z: integer;
begin
z:= random(8);
case z of
0: begin hx:= 3; hy:= 0; end;
1: begin hx:= 3; hy:= -3; end; {оператор выбора варианта}
2: направление 2
3: направление 3
. . .
end;
x:= x + hx;
y:= y + hy;
shape1. left:= x;
shape1. top:= y;
end;
Дополнительно1: Сделать броуновское движение двух шариков.
Дополнительно2: Шарик не должен выходить за пределы формы.
Проект 8. Цветной ковер.
Для этого в процедуре обработки события связанного с таймером пишем:
for k:=1 to 100 do
canvas.Pixels[random(536),random(348)]:= random(1000000);
где Pixels[ x, y ] массив всех точек (пикселей) формы, которым присваиваем случайный цвет.
Причем красим за один раз 100 точек (пикселей).
Цвет можно задавать изменяя случайно предел интервала:
random(random(random(1000000)));
В процедуре FormCreate пишем:
randomize;
включаем таймер, задаем небольшой интервал работы таймера (определяющий скорость).
Проект 9. Броуновское (хаотичное) движение точки (пикселя), оставляющей след (траекторию).
Можно обойтись без case z of , если задать смещение точки так:
dx:= random(3) 1;
dy:= random(3) 1;
Очевидно будет выбрано одно из восьми направлений, т.к. выпадает случайно -1, 0, 1.
Координаты зададим в процедуре FormCreate , двигать точку будем в процедуре Timer1Timer.
Проект 10. Броуновское (хаотичное) движение N точек (пикселей), оставляющих след (траекторию).
Координаты точек (пикселей) и цвет задаем случайным образом (random) и сохраняем их в массивах:
x[k], y[k] координаты k ой точки, c[k] цвет k ой точки.
При этом массивы надо объявить глобальные (перед Implementation):
Const N = 100;
Var x, y, с: array[1 . . N] of integer;
и присвоить (в процедуре FormCreate):
for k:=1 to N do begin
x[k];= random(536);
y[k]:= random(348);
c[k]:= random(random(random(1000000)));
canvas.Pixels[x[k], y[k]]:= c[k];
end;
В итоге можно получить такую картинку:
Проект 11. Снег.
Необходимо использовать массив координат, один цвет и пять направлений движения снежинок:
x[k], y[k] координаты k ой точки.
В процедуре FormCreate зададим значения этих координат случайным образом:
randomize;
timer1.Enabled:=true;
for k:=1 to n do
begin
x[k]:=random(500)+20;
y[k]:=random(70)+50;
end;
В процедуре FormPaint нарисуем снежинки и поверхность земли:
canvas.Pen.Color:=claqua;
canvas.Brush.Color:=claqua;
canvas.Rectangle(0,320,535,330);
for k:=1 to n do
canvas.Pixels[x[k],y[k]]:=clred;
В процедуре обработки таймера находим новые значения координат:
x1:=x[k]+dx; y1:=y[k]+dy;
Рисуем снежинку по новым координатам (x1,y1) и стираем ее по старым координатам (x[k],y[k]):
canvas.Pixels[x1,y1]:=clred;
canvas.Pixels[x[k],y[k]]:=clbtnface;
Если снежинка долетает до поверхности взамен нее выпускаем новую.
x[k]:=random(500)+20;
y[k]:=50;
Не забудем изменить (присвоить) текущие значения координат на новые:
x[k]:=x1;
y[k]:=y1;
Дополнительно: Снег должен накапливаться в сугробы:
Заставим снежинки накапливаться в сугробы (снежный покров).
Для этого будем предварительно проверять цвет пикселя в той точке, в которую собираемся переместить снежинку, т.е. в точке с новыми координатами (x1,y1).
Если впереди препятствие определенного цвета (поверхность земли, а затем и упавший снег), то снежинка останавливается. При этом она меняет свой цвет, что позволяет летящим снежинкам прилипать к уже упавшим, образуя, таким образом, сугроб (снежный покров):
if canvas.pixels[x1,y1]<>claqua then
begin
canvas.Pixels[x1,y1]:=clred;
canvas.Pixels[x[k],y[k]]:=clbtnface;
x[k]:=x1;y[k]:=y1;
end
else
begin
canvas.pixels[x[k],y[k]]:=claqua;
x[k]:=random(500)+20;
y[k]:=50;
end;
Проект 12. Дымоход.
Нарисовать две наклонные линии стенок трубы (наклонные для скорости засорения трубы). Запустить снизу частички сажи и ждать когда засорится труба.
Проект 13. Электролиз.
Нарисовать в центре формы шар (катод).
Запустить с четырех сторон ионы (частички) и ждать когда они налипнут на шар.
Для того, чтобы частички летели с разных сторон необходимо задать четыре пары массивов координат:
x[k], y[k] координаты k ой точки, летящей слева.
x1[k], y1[k] координаты k ой точки, летящей сверху.
x2[k], y2[k] координаты k ой точки, летящей справа.
x3[k], y3[k] координаты k ой точки, летящей снизу.
Проект 14. Берег.
Программа моделирует морские волны, которые размывают берег, изменяя рельеф береговой линии, в зависимости от твердости породы.
Работу над проектом разобьем на три этапа:
В итоге мы можем получить картинки следующего вида:
И через некоторое время:
Приложения Delphi используют управляемые событиями методы для организации взаимодействия между программой и пользователем. Большая часть кода как правило инициирует события. Происхождение событий заставляет работать определенный объект, при этом объект получает заранее определенные параметры для своей настройки на работу. В Delphi процедура, инициируемая событием, называется обработчиком событий.
События делятся на три основные категории:
Рассмотрим как теорию применить на практике.
События мыши.
Для формы событие OnClik возникает в том случае, если пользователь нажимает левую кнопку мыши в то время, когда курсор находится на поле формы.
procedure TForm1.FormClick(Sender: TObject);
begin
color:=RGB(random(256), random(256), random(256));
end;
Функция random генератор случайных чисел. Аргумент функции (256) определяет границу генерируемого числа (от 0 до 256).
Задание №1. Напишите приложение, в котором при нажатии на левую кнопку мыши происходит смена цвета с зеленного на красный, и, наоборот, с красного на зеленый
Событие OnDblClick происходит, если пользователь выполняет двойной щелчок левой кнопкой мыши.
События On MouseDown возникает, если пользователь нажимает на правую, левую или среднюю кнопку мыши
Задание №2. Самостоятельно исследуйте событие OnDblClick. Измените цвет формы и свойство Cursor. Числовой эквивалент свойства Cursor находится в интервале от -21 до 0.
Задание №1.
procedure TForm1.FormClick(Sender: TObject);
begin
if color=clRed then color:=clGreen else color:=clRed;
end;
Задание №2.
procedure TForm1.FormDblClick(Sender: TObject);
begin
Color:=clred;
end;
1. Создайте новую форму. Свойства объекта установите следующим образом:
Caption := графика.
Name :=MainF;
Чтобы нарисовать на форме пунктирную линию красного цвета от точки с координатами (10,10) до точки (300,300) создайте обработчик событий формы Click (двойной клик) и наберите следующие операторы:
procedure TForm1.FormClick(Sender: TObject);
begin
with Canvas do
begin
pen.Color:=clred;
pen.Style:=PsDash;
MoveTo(10,10);
LineTo(300,300);
end
end;
Пояснения: Свойство Pen устанавливает параметры изображения линии, такие как цвет (Color), тип (Style), толщина (Width)
Метод MoveTo(x,y) перемещает графический курсор в точку с координатами (x,y).
Метод LineTo(x,y) рисует отрезок от текущего положения графического курсора до точки с координатами (x,y).
Задание. Напишите программу позволяющую нарисовать схематическое изображение домика.
2. Удалите предыдущую программу командой Close all… Создайте новую форму. Свойства объекта установите следующим образом:
Caption := графика.
Name :=MainF;
Для рисование произвольных отрезков воспользуемся событие OnMouseDown. Нажатие кнопки мыши послужит началом рисования отрезка, освобождение кнопки мыши завершает рисование отрезка.
Создайте обработчик события OnMouseDown (двойной клик)
procedure TmainF.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
canvas.MoveTo(x,y);
end;
Создайте обработчик события OnMouseUp (двойной клик)
procedure TmainF.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Canvas.LineTo(x,y);
end;
3. Удалите предыдущую программу командой Close all… Создайте новую форму. Свойства объекта установите как в предыдущим задании.
Рисование кривых линий это изображение следа курсора мыши. Перемещение курсора мыши возбуждает событие OnMouseMove. Создайте обработчик этого события и введите следующие операторы:
procedure TmainF.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
Canvas.LineTo(x,y);
end;
Недостатком написанной процедуры является:
1 начало рисования левый верхний угол;
2 невозможно завершить процесс.
Обработчик события OnMouseMove в параметре Shift получает состояние клавиш Alt, Ctrl, Shift и кнопок мыши. Для определенности положим, что линия будет рисоваться, когда нажата левая кнопка мыши. Изменим обработчик события следующим образом:
procedure TmainF.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if ssLeft in Shift then Canvas.LineTo(x,y)
else Canvas.MoveTo(x,y);
end;
Рассмотрим некоторые ранее описанные методы.
Метод Rectangle(x1,y1,x2,y2) в котором параметры задают координаты противоположенных вершин прямоугольника. Нажатие кнопки мыши (события OnMouseDown) фиксирует начало рисования прямоугольника и соответственно определяет координаты правого верхнего угла прямоугольника. Освобождение кнопки (событие OnMouseUp) окончание рисования прямоугольника и соответственно определяет координаты правой нижней точки прямоугольника.
Создайте обработчики этих событий и введите следующие операторы:
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
x1:=x;
y1:=y;
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Canvas.Rectangle(x1,y1,x,y);
end;
Переменные x1,y1 являются глобальными переменными их нужно описать в разделе private класса TMainF.
Объединение отрезков A1A2, A2A3, … AN-1AN образуют ломаную А1А2А3 … АN Начало ломаной это точка А1, конец точка АN. Для рисования ломаной нужно задать ее начало, затем нарисовать звенья и наконец завершить ломаную. Начало (конец) рисования ломаной линии свяжем с событием OnDblClick. Введем логическую переменную Draw: ее значение, равное True будет обозначать рисование ломаной, False завершение ломаной. В разделе interface модуля введите раздел констант (после раздела описания переменных Var).
Const draw: Boolean= False;
Создайте обработчик события OnDblClick:
procedure TForm1.FormDblClick(Sender: TObject);
begin
draw := not draw;
end;
В обработчике события OnMouseDown будем рисовать звенья ломаной, Если значение переменной Drawравно True и перемещать графический курсор, в противном случае. Дописать
Рисовать линии с выбором цвета
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
ColorDialog1: TColorDialog;
procedure FormActivate(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
pX,pY:integer;
Len:Extended;
s:String;
implementation
{$R *.dfm}
procedure TForm1.FormActivate(Sender: TObject);
begin
pX:=0;
pY:=0;
Len:=0;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Canvas.MoveTo (pX,pY);
Canvas.LineTo (X,Y);
Len:=Len+sqrt(sqr(Px-X)+sqr(pY-Y));
pX:=X;
pY:=Y;
Str(Len:10:2,s);
Label1.Caption:=s;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
close;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Refresh;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if ColorDialog1.Execute then Canvas.Pen.Color := ColorDialog1.Color;
end;
end.
Получить цвет пикселя под курсором мыши: http://codingrus.ru/readarticle.php?article_id=1651
procedure TForm1.Timer1Timer(Sender: TObject);
var
DC: HDC;
Cur: TPoint;
ColorValue: Cardinal;
begin
DC := GetDC( 0 );
// Получаю координаты курсора
GetCursorPos( Cur );
// Узнаю цвет пикселя в полученных координатах
ColorValue := GetPixel( DC, Cur.X, Cur.Y );
// Показываю полученный цвет
PanelMonitor.Color := ColorValue;
// Показываю красную составляющую цвета
TrackRValue.Position := GetRValue( ColorValue );
// Показываю зеленую составляющую цвета
TrackGValue.Position := GetGValue( ColorValue );
// Показываю синюю составляющую цвета
TrackBValue.Position := GetBValue( ColorValue );
ReleaseDC( 0, DC );
end;
Цель: Познакомится с объектом TShape
1. Откройте новую Форму. Для объекта установите следующим свойства:
Caption := графика.
Name :=MainF;
Color:= белый;
2.На вкладке Samples выберите объект ColorGrids
3. На вкладке Additional выберите объект Shape .
На данном объекте и будем рисовать фигуры.
4. На вкладке Standart выбираем объект GroupBox. Свойства объекта:
Саption:= Shape;
В объект GroupBox вставляем 6 объектов RadioButton. Для каждого объекта измените свойство Caption в соответствии с образцом. Выравнивание объектов RadioButton по размеру и положение пункт меню Edit разделы Size и Align.. (подробно описано в лабораторной работе № )
Программный код.
Программировать начнем с радиокнопок. Для каждой кнопки программируется событие OnClick (двойной клик) и для каждого выбирается свой метод.
procedure TForm1.RadioButton1Click(Sender: TObject);
begin
Shape1.Shape:=stCircle;
end;
procedure TForm1.RadioButton2Click(Sender: TObject);
begin
Shape1.Shape:=stEllipse;
end;
procedure TForm1.RadioButton3Click(Sender: TObject);
begin
Shape1.Shape:=stRectangle;
end;
procedure TForm1.RadioButton4Click(Sender: TObject);
begin
Shape1.Shape:=stRoundRect;
end;
procedure TForm1.RadioButton5Click(Sender: TObject);
begin
Shape1.Shape:=stRoundSquare;
end;
procedure TForm1.RadioButton6Click(Sender: TObject);
begin
Shape1.Shape:=stSquare;
end;
Для объекта ColorGrid событие Change (двойной клик) определяем цвет объекта.
procedure TForm1.ColorGrid1Change(Sender: TObject);
begin
Shape1.Brush.Color:=ColorGrid1.ForeGroundColor;
end;
end.
Цель: Закрепить навыки использования Объекта TShape -
1. Создайте новую форму. Свойства объекта установите следующим образом:
Caption := графика.
Name :=MainF;
2. Создайте кнопку «выход».
3. Создайте объект Label. Свойство: caption :=Светофор.
4. На вкладке additional выберите объект Shape и установите его на форме.
5. Светофор переключается через равномерные промежутки времени. Для этого в форме System выберите и установите на форме объект Timer. На форма создайте объект Label, для отображения времени. Размер текста свойство Font установите 20.
У вас должно получиться приблизительно так:
Переходим к написанию кода.
6. Для начала определим глобальные переменные.
Переменная Сont устанавливает значение текущего цвета фонаря светофора, соответственно: красный, желтый, зеленый.
Переменная Time и S счетчик времени. Time числовое значение, S текстовая величина , для отображения в объекте Label2.
Colors константа устанавливающая цвета светофора.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids, ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
const Colors: array [1..3] of TColor=(clRed,clYellow,clLime);
var
Form1: TForm1;
Cond:integer;
Time:longint;
Ball:array [1..3] of TShape;
s:String;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
close;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if Cond>0 then begin
Ball[Cond].Brush.Style:=bsSolid; \\ Стиль кисти
if Cond<3 then Inc(Cond) \\Выбираем цвет светофора
else Cond:=1;
Ball[Cond].Brush.Style:=bsDiagCross; \\ Закрашиваем фонарь
Inc(Time); \\увеличиваем счетчик времени
str(Time,s);
Label1.Caption:=s; \\выводим значение счетчика времени
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var i:integer;
begin
Cond:=0;
Time:=0;
for i:=1 to 3 do begin
Ball[i]:=TShape.Create(Self);
with Ball[i] do begin
Parent:=Form1;
Shape:=stCircle;
Left:=168;
Height:= 97;
Width:=89;
Top:=178+(i-1)* 75;
Brush.Color:=Colors[i];
{ Visible:=True;
Enabled:=True;
Repaint; }
end;
end;
Ball[1].Brush.Style:=bsDiagCross;
Cond:=1;
end;
end.
Для начала пусть летает влево вправо отражаясь от соответствующих границ формы.
В качестве шарика используем компонент shape - фигура (см. Вкладку палитры компонентов Дополнительно). Причем, одноименное свойство shape в инспекторе объектов настроим на значение stCircle окружность.
Для движения шарика установим компонент Timer (см. вкладку Система - часы).
Это не визуальный компонент (невидимый после запуска).
Выполняет функцию регулярного прерывания программы через определенный интервал времени (см. свойство interval) для выполнения определенных пользователем действий (см. процедуру обработки таймера procedure TForm1.Timer1Timer(Sender: TObject);).
Объявим глобальные переменные:
var x, hx: integer;
В процедуре FormCreate включим таймер:
timer1.Enabled:=true;
Зададим начальное положение шарика
x:=shape1.Left;
Шаг движения:
hx:=10;
Интервал прерывания таймера:
timer1.interval:=20;
Двойным щелчком по часам переходим в процедуру:
procedure TForm1.Timer1Timer(Sender: TObject);
где изменяем координату :
x:=x+hx;
Проверяем границы и меняем направление:
if (x>=536-shape1.width) or (x<=0) then hx:=-hx;
И рисуем по новым координатам (старое положение фигуры стирается автоматически):
shape1.Left:=x;
Дополнительно1: шарик должен летать по диагонали.
Подсказка: координату y определяем как shape1.top.
Дополнительно2: Сделать два шарика, летающих по диагонали не зависимо друг от друга (фигуры shape1 и shape2).
Для построения графиков функций используем метод «как в школе учили». Строить график будем так же , как на бумаге. Тем самым оставим те же недостатки «бумажного» метода построения, и даже усугубим их.
Рассмотрим пример программы приведенный ниже.
unit Graf;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormPaint(Sender: TObject);
procedure FormResize(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
Function f(x:real):real;
begin
f:=2*Sin(x)*exp(x/5); // наша функция
end;
// строит график функции
procedure GrOfFunc;
var
x1,x2:real; // границы изменения аргумента функции
y1,y2:real; // границы изменения значения функции
x:real; //аргумент функции
y:real; // значение функции в точке х
dx:real; // приращение аргумента
l,b:integer; // левый нижний угол области вывода графика
w,h:integer; // ширина и высота области вывода графика
mx,my:real; // масштаб по осям X и Y
x0,y0:integer; // точка - начало координат
begin // область вывода графика
l:=10; // X - координата левого верхнего угла
b:=Form1.ClientHeight-20; //У - координата левого верхнего угла
h:=Form1.ClientHeight-40; // высота
w:=Form1.Width-40; // ширина
x1:=0; // нижняя граница диапазона аргумента
x2:=25; // верхняя граница диапазона аргумента
dx:=0.01; // шаг аргумента
// найдем максимальное и минимальное значения функции на отрезке [x1,x2]
y1:=f(x1); // минимум
y2:=f(x1); //максимум
x:=x1;
repeat
y := f (x);
if y < y1 then y1:=y;
if y > y2 then y2:=y;
x:=x+dx; until (x >= x2);
// вычислим масштаб
my:=h/abs(y2-y1); // масштаб по оси Y
mx:=w/abs(x2-x1); // масштаб по оси X
x0:=1;
y0:=b-Abs(Round(y1*my)) ;
with form1.Canvas do
begin // оси
MoveTo(l,b);LineTo(l,b-h);
MoveTo(x0,y0);LineTo(x0+w,y0);
TextOut(l+5,b-h,FloatToStrF(y2,ffGeneral,6,3));
TextOut(l+5,b,FloatToStrF(y1,ffGeneral,6,3));
// построение графика
x:=x1; repeat
y:=f(x);
Pixels[x0+Round(x*mx),y0-Round(y*my)]:=clRed;
x:=x+dx;
until (x >= x2);
end;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
GrOfFunc;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
// очистить форму
form1.Canvas.FillRect(Rect(0,0,ClientWidth,ClientHeight));
// построить график
GrOfFunc;
end;
end.
Программа хорошо выводит графики, когда функция имеет как положительные, так и отрицательные значения. Причем весь график помещается в указанном прямоугольнике.
Недостатки:
Теперь посмотрим, а сколько вычислений значений функции делает программа? В данном случае (25-0)/0.01=2500. Для любого прямоугольника вывода. Чем был обусловлен выбор шага dx? Скорее всего, непрерывностью линии графика. Который, кстати, так и остался прерывистым на некоторых участках, там, где функция меняется быстро. Для борьбы этим напрашивается решение уменьшение значения dx, например - в 100 раз, доводя dx до 0.0001. это приведет к возрастанию вычислений функции до 250000. Но график все равно получиться прерывистые. Причем большая часть результатов вычислений просто пропадут в результате округления Round . Отсюда вытекает, что функцию нужно считать в количестве точек равных размерам окна по горизонтали, а отрезки вертикальных прямых можно нарисовать карандашом. И dx нужно выбирать например (25-0)/600= 0,0416666. График получится самый качественный, какой только возможно получить.
Вторым недостатком является сам метод построения (вычисление значений функции с шагом dx) работает как фильтр, отсекая высокочастотные гармоники, т.е если к функции f(x) добавить что-то вроде g(x)*sin(2*pi/dx*x), то результат вывода будет плачевным. Этот элемент никак не изменит предыдущий график. Хотя он может являться основным носителем информации о функции. И уж конечно очень непросто вывести на экран график дискретной функции (имеется в ввиду универсальными программами общего пользования, подобными приведенной). Если взять f(x)=2*Sin(x)*exp(x/5)+ exp(x*x)*sin(2*pi/dx*x), то данная программа второе слагаемое не заметит, хотя будет тратить время на расчет f(x)=2*Sin(x)*exp(x/5)* exp(x*x)*sin(2*pi/dx*x). Приведенная программа, некорректно отобразит его.
А вот если взять TAB MathGrapher 1.0 (распространена в Интернете) и просто ввести 5* Sin(200*pi*x), то мы получим чистый ноль. Вместо 5, понятно, можно написать любую функцию, да и вместо Sin(200*pi*x) любую периодическую с кратной частотой, и программа выдаст неверный график.
Как с этими недостатками бороться? Очевидно, нужно, чтобы программа давала возможность рассматривать функцию на небольшом отрезке, с dx=(х2-х1)/w (ширина вывода в пикселях). Т.е. программа должна автоматически менять шаг с уменьшением отрезка(значения х2, х1 нужно вводить вручную).
Лабораторная работа Построение графиков в среде Delphi.
Визуальный этап:
1. Создать новую форму и поместить на нее компонент TСhart вкладка Additional. Растяните TСhart до удобного для разработки размера.
2. Создайте две кнопки BitBtn на этой же вкладке c надписью функции «Y(x)=sin(x)» и «выход» соответственно.
3. Отредактируйте и настройте внешний вид Series. Для этого на объекте TСhart нажмите правую кнопку мыши и в открывшемся окне выберите команду Edit Сhart… В открывшемся окне и проводят настройку внешнего вида. Выберите тип графика Line, цвет и т.п.
Рис внешний вид Series
4.Пишем код нажатия на кнопку событие OnClick.
procedure TForm1.BitBtn1Click(Sender: TObject);
var
i:integer;
begin
Series1.Clear;
for i:=0 to 22 do
begin
Series1.AddXY(i*0.29,10*sin(i*0.29),'',clGreen);
end;
end;
Сегодня мы рассмотрим, как средствами дельфи создать простейшую мультипликацию.
При программировании сложных изображений, состоящих из множества элементов, используется метод, который называется методом базовой точки. Суть этого метода заключается в следующем:
1. Выбирается некоторая точка изображения, которая принимается за базовую.
2. Координаты остальных точек отсчитываются от базовой точки, в относительных координатах.
3. Если координаты точек изображения отсчитывать от базовой в относительных единицах, а не в пикселах, то обеспечивается возможность масштабирования изображения.
Сначала вычертим кораблик. Вычерчивать будем относительно точки X и Y. За единицу приращения примем величину Dx и Dy (Dy=Dx). Для удобства вычерчивать будем отдельно корпус корабля и надстройки. Для этого вычертим на листе бумаги в координатной плоскости формы корпус корабля и надстройки. (рис 1 и рис2) Координаты точек будем хранить в массивах.
Начало координат находится в начале координат. Обход по часовой стрелки.
рис 1 |
рис2 |
p1[1].X := x; p1[1].y := y; p1[2].X := x; p1[2].Y := y-2*dy; p1[3].X :=x+10*dx; p1[3].Y := y-2*dy; p1[4].X :=x+11*dx; p1[4].Y := y-3*dy; p1[5].X :=x+17*dx; p1[5].Y :=y-3*dy; p1[6].X :=x+14*dx; p1[6].Y :=y; p1[7].X :=x; p1[7].Y :=y; |
p2[1].X := x+3*dx; p2[1].Y := y-2*dy; p2[2].X := x+4*dx; p2[2].Y := y-3*dy; p2[3].X := x+4*dx; p2[3].Y := y-4*dy; p2[4].X := x+13*dx; p2[4].Y := y-4*dy; p2[5].X := x+13*dx; p2[5].Y := y-3*dy; p2[6].X := x+11*dx; p2[6].Y := y-3*dy; p2[7].X := x+10*dx; p2[7].Y := y-2*dy; p2[8].X := x+3*dx; p2[8].Y := y-2*dy; |
Координаты остальных элементов рисунка определим следующим образом:
//линия корпуса
MoveTo(x+5*dx,y-3*dy);
LineTo(x+9*dx,y-3*dy);
// капитанский мостик
Rectangle(x+8*dx,y-4*dy,x+11*dx,y-5*dy);
// труба
Rectangle(x+7*dx,y-4*dy,x+8*dx,y-7*dy);
// иллюминаторы
Ellipse(x+11*dx,y-2*dy,x+12*dx,y-1*dy);
Ellipse(x+13*dx,y-2*dy,x+14*dx,y-1*dy);
// мачта
MoveTo(x+10*dx,y-5*dy);
LineTo(x+10*dx,y-10*dy);
// оснастка
Pen.Color := clWhite;
MoveTo(x+17*dx,y-3*dy);
LineTo(x+10*dx,y-10*dy);
LineTo(x,y-2*dy);
Обрисовку и стирание изображения кораблика выполняет процедура Titanik, которая получает в качестве параметров координаты базовой точки и цвет, которым надо вычертить изображение кораблика. Если при вызове процедуры цвет отличается от цвета фона формы, то процедура рисует кораблик, а если совпадает то "стирает". В процедуре Titanik объявлены константы dx и dy, определяющие шаг (в пикселах), используемый при вычислении координат точек изображения. Меняя значения этих констант, можно проводить масштабирование изображения.
unit ship_;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
var
x,y: integer; // координаты корабля (базовой точки)
//вычерчивает на поверхности формы кораблик или стирает его
procedure Parohod(x,y: integer; mode: boolean);
// x,y - координаты базовой точки кораблика mode: True - нарисовать, False - стереть
const
{ Базовые точки кораблика находятся в узлах сетки, шаг которой определяет размер кораблика. }
dx = 5; // шаг сетки по X
dy = 5; // шаг сетки по Y
var
// корпус и надстройку будем рисовать при помощи метода Polygon
p1: array[1..7]of TPoint; // координаты точек корпуса
p2: array[1..8]of TPoint; // координаты точек надстройки
pc,bc: TColor; // текущий цвет карандаша и кисти
begin
if not mode then
begin
// стереть
Form1.Canvas.Brush.Color := clNavy;
Form1.Canvas.Pen.Color := clNavy;
Form1.Canvas.Rectangle(x,y+1,x+17*dx,y-10*dy);
Form1.Canvas.Brush.Color := clNavy;
// небо
if y-10*dy < 80 then
begin
// конец мачты на фоне неба
Form1.Canvas.Pen.Color := clSkyBlue;
Form1.Canvas.Brush.Color := clSkyBlue;
Form1.Canvas.Rectangle(x,y-10*dy,x+17*dx,80);
end;
exit;
end;
// рисуем
with Form1.Canvas do
begin
pc :=Pen.Color; // сохраним текущий цвет карандаша
bc := Brush.Color; // и кисти
Pen.Color:=clBlack; // установим нужный цвет
Brush.Color := clWhite;
// рисуем ...
// корпус
p1[1].X := x; p1[1].y := y;
p1[2].X := x; p1[2].Y := y-2*dy;
p1[3].X :=x+10*dx; p1[3].Y := y-2*dy;
p1[4].X :=x+11*dx; p1[4].Y := y-3*dy;
p1[5].X :=x+17*dx; p1[5].Y :=y-3*dy;
p1[6].X :=x+14*dx; p1[6].Y :=y;
p1[7].X :=x; p1[7].Y :=y;
Polygon(p1);
// надстройка
p2[1].X := x+3*dx; p2[1].Y := y-2*dy;
p2[2].X := x+4*dx; p2[2].Y := y-3*dy;
p2[3].X := x+4*dx; p2[3].Y := y-4*dy;
p2[4].X := x+13*dx; p2[4].Y := y-4*dy;
p2[5].X := x+13*dx; p2[5].Y := y-3*dy;
p2[6].X := x+11*dx; p2[6].Y := y-3*dy;
p2[7].X := x+10*dx; p2[7].Y := y-2*dy;
p2[8].X := x+3*dx; p2[8].Y := y-2*dy;
Polygon(p2);
MoveTo(x+5*dx,y-3*dy);
LineTo(x+9*dx,y-3*dy);
// капитанский мостик
Rectangle(x+8*dx,y-4*dy,x+11*dx,y-5*dy);
// труба
Rectangle(x+7*dx,y-4*dy,x+8*dx,y-7*dy);
// иллюминаторы
Ellipse(x+11*dx,y-2*dy,x+12*dx,y-1*dy);
Ellipse(x+13*dx,y-2*dy,x+14*dx,y-1*dy);
// мачта
MoveTo(x+10*dx,y-5*dy);
LineTo(x+10*dx,y-10*dy);
// оснастка
Pen.Color := clWhite;
MoveTo(x+17*dx,y-3*dy);
LineTo(x+10*dx,y-10*dy);
LineTo(x,y-2*dy);
Pen.Color:=pc; // восстановим старый цвет карандаша
end;
end;
// обработка сигнала таймера
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Parohod(x,y, False); // стереть рисунок
if x < Form1.ClientWidth
then x := x+2
else begin // новый рейс
x := 0;
y := Random(50) + 100;
end;
Parohod(x,y,True); // нарисовать в новой точке
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
// небо
Canvas.Brush.Color := clSkyBlue; //цвет кисти
Canvas.Pen.Color := clSkyBlue; // цвет пера
Canvas.Rectangle(0,0,ClientWidth,80); //небо
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
x:=0; y:=80; // исходное положение парохода
Form1.Color:=clNavy; // цвет моря
Timer1.Interval := 50; // сигнал таймера каждые 50 мСек
end;
end.
Сегодня мы рассмотрим, как средствами дельфи создать простейшую мультипликацию.
При программировании сложных изображений, состоящих из множества элементов, используется метод, который называется методом базовой точки. Суть этого метода заключается в следующем:
1. Выбирается некоторая точка изображения, которая принимается за базовую.
2. Координаты остальных точек отсчитываются от базовой точки, в относительных координатах.
3. Если координаты точек изображения отсчитывать от базовой в относительных единицах, а не в пикселах, то обеспечивается возможность масштабирования изображения.
Рис 1. |
При использовании метода базовой точки легко обеспечить перемещение сформированного изображения: надо сначала вывести изображение в исходной базовой точке, через небольшой промежуток времени стереть изображение и снова его вывести, но уже изменив координаты базовой точки.
Следующая программа демонстрирует перемещение грузовика по поверхности формы от ее левой границы к правой. Изображение грузовика формируется методом базовой точки. После исчезновения грузовика за правой границей формы он вновь появляется слева. На форме предусмотрена кнопка, останавливающая и вновь продолжающая движение грузовика (Стоп/ Пуск). Вид формы должен соответствовать изображенному на рисунке 1.10.
Рис. 11 |
Отрисовку грузовика выполняет процедура lorry(), которая получает в качестве входных параметров координаты базовой точки. Для того чтобы стереть изображение грузовика используется метод Rectangle(), который рисует закрашенный цветом формы прямоугольник, полностью покрывающий грузовик. В программе объявлены константы dx и dy, изменяя значения которых можно подобрать необходимый масштаб грузовика.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Timer1: TTimer;
Button1: TButton;
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
const
dx=5;
dy=5;
var
x, y: integer; //координаты базовой точки грузовика
//процедура вычерчивает грузовик
procedure lorry(x, y: integer);
var
p: array[1..6] of TPoint; //координаты точек кабины
begin
with Form1.Canvas do
begin
Pen.Width:=2;
Pen.Color:=clBlack;
//кузов грузовика
Brush.Color:=clTeal;
Rectangle(x, y-10*dy, x+20*dx, y);
//кабина грузовика
p[1].X:=x+22*dx; p[1].Y:=y;
p[2].X:=x+22*dx; p[2].Y:=y-20*dy;
p[3].X:=x+27*dx; p[3].Y:=y-20*dy;
p[4].X:=x+32*dx; p[4].Y:=y-12*dy;
p[5].X:=x+35*dx; p[5].Y:=y-12*dy;
p[6].X:=x+35*dx; p[6].Y:=y;
Polygon(p);
//окно кабины
MoveTo(x+27*dx, y-20*dy);
LineTo(x+27*dx, y-12*dy);
LineTo(x+32*dx, y-12*dy);
Brush.Color:=clWhite;
FloodFill(x+28*dx, y-13*dy, clBlack, fsBorder);
//колеса грузовика
Brush.Color:=clGray;
Ellipse(x+3*dx, y, x+12*dx, y+9*dy);
Ellipse(x+23*dx, y, x+32*dx, y+9*dy);
//рама грузовика
Brush.Color:=$002B7399;
Rectangle(x, y, x+35*dx, y+dy);
end;
end;
//Обработка сигнала таймера
procedure TForm1.Timer1Timer(Sender: TObject);
begin
//стереть изображение грузовика
with Form1.Canvas do
begin
Pen.Color:=Color;
Brush.Color:=Color;
Rectangle(x, y-20*dy, x+35*dx, y+9*dy)
end;
//определить новую точку появления грузовика
if x then x:=x+5
else x:=-35*dx;
lorry(x, y); //нарисовать грузовик
end;
//Обработка события Create для формы
procedure TForm1.FormCreate(Sender: TObject);
begin
Form1.Width:=500; //ширина формы
Form1.Height:=250; //высота формы
Timer1.Interval:=100; //интервал времени работы таймера
Timer1.Enabled:=false; //таймер выключен
Button1.Caption:='Пуск'; //надпись на кнопке
x:=-35*dx; //начальная координата х грузовика
y:=150; //начальная координата y грузовика
end;
//Обработка события нажатия на кнопку
procedure TForm1.Button1Click(Sender: TObject);
begin
if Timer1.Enabled then
begin
Timer1.Enabled:=false;
Button1.Caption:='Пуск'
end
else
begin
Timer1.Enabled:=true;
Button1.Caption:='Стоп'
end
end;
end.
http://www.warayg.narod.ru/context/prog/Delphi/2/Glava10/Index17.htm
При работе с графикой удобно использовать объекты типа TBitMap (битовый образ). Битовый образ представляет собой находящуюся в памяти компьютера, и, следовательно, невидимую графическую поверхность, на которой программа может сформировать изображение. Содержимое битового образа (картинка) легко и, что особенно важно, быстро может быть выведено на поверхность формы или области вывода иллюстрации (image). Поэтому в программах битовые образы обычно используются для хранения небольших изображений, например, картинок командных кнопок.
1. Создание файла ресурсов http://www.warayg.narod.ru/context/prog/Delphi/2/Glava10/Index22.htm
Рис. |
Для того чтобы воспользоваться возможностью загрузки картинки из ресурса, необходимо сначала создать файл ресурсов, поместив в него нужные картинки. Файл ресурсов можно создать при помощи утилиты Image Editor (Редактор изображений), которая запускается выбором команды Image Editor меню Tools. Для того чтобы создать новый файл ресурсов, надо из меню File выбрать команду New, а затем в появившемся подменю команду Resource File (Файл ресурсов) В результате открывается окно нового файла ресурсов, а в строке меню окна Image Editor появляется новый пункт Resource.
Рис |
Для того чтобы в этот файл добавить новый ресурс, необходимо выбрать команду New меню Resource и из открывшегося списка тип ресурса. В данном случае следует выбрать Bitmap (битовый образ). После выбора Bitmap открывается диалоговое окно Bitmap Properties (Свойства битового образа), используя которое можно установить размер (в пикселах) и количество цветов создаваемой картинки.
Нажатие кнопки ОК в диалоговом окне Bitmap Properties вызывает появление элемента Bitmap1 в иерархическом списке Contents. Этот элемент соответствует новому ресурсу, добавленному в файл .
Bitmap1 это автоматически созданное имя ресурса, которое может быть изменено выбором команды Rename меню Resource и вводом нужного имени. После изменения имени Bitmap1 можно приступить к созданию битового образа. Для этого необходимо выбрать команду Edit меню Resource, в результате чего открывается окно графического редактора.
Рис |
Графический редактор Image Editor предоставляет программисту стандартный для подобных редакторов набор инструментов, используя которые можно нарисовать нужную картинку. Если во время работы надо изменить масштаб отображения картинки, то для увеличения масштаба следует выбрать команду Zoom In меню View, а для уменьшения команду Zoom Out. Увидеть картинку в реальном масштабе можно, выбрав команду Actual Size меню View.
Если нужная картинка уже существует в виде отдельного файла, то ее можно через буфер обмена (clipboard) поместить в битовый образ файла ресурсов. Делается это следующим образом.
Рис |
1. Сначала надо запустить графический редактор, например Microsoft Paint, загрузить в него файл картинки и выделить всю картинку или ее часть. В процессе выделения следует обратить внимание на информацию о размере (в пикселах) выделенной области (Paint выводит размер выделяемой области в строке состояния). Затем, выбрав команду Копировать меню Правка, следует поместить копию выделенного фрагмента в буфер.
2. Далее нужно переключиться в Image Editor, выбрать ресурс, в который надо поместить находящуюся в буфере картинку, и установить значения характеристик ресурса в соответствии с характеристиками картинки, находящейся в буфере. Значения характеристик ресурса вводятся в поля диалогового окна Bitmap Properties, которое открывается выбором команды Image Properties меню Bitmap. После установки характеристик ресурса можно вставить картинку в ресурс, выбрав команду Past меню Edit.
3. После добавления всех нужных ресурсов файл ресурса следует сохранить в том каталоге, где находится программа, для которой этот файл создается. Сохраняется файл ресурса обычным образом, т. е. выбором команды Save меню File. Image Editor присваивает файлу ресурсов расширение res.
2. Подключение файла ресурсов http://www.warayg.narod.ru/context/prog/Delphi/2/Glava10/Index23.htm
Для того чтобы ресурсы были доступны программе, необходимо в текст программы включить инструкцию (директиву), которая сообщит компилятору, что в файл исполняемой программы следует добавить содержимое файла ресурсов.
В общем виде эта директива выглядит следующим образом:
{$R ФайлРесурсов}
где ФайлРесурсов имя файла ресурсов. Например, директива может выглядеть так:
{$R images.res}
Директиву включения файла ресурсов в файл исполняемой программы обычно помещают в начале текста модуля.
Примечание
Если имена файла модуля программы и файла ресурсов совпадают, то вместо имени файла ресурсов можно поставить "*". В этом случае директива включения файла ресурсов в файл исполняемой программы выглядит так:
{$R *.res}
Загрузить картинку из ресурса в переменную типа TBitMap можно при помощи метода LoadFromResourceName, который имеет два параметра: идентификатор программы и имя ресурса. В качестве идентификатора программы используется глобальная переменная Hinstance. Имя ресурса должно быть представлено в виде строковой константы.
Например, инструкция загрузки картинки в переменную может выглядеть так:
Pic.LoadFromResourceName(Hinstance,'FACTORY') ;
Вывести содержимое битового образа (картинку) на поверхность формы или области вывода иллюстрации можно путем применения метода Draw к соответствующему свойству поверхности (canvas). Например, инструкция
Image1.Canvas.Draw(x,у, bm)
выводит картинку битового образа bm на поверхность компонента image 1 (параметры х и у определяют положение левого верхнего угла картинки на поверхности компонента).
Если перед применением метода Draw свойству Transparent объекта TBitMap присвоить значение True, то фрагменты рисунка, окрашенные цветом, совпадающим с цветом левого нижнего угла картинки, не будут выведены через них будет как бы проглядывать фон. Если в качестве "прозрачного" нужно использовать цвет, отличный от цвета левой нижней точки рисунка, то свойству Transparentcoior следует присвоить значение символьной константы, обозначающей необходимый цвет.
552*411 пикселей
В качестве примера в листинге 10.11 приведен текст программы, в которой изображение фона и самолета загружается из ресурсов.
Листинг 10.11. Пример загрузки картинок из ресурса
unit aplanel_;
{$R images.res} // включить файл ресурсов interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, Buttons;
type
TForm1 = class(TForm)
Timer1: TTimer;
Image1: ТImage;
procedure FormActivate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormClose(Sender: TObject;
var Action: TCloseAction); private
{ Private declarations } public
{ Public declarations } end;
var
Form1: TForm1;
Back, bitmap, Buf : TBitMap;
// фон, картинка, буфер
BackRct, BufRet: TRect;
// область фона, картинки, буфера
х,у:integer;
// координаты левого верхнего угла картинки
W,H: integer; // размеры картинки
implementation
{$R *.DFM}
procedure TForm1.FormActivate(Sender: TObject);
begin
Back := TBitmap.Create; // фон
bitmap := TBitmap.Create; // картинка
Buf := TBitmap.Create; // буфер
// загрузить из ресурса фон
Back.LoadFromResourceName(HInstance,'FACTORY');
Forml.Image1.canvas.Draw(0,0,Back);
// загрузить из ресурса картинку, которая будет двигаться
bitmap.LoadFromResourceName(HInstance,'APLANE');
bitmap.Transparent := True;
bitmap.TransParentColor := bitmap.canvas.pixels[1,1];
// создать буфер для сохранения копии области фона, на которую
// накладывается картинка
W:= bitmap.Width;
Н:= bitmap.Height;
Buf.Width:= W;
Buf.Height:=H;
Buf.Palette:=Back.Palette; // Чтобы обеспечить соответствие палитр !!
Buf.Canvas.CopyMode:=cmSrcCopy;
BufRct:=Bounds(0,0,W,H);
x:=-W; y:=20;
// определим сохраняемую область фона
BackRct:=Bounds(x,y,W,H); // и сохраним ее
Buf.Canvas.CopyRect(BufRet,Back.Canvas, BackRct);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
// восстановлением фона (из буфера) удалим рисунок Form1.image1.canvas.Draw(x,y, Buf);
x:=x+2;
if x>form1.Image1.Width then x:=-W;
// определим сохраняемую область фона
BackRct:=Bounds(x,у,W,H);
// сохраним ее копию
Buf.Canvas.CopyRect(BufRct,Back.Canvas,BackRct);
// выведем рисунок
Form1.image1.canvas.Draw(x,y,bitmap);
end;
procedure TForm1.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
Back.Free;
bitmap.Free ;
Buf.Free;
end;
end.
Преимущества загрузки картинок из ресурса программы очевидны: при распространении программы не надо заботиться о том, чтобы во время работы программы были доступны файлы иллюстраций, все необходимые программе картинки находятся в исполняемом файле.
Следующая программа, текст которой приведен в листинге 10.7, демонстрирует использование битовых образов для формирования изображения из нескольких элементов.
Листинг 10.7. Использование битовых образов
unit aplanes_; interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TForml = class(TForm)
procedure FormPaint(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Forml: TForm1;
sky,aplane: TBitMap; // битовые образы: небо и самолет
implementation
($R *.DFM}
procedure TForm1.FormPaint(Sender: TObject);
begin
// создать битовые образы
sky := TBitMap.Create;
aplane := TBitMap.Create;
// загрузить картинки
sky.LoadFromFile('sky.bmp');
aplane.LoadFromFile('aplane.bmp') ;
Form1.Canvas.Draw(0,0,sky); // отрисовка фона
Form1.Canvas.Draw(20,20,aplane); // отрисовка левого самолета
aplane.Transparent:=True;
// теперь элементы рисунка, цвет которых совпадает с цветом
// левой нижней точки битового образа, не отрисовываются Form1.Canvas.Draw(120,20,aplane);
// отрисовка правого самолета
// освободить память sky.free; aplane.free;
end;
end.
После запуска программы в окне приложения (рис. 10.14) появляется изображение летящих на фоне неба самолетов. Фон и изображение самолета -битовые образы, загружаемые из файлов. Белое поле вокруг левого самолета показывает истинный размер картинки битового образа aplane. Белое поле вокруг правого самолета отсутствует, т. к. перед его выводом свойству Transparent битового образа было присвоено значение True.
Рис. 10.14. Влияние значение свойства Transparent на вывод изображения
Проект, который вы должны разработать позволит измерять время. В данном случае это будет период, прошедший от одного момента времени до другого. И первый и второй моменты времени в проекте будут задаваться в часах и минутах. Период между этими двумя моментами мы также будем определять в часах и минутах.
Примерный интерфейс.
Составить программу "Календарь", которая определяет, является ли данный год високосным. Определение производится по следующим правилам. Если порядковый номер года не делится без остатка на 100, то год считается високосным, если его номер делится на 4 (например, 2004-й), и невисокосным, если его номер не делится на 4 (например, 2005-й). Если же номер года делится без остатка на 100, то год считается високосным, если его порядковый номер делится на 400 (например, 2000-й), и невисокосным, если его порядковый номер не делится на 400 (например, 1900-й).
Указания для выполнения задания. В форме должны быть выведены одно текстовое поле для ввода исходных данных (номера года) и три экранные кнопки: для подтверждения ввода, для очистки текстового окна и для выхода из программы. Для того чтобы поместить в форму иллюстрацию, можно поступить следующим образом: двойным щелчком на системных часах, находящихся на панели задач, открыть диалоговое окно Свойства: дата и время, в котором имеется специальное вложенное окно с изображением календаря. Затем сделать копию экрана и в графическом редакторе Paint сохранить изображение календаря в виде отдельного рисунка. Далее этот рисунок поместить В объект Image.
При написании кода рекомендуется использовать структуру с вложенными условными операторами. В заголовке основного условного оператора следует поместить условие делимости исходной даты на 100. Затем в каждой из ветвей основного условного оператора необходимо предусмотреть свой алгоритм определения високосного года, который реализуется в виде вложенного условного оператора.
Приложение.
1. События и обработка событий
Событие реакция приложения на операции ввода (перемещение мыши, нажатие клавиши и т.п.). Приложение Delphi строится как набор реакций программы на те или иные события. Основные события:
OnClick щелчок кнопкой мыши
OnDblClick двойной щелчок кнопкой мыши
OnEnter перед тем, как элемент получает фокус
OnError элемент контроля обнаруживает ошибку
OnExit - перед тем, как элемент управления теряет фокус
OnKeyDown при нажатии на клавишу
OnKeyPress при нажатой клавише
OnKeyUp при отпускании клавиши
OnMouseDown при нажатии кнопки мыши
OnMouseMove при перемещении мыши
OnMouseUp при отпускании кнопки мыши
У формы есть дополнительные события:
OnActivate перед тем, как форма получает управление
OnCreate после того, как форма создается
OnClose перед закрытием окна формы
OnDeactivate перед тем, как форма теряет управление
OnDestroy перед тем, как форма удаляется
OnPaint после отрисовки формы
OnResize при изменении размера окна формы
При двойном щелчке на событии в окне инспектора объектов создается пустая процедура-обработчик этого события.
14. Работа с графикой в окне формы
Canvas клиентская область формы; изучим ее основные свойства:
Brush цвет и шаблон заполнения для кисти;
Brush.Color:=clYellow;
Brush.Style:=bsBdiagonal;
//Другие стили: сплошная - bsSolid нет заливки - bsClear
ClicpRect координаты отсекающего прямоугольника на экране (только чтение)
Rectangle (ClipRect.Left,ClipRect.Top,ClipRect.Right,ClipRect.Bottom);
Var R: TRect;
R := Canvas.GetClientRect;
Canvas.Rectangle(R.Left, R.Top, R.Right, R.Bottom);
CopyMode режим вывода графики
cmSrcCopy обычное наложение, cmNotSrcCopy инверсия цвета, cmMergeCopy наложение «И»
Font шрифт для вывода на форму
With Canvas do begin
Font.Color:=clBlue;
Font.Name:=Arial;
Font.Size:=14;
Font.Style:=[fsItalic];
end;
Pen тип карандаша для отрисовки линий и границ фигур
Pen.Width ширина в пикселах, Color цвет, Mode режим наложения рисования линий (pmCopy, pmNotCopy, pmMerge), Style тип линии (psSolid, psDash, psDot)
Pixels[x,y] массив цветов пикселов
…и методы :
Arc(Left,Top, Right,Bottom, x3, y3, x4, y4); рисует дугу
Left,Top, Right,Bottom, - координаты прямоугольника, в который вписана дуга, (x3,y3),(x4,y4) через эти точки проходят прямые из центра эллипса, определяющие начало и конец дуги
Ellipse (Left,Top, Right,Bottom); рисует эллипс
FillRect заливка области цветом кисти
Var R:TRect;
R:=Rect(20,20,150,150);
Canvas.Brush.Color:=clRed;
Canvas.FillRect (R);
LineTo (X,Y) линия из позиции пера в точку (X,Y)
MoveTo (X,Y) установить перо в точку (X,Y)
Polygon отрисовка замкнутого прямоугольника
Canvas.Brush.Color:=clRed;
Canvas.Polygon ([Point(10,10),Point (30,10),Point(130,30)];
PolyLine незамкнутый многогранник
Rectangle (x1,y1,x2,y2); прямоугольник по 2 указанным углам
TextHeight, TextWidth определяют высоту и ширину строки в пикселах:
procedure TForm1.FormPaint(Sender: TObject);
var s:String;
begin
s:='Delphi';
with Canvas do begin
Pen.Color:=clRed;
Brush.Style:=bsClear;
TextOut (10,10,s);
Rectangle (10,10,10+TextWidth(s),10+TextHeight(s));
end;
end;
Draw отрисовка графики на форме:
procedure TForm1.FormPaint(Sender: TObject);
var BitMap:TBitmap;
begin
Bitmap := TBitmap.Create;
Bitmap.LoadFromFile('c:\Windows\Паркет.bmp');
Canvas.Draw(0, 0, Bitmap);
Bitmap.Free;
end;
Приложение «Простейший калькулятор» http://codingrus.ru/readarticle.php?article_id=2226
Исходный код программы "Калькулятор" с блок схемами
Создадим программу, которая представляет собой арифметический калькулятор, производящий четыре действия над действительными числами. Проектируемый калькулятор должен функционировать следующим образом: пользователь вводит первый операнд, выбирает операцию, затем вводит второй операнд и нажимает «равно». При этом происходит вычисление результата соответствующей операции и его отображение в строке данных калькулятора. Ввод операндов и операций осуществляется путем нажатия кнопки на самом калькуляторе.
Создание новой программы на Delphi начинается с выбора опции File/ New Application. Это означает, что начинается работа над новым приложением для Windows.
Сохраните созданный проект в папке Калькулятор, назвав файл проекта - Calc, а файл модуля формы - CalcUnit.
В окне инспектора объектов изменим свойства элементов формы в соответствии со следующим описанием:
Создайте поле ввода-вывода информации Edit1 и кнопки Button1- Button17 (для кнопок с цифрами, десятичной точкой и действиями). Разместите компоненты на форме в соответствии с рисунком:
Рис. Внешний вид формы проектируемого калькулятора.
В окне инспектора объектов изменить свойства элементов формы в соответствии с таблицей:
Перед созданием обработчиков введем несколько соглашений:
1. Пусть некоторый признак (флаг f) f=1, если над двумя введенными числами произведена операция сложения; f=2, если над двумя введенными числами произведена операция вычитания; f=3, если
над двумя введенными числами произведена операция умножения; f=4, если над двумя введенными числами произведена операция деления и f=5, если была нажата клавиша равно.
2. Необходимо учесть, что арифметические операции вводится циклически (например, после выполнения операции, когда на индикаторе результат). Поэтому введем переменную zifra, которая будет отвечать за ввод следующего числа. Переменная zifra будет иметь значение false, если не введена цифра нового числа, а true, если введена первая цифра нового числа.
3. В программе потребуется использование переменных. Опишем их в разделе var следующим
образом:
Здесь переменная a хранит первое число, b второе число, c результат.
4. При запуске приложения Калькулятор, входящего в состав ОС Windows, в строке ввода
данных отображается «0», реализуем такую возможность в нашем приложении, также
установим предварительное значение признака (флага), которое будет уму присвоено после
открытия формы, а также признака того, что число не вводилось. Это делается следующей
процедурой:
5. При нажатии на любой кнопке с числом (при вводе операндов), введенный символ должен
отображаться в текстовом поле edInput (исключение составляет случай, когда ноль
вводится как первый символ числа). При этом необходимо различать первая ли цифра в
числе, или нет. Также необходимо менять значение признака zifra при вводе первой цифры
числа. Это делается следующими процедурами:
6. Аналогично запишутся обработчики для компонентов bt_3, bt_4, … bt_9, bt_0.
7. Необходимо учесть, что в действительном числе может быть только одна запятая, отделяющая
целую часть от дробной, т.е. повторное нажатие на кнопку с изображением запятой игнорируется.
Запрограммируем кнопку «,» (компонент btPoint):
8. Если нажимается кнопка «Сброс», надо обнулить значение a,b и f, очистить поле edInput и
параметру zifra задать значение false. Т.о. обработчик нажатия на кнопке, т.е. на событие
Click следующий:
9. Если же нажимается кнопка для совершения действия (/, *, -, +), то флагу надо дать
соответствующее значение, чтобы после ввода второго операнда и нажатия на кнопке
равно, знать какое действие совершать между первым a и вторым b операндом. Но надо
учесть, что если перед нажатием на кнопке с операцией была нажата кнопка равно (f=5), то
предыдущие вычисления продолжаются, и полученный результат должен теперь выступать
в роли первого операнда, т.е. надо выполнить команду a:=c. Т.о. обработчики нажатий
кнопок с действиями (/, *, -, +), т.е. на событие Click следующие:
10. Если же нажимается кнопка равно, то в зависимости от значения флага f надо произвести
одно из четырех действий: 1-«+», 2-«-», 3-«*», 4-«/» и после этого флагу дать значение f=5.
Т.о. обработчик нажатия на кнопке равно, т.е. на событие Click следующий:
11. Известное Вам приложение Калькулятор, входящего в состав ОС Windows, предполагает
ввод операндов с клавиатуры. Запрограммируем это событие компонента edInput, но
учтем, что в поле можно вводить только цифры и одну запятую:
12. Запустите созданное приложение, исправьте (если они появятся) ошибки. После
тестирования откомпилируйте проект и запустите готовое приложение.
P.S. Для того что бы калькулятор считал подряд, т.е. выдавал результат при нажатие операции, необходимо дописать к обработчику кнопки каждой операции код:
SpeedButton17Click(Sender);
Полностью обработчик нажатия на кнопку:
procedure TForm1.SpeedButton11Click(Sender: TObject);
begin
SpeedButton17Click(Sender); //если была операция то вычисляем
if f=5
then a:=c
else a:=strtofloat(edit1.Text);
f:=3;
zifra:=false;
end;
Материал взят с сайта http://www.delphikingdom.ru
2
0
0
0
0
1
3
4
5
6
7
2
0
0
0
0
1
3
4
400-r,200-r
400+r,200+r