Министерство образования и науки Российской федерации Бузулукский гуманитарно-технологический институт (филиал) федерального государственного бюджетного образовательного учреждения высшего профессионального образования «Оренбургский государственный университет» Кафедра физики, информатики и математики Литвинова С.А. ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ Рекомендовано к изданию Редакционно-издательским советом федерального государственного бюджетного образовательного учреждения высшего профессионального образования «Оренбургский государственный университет» в качестве методических указаний к лабораторным работам для студентов, обучающихся по программе высшего профессионального образования (бакалавриат) по направлению подготовки 050100.62 «Педагогическое образование» Бузулук 2012 УДК 004.382.7 ББК 32.973.26 – 018.1 Л 64 Рецензент инженер 1 категории ООО «ТБинформ» Федянина Т.В. Литвинова, С.А. Объектно-ориентированное программирование: методические указания к лабораторным работам / С.А. Литвинова: Бузулукский гуманитарнотехнологический институт (филиал) ОГУ. – Бузулук: БГТИ (филиал) ОГУ, 2012. – 59с. Методические указания содержат общие понятие объектноориентированного программирования, краткие сведения о среде программирования Delphi. Методические указания предназначены для выполнения лабораторных работ по дисциплине «Объектно-ориентированное программирование» для студентов направления подготовки 050100.62 «Педагогическое образование» УДК 004.382.7 ББК 32.973.26 – 018.1 © Литвинова С.А., 2012 © БГТИ (филиал) ОГУ, 2012 2 Оглавление 1 Основные теоретические сведения ........................................................................ 4 1.1 Понятие объектно-ориентированного программирования ............................... 4 1.2 Объекты и классы.................................................................................................. 4 1.3 Инкапсуляция ........................................................................................................ 5 1.4 Наследование ......................................................................................................... 5 1.4.1 Виртуальные методы ......................................................................................... 6 1.4.2 Динамическое создание объектов .................................................................... 6 1.5 Полиморфизм ........................................................................................................ 7 1.6 Общие сведения о языке Delphi ........................................................................... 7 1.6.1 Окно формы ........................................................................................................ 9 1.6.2 Окно дерева объектов ...................................................................................... 10 1.6.3 Окно инспектора объектов .............................................................................. 10 1.6.4 Окно кода программы ...................................................................................... 12 1.7 Основные компоненты Delphi ........................................................................... 14 1.7.1 Стандартные компоненты ............................................................................... 15 2 Лабораторные работы ............................................................................................ 17 2.1 Лабораторная работа «Изменение заголовка формы» .................................... 17 2.2 Лабораторная работа «Случайный выбор из списка» ..................................... 18 2.3 Лабораторная работа «Бросок кубика» ............................................................. 19 2.4 Лабораторная работа «Применение полос прокрутки» .................................. 20 2.5 Лабораторная работа «Прыгающая кнопка» .................................................... 22 2.6 Лабораторная работа «Таблица умножения» ................................................... 24 2.7 Лабораторная работа «Светофор» ..................................................................... 25 2.8 Лабораторная работа «Вычисление процентов» ............................................. 27 2.9 Лабораторная работа «Строковый калькулятор» ............................................ 29 2.10 Лабораторная работа «Электронные часы» ................................................... 30 2.11 Лабораторная работа «Разработка простых приложений» ........................... 32 2.12 Лабораторная работа «Создание главного и контекстного меню» .............. 33 2.13 Лабораторная работа «Подсказки к кнопкам» ............................................... 41 2.14 Лабораторная работа «Создание панели инструментов» ............................. 55 3 Рекомендуемая литература ................................................................................... 58 3 1 Основные теоретические сведения 1.1 Понятие объектно-ориентированного программирования Объектно-ориентированное программирование (ООП) – методология программирования, которая основана на представлении программы в виде совокупности объектов, каждый из которых является реализацией определенного класса (типа особого вида), а классы образуют иерархию на принципах наследуемости». Элементы ООП появились в начале 70-х годов в языке моделирования Симула (первый язык программирования, в котором были предложены принципы объектной ориентированности), затем получили свое развитие, и в настоящее время ООП принадлежит к числу ведущих технологий программирования. Основная цель ООП, как и большинства других подходов к программированию повышение эффективности разработки программ. ООП является одним из наиболее интересных направлений для профессиональной разработки программ. Использование ООП позволяет существенно не изменять программу, сводя необходимую модификацию программы к её расширению и дополнению. Изучение идей и методов ООП может существенно упростить разработку и отладку сложных программ. Обычно мы используем в своих программах процедуры и функции для программирования тех сложных действий по обработке данных, которые приходится выполнять многократно. Впоследствии начали использоваться подпрограммы. Она может иметь формальные предметы, которые при обращении к ней заменяются фактическими предметами. В этом случае есть опасность вызова подпрограммы с неправильными данными, что может привести к сбою программы и её аварийному завершению при выполнении. Поэтому естественным обобщением традиционного подхода к программированию является объединение данных и подпрограмм (процедур и функций), предназначенных для их обработки. 1.2 Объекты и классы Базовыми в ООП являются понятие объекта и класса. Объект часть окружающей нас реальности, т. е. он существует во времени и в пространстве. Формально объект определить довольно трудно. Это можно сделать через некоторые свойства, а именно: объект имеет состояние, поведение и может быть однозначно идентифицирован (другими словами, имеет уникальное имя). Программа, написанная с использованием ООП, состоит из объектов, которые могут взаимодействовать между собой. Класс множество объектов, имеющих общую структуру и общее поведение. Класс описание (абстракция), которое показывает, как построить 4 существующую во времени и пространстве переменную этого класса, называемую объектом. Смысл предложений «описание переменных класса» и «описание объектов класса» один и тот же. Переменные объектного типа называют экземплярами объекта. Здесь требуется уточнение экземпляр можно лишь формально назвать переменной. Его описание дается в предложение описания переменных, но в действительности экземпляр нечто большее, чем обычная переменная. Объектный тип содержит не только поля, описывающие данные, но также процедуры и функции, описания которых содержится в описании объекта. Эти процедуры и функции называют методами. Методам объекта доступны его поля. Следует отметить, что методы и их параметры определяются в описании объекта, а их реализация даётся вне этого описания, в том мест программы, которое предшествует вызову данного метода. Объект описывается с помощью зарезервированных слов «object…end», между которыми находиться описание полей и методов. 1.3 Инкапсуляция Инкапсуляция является важнейшим свойством объектов, на котором строится ООП. Инкапсуляция заключается в том, что объект скрывает в себе детали, которые несущественны для использования объекта. В традиционном подходе к программированию с использованием глобальных переменных программист не был застрахован от ошибок, связанных с использованием процедур, не предназначенных для обработки данных, связанных с этими переменными. Инкапсуляция и является средством организации доступа к данным только через соответствующие методы. Инкапсуляция позволяет в максимальной степени изолировать объект от внешнего окружения. Она существенно повышает надежность разрабатываемых программ, т.к. локализованные в объекте алгоритмы обмениваются с программой сравнительно небольшими объемами данных, причем количество и тип этих данных обычно тщательно контролируется. В результате замена или модификация алгоритмов и данных, инкапсулированных в объект, как правило, не влечет за собой плохо прослеживаемых последствий для программы в целом. Другим немаловажным следствием инкапсуляции является легкость обмена объектами, переноса их из одной программы в другую. 1.4 Наследование Наследование это еще одно базовое понятие объектноориентированного программирования. Наследование позволяет определять новые объекты, используя свойства прежних, дополняя или изменяя их. Объект-наследник получает все поля и методы «родителя», к которым он может добавить свои собственные поля и методы или заменить их своими методами. Наследник не содержит описание полей и методов родителя. Имя последнего 5 указывается в круглых скобках после слова «object». Из методов наследника можно вызывать методы родителя. Для создания наследника не требуется иметь исходный текст объекта родителя. Объект-родитель может быть уже в составе оттранслированного модуля. Плюс в наследовании: если некий объект был уже определен и отлажен, он может быть использован и в других программах. При этом может оказаться, что новая задача отличается от предыдущей, и возникает необходимость некоторой модификации как данных, так и методов их обработки. Программисту приходится решать дилемму создания объектов заново или использовать результаты предыдущей работы, применяя механизм наследования. Первый путь менее эффективен, так как требует дополнительных затрат времени на отладку и тестирование. Во втором случае часть этой работы оказывается выполненной, что сокращает время на разработку новой программы. Программист при этом может и не знать деталей реализации объекта-родителя. 1.4.1 Виртуальные методы Чтобы использовать виртуальный метод, необходимо в описании объекта после заголовка метода добавить ключевое слово «virtual». Заголовки виртуальных методов родителя и наследника должны в точности совпадать. Инициализация экземпляра объекта, имеющего виртуальные методы, должна выполняться с помощью специального метода конструктора. Конструктор обычно присваивает полям объекта начальные значения и выполняет другие действия по инициализации объекта. В заголовке методаконструктора слово «procedure» заменяется словом «constructor». Действия обратные действиям конструктора, выполняет ещё один специальный метод деструктор. Он описывается словом «destructor». Конструктор выполняет действия по подготовке позднего связывания. Эти действия заключаются в создании указателя на таблицу виртуальных методов, которая в дальнейшем используется для поиска методов. Таблица содержит адреса всех виртуальных методов. При вызове виртуального метода по его имени определяется адрес, а затем по этому адресу передается управление. У каждого объектного типа имеется своя собственная таблица виртуальных методов, что позволяет одному и тому же оператору вызывать разные процедуры. Каждый объект должен иметь свой собственный конструктор, который вызывается для каждого экземпляра. В противном случае возможен сбой в работе программы. Конструктор или деструктор, могут не содержать операторов. Весь необходимый код в этом случае создается при трансляции ключевых слов «construct» и «destruct». 1.4.2 Динамическое создание объектов Переменные объектного типа могут быть динамическими, то есть размещаться в памяти только во время их использования. Для работы с динамическими объектами используются расширенный синтаксис процедур «new» и «dispose». Обе процедуры в этом случае содержат в качестве второго параметра вызов конструктора или деструктора для выделения или освобождения памяти переменной объектного типа. 6 Применение расширенного синтаксиса не только улучшает читаемость исходного кода, но и генерирует более короткий и эффективный исполняемый код. 1.5 Полиморфизм Полиморфизм – это свойство родственных объектов (т.е. объектов, имеющих одного родителя) решать схожие по смыслу проблемы разными способами. Два или более класса, которые являются производными одного и того же базового класса, называются полиморфными. Это означает, что они могут иметь общие характеристики, но так же обладать собственными свойствами. В рамках ООП поведенческие свойства объекта определяются набором входящих в него методов. Изменяя алгоритм того или иного метода в потомках объекта, программист может придавать этим потомкам отсутствующие у родителя специфические свойства. Для изменения метода необходимо перекрыть его в потомке, т.е. объявить в потомке одноименный метод и реализовать в нем нужные действия. В результате чего в объекте-родителе и объекте-потомке будут действовать два одноименных метода, имеющих разную алгоритмическую основу и, следовательно, придающие объектам разные свойства. Это и называется полиморфизмом объектов. 1.6 Общие сведения о языке Delphi Delphi (Делфи) – среда программирования, в которой используется язык программирования Object Pascal. Изначально язык был предназначен исключительно для разработки приложений Microsoft Windows, затем был реализован также для платформ Linux (как Kylix), однако после выпуска в 2002 году Kylix 3 его разработка была прекращена, и, вскоре после этого, было объявлено о поддержке Microsoft .NET. Реализация языка Delphi проектом Free Pascal позволяет использовать его для создания приложений для таких платформ, как Mac OS X, Windows CE и Linux. Delphi результат развития языка Турбо Паскаль, который, в свою очередь, развился из языка Паскаль. Паскаль был полностью процедурным языком, Турбо Паскаль начиная с версии 5.5 добавил в Паскаль объектноориентированные свойства, а Delphi объектно-ориентированный язык программирования с возможностью доступа к описанию классов и их членов в компилируемом коде, также называемом интроспекцией. Так как все классы наследуют функции базового класса TObject, то любой указатель на объект можно преобразовать к нему, и воспользоваться методом ClassType и функцией TypeInfo, которые и обеспечат интроспекцию. Также отличительным свойством Дельфи от С++ является отсутствие возможности располагать объекты в стеке (объекты, унаследованные из Турбо Паскаля, располагаться в стеке могут) – все объекты попадают в динамически выделяемую область. Object Pascal, а затем и 7 язык Delphi являются функциональными наращиваниями Turbo Pascal. Об этом говорят обозначения версий компилятора. Так, в Delphi 7 компилятор имеет номер версии 15.0 (Последняя версия Borland Pascal / Turbo Pascal обозначалась 7.0, в Delphi 1 компилятор имеет версию 8.0, в Delphi 2 9.0, и т. д. Номер версии 11.0 носит компилятор Pascal, входивший в состав среды C++Builder). Delphi оказал огромное влияние на создание концепции языка C++ для платформы .NET. Многие его элементы и концептуальные решения вошли в состав С++. Одной из причин называют переход Андерса Хейлсберга, одного из ведущих разработчиков Дельфи, из компании Borland Ltd. в Microsoft Corp. Версия 1 была предназначена для разработки под 16-ти разрядную платформу Win16; Версии со второй компилируют программы под 32-х разрядную платформу Win32; Вместе с шестой версией Delphi вышла совместимая с ним по языку и библиотекам среда Kylix, предназначенная для компиляции программ под операционную систему Linux; Версия восемь способна генерировать байт-код исключительно для платформы .NET. Это первая среда, ориентированная на разработку мультиязычных приложений (лишь для платформы .NET); Последующие версии (обозначаемые годами выхода, а не порядковыми номерами, как это было ранее) могут создавать как приложения Win32, так и байт-код для платформы .NET; Delphi for .NET – среда разработки Delphi, а так же язык Delphi (Object Pascal), ориентированные на разработку приложений для .NET. Первая версия полноценной среды разработки Delphi для .NET – Delphi 8. Она позволяла писать приложения только для .NET. В настоящее время, в Delphi 2006, можно писать приложения для .NET используя стандартную библиотеку классов .NET, VCL для .NET. В марте 2006 года компания Borland приняла решение о прекращении дальнейшего совершенствования интегрированных сред разработки JBuilder, Delphi и C++Builder по причине убыточности этого направления. Планируется продажа IDE-сектора компании. Группа сторонников свободного программного обеспечения организовала сбор средств для покупки у Borland прав на среду разработки и компилятор. Однако в ноябре того же года было принято решение отказаться от продажи IDE бизнеса. Тем не менее, разработкой IDE продуктов теперь будет заниматься новая компания CodeGear, которая будет финансово полностью подконтрольна Borland. Borland продолжил развитие IDE систем под именем Turbo: Turbo Delphi, Turbo Delphi for .NET, Turbo C#, Turbo C++ А в марте 2007 года CodeGear порадовала пользователей обновленной линейкой продуктов Delphi 2007 for Win32 и выходом совершенно нового продукта Delphi 2007 for PHP. Delphi это комбинация нескольких важнейших технологий: высокопроизводительный компилятор в машинный код; объектно-ориентированная модель компонент; 8 визуальное (а, следовательно, и скоростное) построение приложений из программных прототипов; масштабируемые средства для построения баз данных; компилятор в машинный код. Компилятор, встроенный в Delphi, обеспечивает высокую производительность, необходимую для построения приложений в архитектуре «клиент-сервер». Этот компилятор в настоящее время является самым быстрым в мире, его скорость компиляции составляет свыше 120 тысяч строк в минуту на компьютере 486DX33. Он предлагает легкость разработки и быстрое время проверки готового программного блока, характерного для языков четвертого поколения и в то же время обеспечивает качество кода, характерного для компилятора 3GL. Кроме того, Delphi обеспечивает быструю разработку без необходимости писать вставки на Си или ручного написания кода (хотя это возможно). В процессе построения приложения разработчик выбирает из палитры компонент готовые компоненты как художник, делающий крупные мазки кистью. Еще до компиляции он видит результаты своей работы после подключения к источнику данных их можно видеть отображенными на форме, можно перемещаться по данным, представлять их в том или ином виде. В этом смысле проектирование в Delphi мало чем отличается от проектирования в интерпретирующей среде, однако после выполнения компиляции мы получаем код, который исполняется в 10-20 раз быстрее, чем то же самое, сделанное при помощи интерпретатора. Кроме того, компилятор компилятору рознь, в Delphi компиляция производится непосредственно в родной машинный код, в то время как существуют компиляторы, превращающие программу в так называемый pкод, который затем интерпретируется виртуальной p-машиной. Это не может не сказаться на фактическом быстродействии готового приложения. 1.6.1 Окно формы Окно формы представляет собой проект Windows-окна будущей программы. Вначале это окно пусто. Точнее, оно содержит стандартные для Windows интерфейсные элементы – кнопки вызова системного меню, максимизации, минимизации и закрытия окна, полосу заголовка и очерчивающую рамку. Вся рабочая область окна обычно заполнена точками координатной сетки, служащей для упорядочения размещаемых на форме компонентов (вы можете убрать эти точки, вызвав с помощью меню Tools | Environment options соответствующее окно настроек и убрав флажок в переключателе Display Grid на окне, связанном с закладкой Preferences). Значительную часть времени программист занят увлекательным занятием, напоминающим работу с набором деталей конструктора Lego: он «достает» из палитры компонентов, как из коробки с деталями, нужный компонент и размещает его на «наборном поле» окна формы, постепенно заполняя форму интерфейсными элементами. Собственно, именно в этом процессе наполнения формы и заключается главная изюминка визуального программирования. Программист в любой момент времени контролирует 9 содержание окна создаваемой программы и может внести в него необходимые изменения. 1.6.2 Окно дерева объектов Это окно появилось в версии 6 и предназначено для наглядного отображения связей между отдельными компонентами, размещенными на активной форме или в активном модуле данных. Щелчок по любому компоненту в этом окне активизирует соответствующий компонент в окне формы и отображает свойства этого компонента в окне Инспектора объектов. Двойной щелчок приводит к срабатыванию механизма Code Insight, который вставляет в окно кода заготовку для обработчика события OnClick. Наконец, компонент можно «перетащить» в окне и таким образом поменять его владельца (свойство parent). В предыдущих версиях такую замену можно было сделать только с помощью межпрограммного буфера обмена Clipboard. 1.6.3 Окно инспектора объектов Любой размещаемый на форме компонент характеризуется некоторым набором параметров: положением, размером, цветом и т.д. Часть этих параметров, например, положение и размеры компонента, программист может изменять, манипулируя с компонентом в окне формы. Для изменения других параметров предназначено окно Инспектора объектов. Это окно содержит две страницы – Properties (Свойства) и Events (События). Страница properties служит для установки нужных свойств компонента, страница Events позволяет определить реакцию компонента на то или иное событие. Совокупность cвойств отображает видимую сторону компонента: положение относительно левого верхнего угла рабочей области формы, его размеры и цвет, шрифт и текст надписи на нем и т. п.; совокупность событий – его поведенческую сторону: будет ли компонент реагировать на щелчок мыши или на нажатие клавиш, как он будет вести себя в момент появления на экране или в момент изменения размеров окна и т. п. Каждая страница окна Инспектора объектов представляет собой двухколончатую таблицу, левая колонка которой содержит название свойства или события, а правая – конкретное значение свойства или имя, обрабатывающей соответствующее событие. Строки таблицы выбираются щелчком мыши и могут отображать простые или сложные свойства. К простым относятся свойства, определяемые единственным значением – числом, строкой символов, значением True (Истина) или False (Ложь) и т. п. Например, свойство caption (Заголовок) представляется строкой символов, свойства Height (Высота) и width (Ширина) – числами, свойство Enabled (Доступность) –значениями True или False. Сложные свойства определяются совокупностью значений. Слева от имени таких свойств указывается значок «+», а щелчок мышью по этому символу приводит к раскрытию списка составляющих сложного свойства. Чтобы закрыть раскрытый список, нужно щелкнуть по значку «-» сложного свойства. В верхней части окна Инспектора объектов располагается раскрывающийся список всех помещенных на форму компонентов. Поскольку форма сама по себе является компонентом, ее имя также присутствует в этом 10 списке. В отличие от предыдущих версий раскрывающийся список содержит не только имена компонентов, но и их классы. В локальном меню окна, которое появляется после щелчка по нему правой кнопкой, имеется ряд опций, позволяющих настроить окно. В частности, после выбора stay on Top, окно Инспектора объектов будет «всплывать» над всеми другими окнами независимо от его активности. Такое состояние окна удобно при частом его использовании, например, при конструировании сложной формы, содержащей множество компонентов. Если выбрать в локальном меню опцию Arrange и затем by Category, все строки окна Инспектора объектов будут представлять собой раскрывающиеся списки свойств, упорядоченные по категориям (рисунок 1). Рисунок 1– Списки свойств упорядоченные по категориям Любые категории можно сделать невидимыми. Для этого нужно в локальном меню выбрать view и затем в дополнительном меню убрать флажок слева от категории. В отличие от предыдущих версий Delphi в версии 6 сложные свойства, ссылающиеся на объекты, выделяются в окне Инспектора объектов цветом и показываются на странице Events. Если такое свойство определено, слева от него появляется кнопка «+», позволяющая увидеть (и при необходимости изменить) свойства и обработчики событий связанного объекта. Для примера на рисунке 2 показано, как с помощью окна Инспектора объектов, связанного с формой Form1, определить обработчик OnClick для одной из опций связанного с формой меню. 11 С помощью опции properties локального меню окна Инспектора объектов можно отменить такую его функциональность, если в списке SpeedSettings соответствующего диалогового окна выбрать Delphi 5 emulation. Рисунок 2 – Установка обработчика OnClick опции меню для формы Form1 1.6.4 Окно кода программы Окно кода предназначено для создания и редактирования текста программы. Этот текст составляется по специальным правилам и описывает алгоритм работы программы. Совокупность правил записи текста называется языком программирования. В системе Delphi используется язык программирования Object Pascal, который представляет собой расширенную и усовершенствованную версию широко распространенного языка Паскаль, впервые предложенного швейцарским ученым Н. Виртом еще в 1970г. и усовершенствованного сотрудниками корпорации Borland (созданные ими языки назывались Turbo Pascal, Borland Pascal и Object Pascal). Несмотря на то, что визуальная среда Delphi берет на себя многие рутинные аспекты программирования, знание языка Object Pascal является непременным условием для любого программиста, работающего в этой среде. Первоначально окно кода содержит минимальный исходный текст, обеспечивающий нормальное функционирование пустой формы в качестве полноценного Windows-окна. В ходе работы над проектом программист вносит в него необходимые дополнения, чтобы придать программе нужную функциональность. Поскольку для создания даже простых программ вам понадобится создавать и изменять (редактировать) код программы, ниже описываются основные приемы работы с окном кода. 12 Сразу после открытия нового проекта в нем будут такие строки: unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Frms, Dialogs; type TFormI = class(TForm) private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {SR *.DFM} end. Эти строки Delphi автоматически вставляет в окно кода для новой формы. Как уже говорилось, окно кода определяет поведенческую сторону окна программы (т. е. окна, появляющегося после начала работы программы), а окно формы - его внешние проявления. Оба окна тесно связаны друг с другом, причем Delphi «хозяйничает» в его верхней части, вставляя необходимые строки между unit Unit1; и implementation Пока не стоит изменять эту часть текста. В дальнейшем можно будет вставлять в окно текст программы между строками {$R-*.DFM} и end. в нижней части окна. Чтобы вставить в окно новую строку (строки), нужно сначала, с помощью клавиш курсора или щелкнув по окну мышью, поставить текстовый указатель (мигающую вертикальную черту) на нужное место, а затем с помощью клавиатуры ввести текст. Обычно текст кода программы располагается в нескольких строках. Для перехода на новую строку используйте клавишу Enter. Если в процессе ввода вы ошиблись и тут же заметили свою ошибку, удалите ошибочный символ клавишей Backspace (продолговатая серая клавиша в правом верхнем углу зоны алфавитноцифровых клавиш или расположенная там же клавиша с левой стрелкой). Клавиша Backspace удаляет символ слева от мигающего указателя, а клавиша Delete - справа от него. Если понадобится удалить сразу всю строку текста, поставьте в любое место строки мигающий указатель, нажмите клавишу Ctrl и, не отпуская ее, клавишу с латинской буквой Y. Такое совместное нажатие клавиш в дальнейшем будем обозначать символом «+»: Ctrl+Y. Чтобы отменить последнее изменение текста, нажмите Ctrl+Z. После сохранения проекта появляется целый перечень сохраняемых файлов: 13 DPR – файл проекта. Содержит он основной код программы, ссылки на все окна (формы) проекта и относящиеся к ним модули. В нем также содержится код инициализации. Имеет одноименное название с проектом; PAS – pascal файл. Он содержит текст, который вы видите в окне редактора кода так называемого модуля программы; DFM – delphi form. Представляет собой файл с полными данными о проектировщике формы. Позиция, размер, расположенные компоненты и пр. Форма приложения является неотъемлемой частью модуля PAS и имеет то же название; DCU – двоичный файл модуля. Имеет одноименное название с модулем; RES – ресурсный файл. Содержит в себе иконки, значки указателя мыши, картинки, звуки; DOF, DSK – содержат настройки проекта; CFG – содержит настройки конфигурации проекта; EXE – откомпилированная программа. Сохраняется автоматически при запуске проекта на выполнение. Обновляется в момент компиляции. Имеет одноименное название проекта. Полностью самостоятельное приложение; По ходу работы в среде Delphi могут автоматически создаваться файлы, имеющие расширение, начинающееся символом ~. Это резервные копии файлов, которые создаются при их повторном сохранении. 1.7 Основные компоненты Delphi Для того, чтобы наполнить форму содержанием используем компоненты Delphi. Они располагаются на соответствующих вкладках палитры компонентов на главном окне. Рисунок 3 – Вкладки компонентов Delphi Все основные компоненты Delphi находятся на первых четырех вкладках: Standard; Additional; Win32; System. Их названия всплывают в виде подсказок при наведении мышки на пиктограммы. Чтобы перенести компонент на форму, нужно щёлкнуть его 14 мышкой (при этом выбранный компонент выделяется), и затем щёлкнуть в том месте формы, где его предполагается разместить. В дальнейшем компоненты можно свободно перетаскивать по форме мышкой, «конструируя» нужный интерфейс. Если, щёлкнув по компоненту, мы захотим отказаться от его переноса на форму, то необходимо щёлкнуть по стрелке, расположенной слева на вкладке. Выделение компонента снимется. 1.7.1 Стандартные компоненты Первым компонентом в среде программирования Delphi является страница Палитры Компонент. На первой странице Палитры Компонент размещены 14 объектов определенно важных для использования. Набор и порядок компонент на каждой странице являются конфигурируемыми. При необходимости можно добавить к имеющимся компонентам новые, изменить их количество и порядок. Стандартные компоненты Delphi перечислены ниже с некоторыми комментариями по их применению. При изучении данных компонент было бы полезно иметь под рукой компьютер с тем, чтобы посмотреть, как они работают и как ими манипулировать. TMainMenu позволяет поместить главное меню в программу. При помещении TMainMenu на форму это выглядит, как просто иконка. Иконки данного типа называют «невидимыми компонентом», поскольку они невидимы во время выполнения программы. Создание меню включает три шага: помещение TMainMenu на форму, вызов Дизайнера Меню через свойство Items в Инспекторе Объектов, определение пунктов меню в Дизайнере Меню. TPopupMenu позволяет создавать всплывающие меню. Этот тип меню появляется по щелчку правой кнопки мыши. TLabel служит для отображения текста на экране. Можно изменить шрифт и цвет метки, если дважды щелкнете на свойство Font в Инспекторе Объектов. TEdit – стандартный управляющий элемент Windows для ввода. Он может быть использован для отображения короткого фрагмента текста и позволяет пользователю вводить текст во время выполнения программы. TMemo – иная форма TEdit. Подразумевает работу с большими текстами. TMemo может переносить слова, сохранять в Clipboard фрагменты текста и восстанавливать их, и другие основные функции редактора. TMemo имеет ограничения на объем текста в 32Кб, это составляет 10-20 страниц. (Есть VBX и «родные»компоненты Delphi, где этот предел снят). TButton позволяет выполнить какие-либо действия при нажатии кнопки во время выполнения программы. В Delphi все делается очень просто. Поместив TButton на форму, Вы по двойному щелчку можете создать заготовку обработчика события нажатия кнопки. Далее нужно заполнить заготовку кодом (подчеркнуто то, что нужно написать вручную): procedure TForm1.Button1Click(Sender: TObject); begin 15 MessageDlg('Are you there?',mtConfirmation,mbYesNoCancel,0); end; TCheckBox отображает строку текста с маленьким окошком рядом. В окошке можно поставить отметку, которая означает, что что-то выбрано. Например, если посмотреть окно диалога настроек компилятора (пункт меню Options | Project, страница Compiler), то можно увидеть, что оно состоит преимущественно из CheckBox'ов. TRadioButton позволяет выбрать только одну опцию из нескольких. Если опять открыть диалог Options | Project и выберете страницу Linker Options, то можно видеть, что секции Map file и Link buffer file состоят из наборов RadioButton. TListBox нужен для показа прокручиваемого списка. Классический пример ListBox'а в среде Windows – выбор файла из списка в пункте меню File | Open многих приложений. Названия файлов или директорий и находятся в ListBox'е. TComboBox во многом напоминает ListBox, за исключением того, что позволяет водить информацию в маленьком поле ввода сверху ListBox. Есть несколько типов ComboBox, но наиболее популярен выпадающий вниз (dropdown combo box), который можно видеть внизу окна диалога выбора файла. TScrollbar – полоса прокрутки, появляется автоматически в объектах редактирования, ListBox'ах при необходимости прокрутки текста для просмотра. TGroupBox используется для визуальных целей и для указания Windows, каков порядок перемещения по компонентам на форме (при нажатии клавиши TAB). TPanel – управляющий элемент, похожий на TGroupBox, используется в декоративных целях. Чтобы использовать TPanel, просто поместите его на форму и затем положите другие компоненты на него. Теперь при перемещении TPanel будут передвигаться и эти компоненты. TPanel используется также для создания линейки инструментов и окна статуса. TScrollBox представляет место на форме, которое можно скроллировать в вертикальном и горизонтальном направлениях. Пока в явном виде не отключить эту возможность, форма сама по себе действует так же. Однако, могут быть случаи, когда понадобится прокручивать только часть формы. В таких случаях используется TScrollBox. 16 2 Лабораторные работы 2.1 Лабораторная работа «Изменение заголовка формы» Цель работы – создать программу, выполняющую следующие действия: После запуска программы ввести текст в текстовом поле. По щелчку мышью на кнопке «Сменить заголовок окна» изменяется заголовок окна. Ввести новый текст в текстовом поле. Изменить название заголовка окна по нажатию клавиши Enter. Для выхода из программы необходимо щелкнуть мышью на закрывающей кнопке в строке заголовка. Описание плана разработки программы Открыть новый проект. Разместить на форме экземпляры компонентов: метку Label, кнопку Button, текстовое поле Edit. Выполнить следующие действия: Выделенный объект Form1 Вкладка окна Object Inspector Properties Имя свойства/ имя события Caption Label 1 (Вкладка Standard) Properties Caption Edit1 (Вкладка Standard) Properties Text Button1 (Вкладка Standard) Properties Caption Default Действие Установка имени формы «Проект3» Ввод текста надписи «Введите новый заголовок:» Очистить значение свойства Text Установка имени кнопки «Сменить заголовок окна» Выбрать в раскрывающемся списке значение True OnClick Events Сохраните проект, запустите и протестируйте его. Задание для самостоятельного выполнения Создать программу, выполняющую следующие действия: 1. После запуска программы отображаются: две строки для ввода текущих курсов для евро и доллара; строка для ввода денежной суммы в рублях; две строки для вывода эквивалента в евро, долларах. 2. Ввести текущий курс для евро и доллара. 3. Ввести денежную сумму в рублях. 4. По щелчку мышью на кнопке «Подсчитать эквивалент» выводится денежная сумма в евро и долларах. 5. Ввести новый текущий курс для евро и доллара. 6. Ввести новую денежную сумму в рублях. 7. По щелчку мышью на кнопке «Подсчитать эквивалент» выводится новая денежная сумма в евро и долларах. 8. Для выхода из программы необходимо щелкнуть мышью на закрывающей кнопке в строке заголовка. 17 2.2 Лабораторная работа «Случайный выбор из списка» Цель работы – создать программу, выполняющую следующие действия: 1. После запуска программы в окне изображается три поля. 2. По щелчку мышью на кнопке «Случайный выбор» из трех слов составляется предложение случайным образом. Для выхода из программы необходимо щелкнуть мышью на закрывающей кнопке в строке заголовка. Описание плана разработки программы Открыть новый проект. Разместить на форме экземпляры компонентов: поле со списком ComboBox, командная кнопка Button. Выполнить следующие действия: Выделенный объект Form1 ComboBox1 (Вкладка Standard) Вкладка окна Object Inspector Properties Events Properties Имя свойства/ Действие имя события Caption Установка имени формы «Сочинитель» OnCreate Style Выберите значение cSDropDownList из раскрывающегося списка Items Щелкните на кнопке построителя. Откроется окно String List Editor (Редактор списка строк). Ввести пункты списка по одному в каждую строчку, завершая ввод нажатием клавиши Enter. После того как список готов, щелкнуть на кнопке OK. Выделенный Вкладка окна Имя свойства/ Действие объект Object Inspector имя события ComboBox2 Properties Style Выберите значение cSDropDownList из (Вкладка Standard) раскрывающегося списка Items Щелкните на кнопке построителя. Откроется окно String List Editor (Редактор списка строк). Ввести пункты списка по одному в каждую строчку, завершая ввод нажатием клавиши Enter. После того как список готов, щелкнуть на кнопке OK. СотЬоВохЗ Properties Style Выберите значение cSDropDownList из (Вкладка Standard) раскрывающегося списка Items Щелкните на кнопке построителя. Откроется окно String List Editor (Редактор списка строк). Ввести пункты списка по одному в каждую строчку, завершая ввод нажатием клавиши Enter. После того как список готов, щелкнуть на кнопке OK. Button 1 Properties Caption Установка имени кнопки «Случайный (Вкладка Standard) выбор» Events OnClick 4. Сохраните проект, запустите и протестируйте его. 18 Листинг подпрограммы procedure TForm1.FormCreate (Sender: TObject); begin Randomize; ComboBox1.ItemIndex :=0; ComboBox2.ItemIndex :=0; ComboBox3.ItemIndex :=0; end; procedure TForm1.Button 1 Click (Sender: TObject); begin ComboBox1.ItemIndex := Random(ComboBox1.ItemIndex.Count); ComboBox2.ItemIndex := Random(ComboBox2.ItemIndex.Count); ComboBox3.ItemIndex := Random(ComboBox3.ItemIndex.Count); end; 2.3 Лабораторная работа «Бросок кубика» Цель работы – создать программу, выполняющую следующие действия: 1. После запуска программы появляется надпись «Брось кубик». 2. По щелчку мышью на кнопке «Бросок кубика» появляется сообщение, выдающее числа-очки в диапазоне 0 – 6 3. Для выхода из программы необходимо щелкнуть мышью на закрывающей кнопке в строке заголовка. Описание плана разработки программы Открыть новый проект. Разместить на форме экземпляры компонентов: метку Label и кнопку Button. Выполнить следующие действия: Выделенный объект Вкладка окна Имя свойства/ Действие Object Inspector имя события Form1 Properties Caption Установка имени формы «Бросок кубика» Label1 Properties Caption Ввод текста надписи «Брось кубик» Button1 Properties Caption Установка имени кнопки «Бросок кубика» Events OnClick 4. Сохраните проект, запустите и протестируйте его. Фрагмент программы procedure TForml.ButtonlClick(Sender: TObject); var n: Integer; begin n := random (6) + 1 ; Label 1.Caption := IntToStr (n) ; end; 5. Создать функцию, отображающую числовые значения граней. Function Kubic (Sides:Integer): Integer; Begin If Sides >= 1 then 19 begin Result := random (Sides) +1 ; end else begin Result :=0; end; End; 2.4 Лабораторная работа «Применение полос прокрутки» Выделенный объект Form1 Panel (Вкладка Standard) ScrollBar1 (Вкладка Standard) ScrollBar2 (Вкладка Standard) Shape1 (Вкладка Additional) Вкладка окна Object Inspector Properties Имя свойства/ имя события Действие Caption Установка имени формы «Перемещение фигур» Events Properties OnCreate Height Width Caption Properties Min Max Position SmallChange LargeChange OnChange Kind Events Properties Events Properties Min Max Position SmallChange LargeChange OnChange Height Width Left Top Shape (Форма) Brush (Кисть) Shape2 (Вкладка Additional) Events Properties OnMouseMove Height Width Left Top 20 Присвоить значение 172 Присвоить значение 172 Оставить значение свойства пустым Присвоить значение 5 Присвоить значение 145 Присвоить значение 76 Присвоить значение 2 Присвоить значение 20 Выбрать значение sbVertical. Горизонтальная полоса прокрутки станет вертикальной. Присвоить значение 5 Присвоить значение 145 Присвоить значение 76 Присвоить значение 2 Присвоить значение 20 20 20 Присвоить значение 76 Присвоить значение 76 Выбрать значение stCircle (Круг) Выбрать для подсвойства Color (Цвет кисти) значение clAqua (голубой цвет) Присвоить значение 20 Присвоить значение 20 Присвоить значение 76 Присвоить значение 76 Shape (Форма) Brush (Кисть) Events Выбрать значение stSquare (Квадрат) Выбрать для подсвойства Color (Цвет кисти) значение clFuchsia (фиолетовый цвет) OnMouseMove Описание плана разработки: 1. Ввести глобальную переменную логического типа, определяющую порядок фигуры. Если она принимает значение True, то текущей считается первая фигура. Значению False соответствует вторая фигура. 2. Событие OnCreate описывает присвоение глобальной переменной значения True. 3. Событие On Change для горизонтальной полосы прокрутки при истинном значении глобальной переменной присваивает значение положения прокрутки левому положению компоненты Shape1, иначе левому положению компоненты Shape2. 4. Событие On Change для вертикальной полосы прокрутки при истинном значении глобальной переменной присваивает значение положения прокрутки верхнему положению компоненты Shape1, иначе верхнему положению компоненты Shape2. 5. Событие OnMouseMove для компоненты Shape1 выполняет следующие действия первой фигуре задает толщину контура равной 3, второй фигуре – 1; глобальной переменной присваивает значение True; позиция горизонтальной полосы прокрутки принимает значение левого положения первой фигуры; позиция вертикальной полосы прокрутки принимает значение верхнего положения первой фигуры. 6. Событие OnMouseMove для компоненты Shape2 выполняет следующие действия первой фигуре задает толщину контура равной 1, второй фигуре – 3; глобальной переменной присваивает значение False; позиция горизонтальной полосы прокрутки принимает значение левого положения второй фигуры; позиция вертикальной полосы прокрутки принимает значение верхнего положения второй фигуры. Примерный внешний вид приложения: 21 2.5 Лабораторная работа «Прыгающая кнопка» Цель работы – создать программу-игру, выполняющую следующие действия: После запуска программы в окне изображается беспорядочно прыгающая кнопка. Необходимо успеть щелкнуть по ней. Кнопка перепрыгивает из одного места в другое по сигналу, полученному от таймера. Для выхода из программы необходимо щелкнуть мышью на закрывающей кнопке в строке заголовка. Описание плана разработки программы Открыть новый проект. Разместить на форме экземпляры компонентов: командная кнопка Button, таймер Timer Выполнить следующие действия: Выделенный объект Вкладка окна Object Inspector Form1 Properties Button 1 (Вкладка Standard) Events Properties Имя свойства/ Действие имя события Caption ClientWidth (Внутренняя ширина) ClientHeigth (Внутренняя высота) BorderStyle (тип границы) OnCreate Caption Tab Stop Visible Events Выделенный объект Вкладка окна Object Inspector Button2 Properties (Вкладка Standard) Установка имени формы «Прыгающая кнопка» Присвоить значение 300 Присвоить значение 200 Выбрать значение bsSingle (тонкая) Ввести надпись «Нажми меня» Присвоить значение False. Это свойство разрешает выбрать данный элемент управления клавишей Tab. Клавиатурой пользоваться запрещается. Присвоить значение False. Сначала кнопка невидима. Присвоить значение 30 Присвоить значение 80 Height Width OnClick Имя свойства/ Действие имя события Caption Default (по умолчанию) Left (слева) Тор (сверху) Width (ширина) Height 22 Ввести надпись «Выход» Выбрать значение True Присвоить значение 110 Присвоить значение 160 Присвоить значение 80 Присвоить значение 30 Timer1 (Вкладка System) Events Properties Events (высота) OnClick Interval (интервал) Timer Присвоить значение 500 (промежуток времени измеряется в миллисекундах) 4. Сохраните проект, запустите и протестируйте его. Листинг подпрограммы procedure TForm1.Button2Click (Sender: TObject); begin Close; end; procedure TForm1. Timer1 Timer (Sender: TObject); var i: Integer; begin i:=Random(9); Button1.Visible := True; Button1.Top := 10 + 50 * ( i div 3); Button1.Left := 10 + 100 * ( i mod 3); end; procedure TForm1. Button1 Click (Sender: TObject); begin Button1.Caption := 'Готово'; Button1.Enabled := False; Timer1.Enabled := False; end; procedure TForm1.FormCreate (Sender: TObject); begin Randomize; end; Задание для самостоятельного выполнения Измените игру так, чтобы скорость можно было настраивать в процессе игры. Создайте две кнопки: Медленнее и Быстрее. Щелчок на одной из них будет увеличивать или уменьшать значение свойства Timer1.Interval на 100 миллисекунд. 23 2.6 Лабораторная работа «Таблица умножения» Цель работы – создать программу, выполняющую следующие действия: После запуска программы в окне изображается два движка. Необходимо выбрать два числовых значения и найти их произведение. Для выхода из программы необходимо щелкнуть мышью на закрывающей кнопке в строке заголовка. Описание плана разработки программы 1. Открыть новый проект. 2. Разместить на форме экземпляры компонентов: командная кнопка Button, движок TrackBar, рамка GroupBox, надпись Label. Выполнить следующие действия: Выделенный объект Form1 Вкладка окна Object Inspector Properties TrackBar1 Properties (Вкладка Win32) Выделенный объект TrackBar2 (Вкладка Win32) GroupBox1 (Вкладка Standard) Label1 (Вкладка Standard) Events Вкладка окна Object Inspector Properties Events Properties Properties Имя свойства/ имя события Действие Установка имени формы «Таблица умножения» Min (Минимум) Присвоить значение 2 Мах (Максимум) Присвоить значение 99 Position Присвоить значение 2 (Положение) LineSize (Малое Присвоить значение 1 изменение) PageSize (Постр. Присвоить значение 7 изменение) Frequency Присвоить значение 7 (Частота засечек) OnChange Имя свойства/ Действие имя события Caption Min (Минимум) Мах (Максимум) Position (Положение) LineSize (Малое изменение) PageSize (Постраничное изменение) Frequency (Частота засечек) OnChange Caption Присвоить значение 2 Присвоить значение 99 Присвоить значение 2 AutoSize (Автоподбор) Caption Alignment Установить значение False 24 Присвоить значение 1 Присвоить значение 7 Присвоить значение 7 Ввести подпись «Произведение» Присвоить значение 2 Установить значение taRightJustify Label2 (Вкладка Standard) Properties Label3 (Вкладка Standard) Properties (Выравнивание) AutoSize Caption Alignment AutoSize Caption Alignment (Выравнивание по правому краю) Установить значение False Присвоить значение 2 Установить значение taRightJustify (Выравнивание по правому краю) Установить значение False Присвоить значение 4 Установить значение taRightJustify (Выравнивание по правому краю) 3. Сохраните проект, запустите и протестируйте его. Листинг подпрограммы procedure TForm1.TrackBar1Change (Sender: TObject); begin Label1.Caption := IntToStr(TrackBar1.Position); Label3.Caption := IntToStr(TrackBar1.Position * TrackBar2.Position); end; procedure TForm1.TrackBar2Change (Sender: TObject); begin Label2.Caption := IntToStr(TrackBar2.Position); Label3.Caption := IntToStr(TrackBar1.Position * TrackBar2.Position); Задание для самостоятельного выполнения Изменить программу так, чтобы находить произведения не только двузначных, но и трехзначных чисел от 2 до 199. Изменить программу так, чтобы находить сумму двух чисел. 2.7 Лабораторная работа «Светофор» Цель работы – создать программу, выполняющую следующие действия: После запуска программы в окне изображается светофор с тремя лампочками, способными реагировать на наведение указателя мыши. Когда указатель мыши наведен на лампочку, она меняет свой цвет. Для выхода из программы необходимо щелкнуть мышью на закрывающей кнопке в строке заголовка. Описание плана разработки программы Открыть новый проект. Разместить на форме экземпляры компонентов: фигура Shape. Выполнить следующие действия: Выделенный объект Form1 Вкладка окна Имя свойства/ имя Object события Inspector Properties Caption Height Width BorderIcons (Служебные кнопки) 25 Действие Установка имени формы «Светофор» Присвоить значение 300 Присвоить значение 120 Выбрать для подсвойства biMinimize (Сворачивание) и Выделенный объект Shape1 (Вкладка Additional) Color BorderStyle (Стиль рамки) Events OnMouseMove Вкладка окна Имя свойства/ имя Object события Inspector Properties Height Width Shape (Форма) Pen (Контур) Brush (Кисть) Shape2 (Вкладка Additional) Properties Enabled (Включен) Height Width Shape Pen Brush Shape3 (Вкладка Additional) Properties Enabled (Включен) Height Width Shape Pen Brush Enabled (Включен) biMaximize (Разворачивание) значение False Задать стандартный серый цвет Выбрать значение bsSingle Действие Присвоить значение 61 Присвоить значение 61 Выбрать значение stCircle (Круг) Выбрать для подсвойства Color (Цвет) значение clRed (красный цвет) Выбрать для подсвойства Style (стиль) значение bsClear (прозрачный) Выбрать значение False (Нет) Присвоить значение 61 Присвоить значение 61 Выбрать значение stCircle (Круг) Выбрать для подсвойства Color (Цвет) значение clYellow (желтый цвет) Выбрать для подсвойства Style значение bsClear Выбрать значение False (Нет) Присвоить значение 61 Присвоить значение 61 Выбрать значение stCircle (Круг) Выбрать для подсвойства Color (Цвет) значение clLime (яркозеленый цвет) Выбрать для подсвойства Style значение bsClear Выбрать значение False (Нет) Написать функцию OnShape, которая вызывается из процедуры FormMouseMove. Работа функции определяет следующие события: Если указатель мыши не наведен на лампочку, то ее цвет будет прозрачным. Если указатель мыши наведен на лампочку, то ее цвет будет соответствовать цветам светофора. г := sh.Width div 2; {r - радиус фигуры} сх := sh.Left + r; {cx, cy - координаты центра фигуры} су := sh.Top + r; d2 := (X - cx) * (X - cx) + (Y - cy) * (Y - cy); {d2 - квадрат расстояния от центра} 26 OnShape := bsClear; {указатель мыши не наведен на лампочку, т.е. находиться за пределами фигуры} if d2 > r*r then ObShape := bsSolid; {указатель мыши наведен на лампочку, т.е. находиться внутри фигуры} Сохраните проект, запустите и протестируйте его. Листинг подпрограммы Function OnShape (sh: TShape: X, Y: Integer): TBrushStyle; var r, cx, cy, d2: Integer; begin r := sh.Width div 2; cx:= sh.Left + r; cy := sh.Top + r; d2 := (X - cx) * (X - cx) + (Y - cy) * (Y - cy); OnShape := bsClear; if d2 > r*r then ObShape := bsSolid; end; procedure TForm1.FormMouseMove (Sender: TObject, Shift: TShiftState; X, Y: Integer);); begin Shape1.Brush.Color := clRed; Shape 1.Brush.Style := OnShape (Shape1, X, Y); Shape2.Brush.Color := clYellow; Shape2.Brush.Style := OnShape (Shape2, X, Y); Shape3.Brush. Col or := clLime; Shape.Brush.Style := OnShape (Shape3, X, Y); end; 2.8 Лабораторная работа «Вычисление процентов» Цель работы – создать программу, выполняющую следующие действия: 1. После запуска программы в окне изображается три текстовых поля. 2. В первое поле вводится число. Во второе поле - проценты. При нажатии кнопки «Рассчитать» в третье поле выводятся вычисленные проценты от числа. При нажатии кнопки «Очистить» очищаются значения полей. Далее вводятся новые значения в поля. Для выхода из программы необходимо щелкнуть мышью на закрывающей кнопке в строке заголовка. Описание плана разработки программы Открыть новый проект. Разместить на форме экземпляры компонентов: командная кнопка Button, надпись Label, текстовое поле Edit. 27 Выполнить следующие действия: Выделенный объект Form1 Вкладка окна Имя свойства/ Object Inspector имя события Properties Caption Label1 Edit1 Edit2 Edit3 Button1 Properties Properties Properties Properties Properties Events Вкладка окна Object Inspector Properties Events Выделенный объект Button2 Caption Text Text Text Caption OnClick Имя свойства/ имя события Caption OnClick Действие Установка имени формы «Вычисление процентов» Введите название «Считаем проценты!» Очистить значение свойства Очистить значение свойства Очистить значение свойства Введите название «Рассчитать» Описать локальные Number, Procent, Prn Действие Введите название «Очистить» Сохраните проект, запустите и протестируйте его. Фрагмент программы Var Number, Procent, Prn: Real; procedure TForm1.Button1Click(Sender: TObject); begin Number:=StrToFloat(Edit1 .Text); Procent:= StrToFloat(Edit2.Text); PrN:=0.01*Procent*Number; Edit3 .Text:=FloatToStr(PrN); end; procedure TForm1.Button2Click(Sender: TObject); begin Edit1.Text:=''; Edit2.Text:=''; Edit3.Text:=''; end; 28 2.9 Лабораторная работа «Строковый калькулятор» Цель работы – создать программу, выполняющую действия строкового калькулятора. Описание плана разработки программы Открыть новый проект. Разместить на форме экземпляры компонентов: Edit, Label, Button. Фрагмент программы procedure TForm1.Button2Click(Sender: TObject); begin s:=Edit1.Text; k:=StrToInt(Edit2.Text); t:=StrToInt(Edit3.text); Delete(s,k,t); Edit10.Text:=s; end; procedure TForm1.Button3Click(Sender: TObject); begin s:=Edit1.Text; q:=StrToInt(Edit4.Text); w:=Edit5.Text; Insert(w,s,q); edit11.Text:=s; end; procedure TForm1.Button4Click(Sender: TObject); begin s:=Edit1.Text; p:=StrToInt(Edit6.Text); l:=StrToInt(Edit7.Text); 29 Copy(s,p,l); s1:=copy(s,p,l); Edit12.Text:=s1; end; procedure TForm1.Button5Click(Sender: TObject); begin s:=Edit1.Text; r:=Edit9.Text; a:=Pos(r,s); edit13.Text:=IntToStr(a); end; procedure TForm1.Button6Click(Sender: TObject); begin s:=edit1.Text; b:=Length(s); edit14.Text:=IntToStr(b); end; 2.10 Лабораторная работа «Электронные часы» Цель работы – написать программу «Электронные часы», в окне которой отображается текущее время, дата и день недели. Описание плана разработки программы Открыть новый проект. Разместить на форме экземпляры компонентов: Label, Timer. Выполнить следующие действия: Ввести константы, отвечающие за названия дней недели и месяцев. Объявить процедуру ShowTime вручную для доступа к компонентам формы напрямую. Процедура ShowTime отображает текущее время. Процедура Timer 1 Timer обрабатывает сигнал таймера. Процедура FormCreate обрабатывает событие OnCreate. Листинг программы: unit Unit 1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Timer1: TTimer; Label 1: TLabel; // время Label2: TLabel; // дата и день недели procedure Timer1 Timer(Sender: TObject); 30 procedure FormCreate(Sender: TObject); procedure ShowTime; private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation const stDay : array[1..7] of string[11] = ('воскресенье','понедельник', 'вторник', среда','четверг','пятница','суббота'); stMonth : array[1.. 12] of string[8] = ('января', 'февраля','марта', апреля','мая','июня','июля', августа','сентября','октября', ноября','декабря'); {$R *.dfm} procedure TForm1.ShowTime; var Time : TDateTime; // текущее время begin Time := Now(); // получить системное время Label 1.Caption := FormatDateTime('hh:mm:ss',Time); end; procedure TForm1.Timer1Timer(Sender: TObject); begin ShowTime; // отобразить время end; procedure TForm1.FormCreate(Sender: TObject); var Present: TDateTime; // текущая дата и время Year, Month, Day : Word; // год, месяц и число, как // отдельные числа begin Present:= Now; // получить текущую дату DecodeDate(Present, Year, Month, Day); Label2.Caption := 'Сегодня '+IntToStr(Day)+ ' ' + stMonth[Month] + ' '+ IntToStr(Year)+ ' года, '+ stDay [Day OfWeek(Present)]; // настроить и запустить таймер Timer 1.Interval := 1000; //период сигналов таймера 1 с Timer1 .Enabled := True; // пуск таймера end; 31 2.11 Лабораторная работа «Разработка простых приложений» Цель работы – закрепить практические навыки по теоретическим основам объектно-ориентированного программирования и по разработке простых приложений средствами интегрированной средой Delphi. Основные свойства формы Свойство Name Caption Width Height Top Left BorderStyle BorderIcons Color Font Описание Имя формы. Используется в программе для управления формой и доступа к ее компонентам. Стандартное имя Form1, Form2… Текст заголовка окна. Ширина формы в пикселях. Высота формы. Расстояние от верхней границы формы до верхней границы экрана. Расстояние от левой границы формы до левой границы экрана. Вид границы BsSizeable – обычная. Во время работы программы можно изменять размер окна. BsSingle – тонкая. Нельзя изменить размер окна. BsNone – нет границы. Окно выводится без заголовка и его положение и размер изменить нельзя. Кнопки управления окном biSystemMenu определяет доступность кнопки «Свернуть» и кнопки системного меню, biMinimaze – кнопки «Свернуть», biMaximaze – кнопки «Развернуть», biHelp – кнопки вывода справочной информации Цвет фона Шрифт Вопросы для закрепления 1) Цвет фона в окне Windows с точки зрения объектноориентированного программирования. 2) Тип вводимого значения в компонент Edit. 3) Вложение функциональности одного класса в другой. 4) Объект по отношению к своему классу в объектно-ориентированном программировании. 5) Вид подпрограммы, которым описываются события в языке Delphi. 6) Что означает свойство Heigth? 7) Объектно-ориентированный язык программирования. 8) Что означает термин «полиморфизм»? 9) Окно, на котором размещаются управляющие элементы. 10) Что описывает в окне редактора свойств вкладка Events? 11) Как называется продукт, созданный средствами языка Delphi? 12) Как называется раздел Implementation? 13) Окно Windows с точки зрения объектно-ориентированного программирования. 14) Функционально законченный фрагмент программы, оформленный в виде отдельного файла с исходным кодом. 15) Что означает свойство Caption? 32 16) Что организует компонент Label? 17) Что организует компонент Edit? 18) Единство свойств и действий. Список компонент для разработки простых приложений Button Edit RadioButton BitBtn GroupBox ScrollBar CheckBox Label Shape CheckListBox ListBox Timer ComboBox Panel TrackBar Перечень приложений, подлежащих разработке 1. Разработка приложения, реализующего решение биквадратного уравнения; 2. Разработка приложения, реализующего решение квадратного уравнения; 3. Разработка игрового приложения; 4. Разработка приложения с реализацией компоненты TrackBar; 5. Разработка приложения, реализующего решение системы двух уравнений с двумя неизвестными; 6. Разработка приложения с реализацией компоненты ScrollBar; 7. Разработка приложения, реализующего работу светофора; 8. Разработка приложения с реализацией компоненты Timer; 9. Разработка приложения с реализацией компоненты ComboBox. 10. Произвольная тема. События обрабатываемых компонент Компонент ТButton ТRadioButton ТTrackBar ТForm ТTimer Событие OnClick Описание Щелчок по кнопке мыши OnChange onMouseMove OnCreate OnTimer Перемещение ползунка Перемещении указателя мыши Начальные настройки формы Обработка таймера 2.12 Лабораторная работа «Создание главного и контекстного меню» 1. Создать новое приложение. Заголовок формы Picture Viewer (свойство Caption), назовем форму PictureForm (свойство Name). 2. Сохранить модуль формы и весь проект. 3. Поместить компонент MainMenu на форму и дать ему имя MainMenu. В компоненте MainMenu свойство AutoHotKeys установить значением maAutomatic. 33 4. Создать меню: File Caption Open … Save As … Close Exit Name OpenMenuItem SaveAsMenuItem CloseMenuItem разделитель ExitMenuItem View Caption Status bar Half Size Normal Size Double Size Name StatusBarMenuItem разделитель HalfSizeMenuItem NormalSizeMenuItem DoubleSizeMenuItem 5. Обработать событие OnClick компонента ExitMenuItem. 6. Для создания переключателей установите в пунктах Toolbar и Status bar свойство Checked в значение True. 7. В ответ на выбор пользователем пунктов Toolbar и Status bar будем переключать флажок. Обработчик события OnClick для этих пунктов меню будет выглядеть следующим образом: procedure TPictureForm.ToolBarMenuItemClick(Sender: TObject); begin // Спрятать или показать панель инструментов ToolBarMenuItem.Checked := not ToolBarMenuItem.Checked; end; procedure TPictureForm.StatusBarMenuItemClick(Sender: TObject); begin // Спрятать или показать строку состояния StatusBarMenuItem.Checked := not StatusBarMenuItem.Checked; end; 8. Объедините только что созданные пункты меню в одну согласовано работающую группу. Для этого у всех пунктов установите одинаковое ненулевое значение свойства GroupIndex (например, 1). Установите для всех этих пунктов свойство RadioItem в значение True. Один из пунктов (например, Normal Size) переведите во включенное состояние, установив его свойство Checked в значение True. 9. Чтобы привести в действие механизм переключения пунктов, определите в них следующие обработчики события OnClick: procedure TPictureForm.HalfSizeMenuItemClick(Sender: TObject); begin // Показать рисунок половинного размера HalfSizeMenuItem.Checked := True; end; procedure TPictureForm.NormalSizeMenuItemClick(Sender: TObject); begin // Показать рисунок нормального размера NormalSizeMenuItem.Checked := True; end; procedure TPictureForm.DoubleSizeMenuItemClick(Sender: TObject); 34 begin // Показать рисунок двойного размера DoubleSizeMenuItem.Checked := True; end; 10. Часть пунктов должна быть недоступна, если не открыт файл. Для этого в каждом из пунктов меню (кроме Open …) установите свойство Enabled в значение False. 11. Во время работы приложения нужно еще динамически делать пункты меню доступными или недоступными в зависимости от того, открыт графический файл или нет. Оформим их в виде отдельного метода EnableCommands: type TPictureForm = class(TForm) ... private { Private declarations } procedure EnableCommands(Enable: Boolean); end; ... procedure TPictureForm.EnableCommands(Enable: Boolean); begin SaveAsMenuItem.Enabled := Enable; CloseMenuItem.Enabled := Enable; HalfSizeMenuItem.Enabled := Enable; NormalSizeMenuItem.Enabled := Enable; DoubleSizeMenuItem.Enabled := Enable; end; 12. Создайте обработчики команд Open... и Close согласно образцу: procedure TPictureForm.OpenMenuItemClick(Sender: TObject); begin // Открыть рисунок и разрешить команды EnableCommands(True); end; procedure TPictureForm.CloseMenuItemClick(Sender: TObject); begin // Закрыть рисунок и запретить команды EnableCommands(False); end; Создание контекстного меню 13. Поместите на форму компонент PopupMenu, находящийся на вкладке Standard. Дайте новому компоненту имя PopupMenu. 35 14. Контекстное меню наполняется пунктами, как и главное меню, в дизайнере меню. Двойным щелчком мыши на компоненте PopupMenu откройте окно конструктора меню и добавьте в меню пункты Half Size (с идентификатором HalfSizePopupItem), Normal Size (с идентификатором NormalSizePopupItem) и Double Size (с идентификатором DoubleSizePopupItem). Во всех пунктах контекстного меню установите следующие свойства: Enabled = False GroupIndex = 1 RadioItem = True Кроме этого пометьте пункт Normal Size, установив в нем свойство Checked в значение True. Таким образом, команды всплывающего меню дублируют некоторые команды главного меню. 15. Активизируйте в дизайнере меню пункт Half Size и выберите в окне свойств вкладку Events. Выберите обработчик HalfSizeMenuItemClick из раскрывающегося списка события OnClick. То же самое проделайте с пунктами Normal Size и Double Size, установив для них обработчики NormalSizeMenuItemClick и DoubleSizeMenuItemClick соответственно. 16. Для синхронной работы главного и контекстного меню нужно еще подправить некоторые обработчики: procedure TPictureForm.HalfSizeMenuItemClick(Sender: TObject); begin // Показать рисунок половинного размера HalfSizeMenuItem.Checked := True; HalfSizePopupItem.Checked := True; end; procedure TPictureForm.NormalSizeMenuItemClick(Sender: TObject); begin // Показать рисунок нормального размера NormalSizeMenuItem.Checked := True; NormalSizePopupItem.Checked := True; end; procedure TPictureForm.DoubleSizeMenuItemClick(Sender: TObject); begin // Показать рисунок двойного размера DoubleSizeMenuItem.Checked := True; DoubleSizePopupItem.Checked := True; end; procedure TPictureForm.EnableCommands(Enable: Boolean); begin SaveAsMenuItem.Enabled := Enable; CloseMenuItem.Enabled := Enable; HalfSizeMenuItem.Enabled := Enable; 36 HalfSizePopupItem.Enabled := Enable; NormalSizeMenuItem.Enabled := Enable; NormalSizePopupItem.Enabled := Enable; DoubleSizeMenuItem.Enabled := Enable; DoubleSizePopupItem.Enabled := Enable; end; 17. Контекстное меню готово, осталось сделать так, чтобы оно вызывалось по щелчку правой кнопки мыши на форме. Активизируйте форму и запишите в значении свойства PopupMenu имя разработанного ранее контекстного меню - PopupMenu. Добавление значков для пунктов меню Компонент ImageList предназначен для хранения заранее подготовленного списка значков. Ограничение: все хранимые значки должны иметь одинаковые размеры. 18. Поместите компонент ImageList на форму и дайте ему имя ImageList. Редактирование списка рисунков осуществляется в специальном окне. Вызовите его с помощью команды ImageList Editor…, находящейся в контекстном меню компонента ImageList. 19. В открывшемся окне нажмите кнопку Add... и выберите несколько подходящих файлов из коллекции рисунков. 20. Теперь нужно указать компоненту MainMenu, откуда брать значки для своих пунктов. Выделите компонент MainMenu на форме и перейдите к свойству Images в окне свойств. Из списка значений свойства Images выберите элемент ImageList. 21. Теперь осталось указать пунктам меню номера соответствующих им значков. Для этого вызовите дизайнер меню для компонента MainMenu. Далее выберите пункт Open... (программный идентификатор OpenMenuItem), перейдите к свойству ImageIndex и выберите из раскрывающегося списка подходящий значок. Аналогично установите номера соответствующих значков для пунктов Save As…, Half Size, Normal Size и Double Size. Организация открытия и сохранения файла Диалоговые окна для выбора открываемого или сохраняемого файла организуются с помощью компонентов OpenDialog и SaveDialog. 22. Найдите их в палитре компонентов на вкладке Dialogs и поместите на форму. Первый компонент назовите OpenDialog, а второй – SaveDialog. 23. Приспособим компоненты OpenDialog и SaveDialog для выбора графических файлов. Активизируйте на форме компонент OpenDialog и в окне свойств выберите свойство Filter. Щелчком кнопки с многоточием откройте редактор фильтров – окно Filter Editor. 24. Установите в компоненте OpenDialog фильтры, как показано на рисунке 37 25. Аналогичным образом установите фильтры в компоненте SaveDialog. 26. Установим в компоненте SaveDialog параметр ofOverwritePrompt в значение True, т.е. пользователю выдается предупреждение при попытке сохранить файл с именем, которое уже существует. 27. Выберите компонент Image из палитры Additional и поместите на форму. Чтобы подогнать размеры компонента под размеры рисунка установите свойство AutoSize в значение True. 28. В исходном тексте уже имеется недописанный обработчик команды Open... . В нем нужно вызвать стандартное диалоговое окно открытия файла и загрузить рисунок в том случае, если пользователь ввел в этом окне имя файла: procedure TPictureForm.OpenMenuItemClick(Sender: TObject); begin if OpenDialog.Execute then begin Image.Picture.LoadFromFile(OpenDialog.FileName); EnableCommands(True); NormalSizeMenuItem.Click; end; end; 29. Обработка команды Save As... состоит в вызове стандартного диалогового окна Save с последующем сохранением рисунка в файле: procedure TPictureForm.SaveAsMenuItemClick(Sender: TObject); begin if SaveDialog.Execute then Image.Picture.SaveToFile(SaveDialog.FileName); end; 30. В обработчике команды меню Close добавим операторы удаления рисунка из компонента Image и уменьшения размеров компонента до нуля, чтобы в отсутствие рисунка компонент не занимал места на форме: procedure TPictureForm.CloseMenuItemClick(Sender: TObject); begin with Image do 38 begin Picture := nil; Width := 0; Height := 0; end; NormalSizeMenuItem.Click; EnableCommands(False); end; 31. Доработать события команд меню Half Size, Normal Size Double Size. procedure TPictureForm.HalfSizeMenuItemClick(Sender: TObject); begin HalfSizeMenuItem.Checked := True; HalfSizePopupItem.Checked := True; with Image do begin AutoSize := False; Width := Picture.Width div 2; Height := Picture.Height div 2; Stretch := True; end; end; и procedure TPictureForm.NormalSizeMenuItemClick(Sender: TObject); begin NormalSizeMenuItem.Checked := True; NormalSizePopupItem.Checked := True; Image.AutoSize := True; // восстановить нормальные размеры компонента end; procedure TPictureForm.DoubleSizeMenuItemClick(Sender: TObject); begin DoubleSizeMenuItem.Checked := True; DoubleSizePopupItem.Checked := True; with Image do begin AutoSize := False; Width := Picture.Width * 2; Height := Picture.Height * 2; Stretch := True; end; end; Проверить скомпилированный проект, добавив рисунок из коллекции размещенной по адресу C:\Program Files\Common Files\CodeGear Shared\Images\Splash\256Color 39 Создание строки состояния 32. Поместите компонент StatusBar на форму и дайте ему имя StatusBar. 33. Приспособим строку состояния для отображения размеров рисунка и имени файла, в котором рисунок хранится на диске. С этой целью разделим строку состояния на две информационные панели. Перейдите к окну свойств и в поле Panels щелкните кнопку с многоточием (либо в контекстном меню строки состояния выберите пункт Panels Editor…). Откроется специальное окно с заголовком Editing StatusBar.Panels для создания панелей в строке состояния: 34. В этом окне создаются, редактируются и удаляются панели строки состояния. Оно работает в паре с окном свойств, в котором настраиваются свойства отдельно взятой панели строки состояния. Нажатием кнопки Add New создайте первую панель и установите ее свойства так, чтобы она получилась шириной 70 пикселей (Width = 70), продавленной (Bevel = pbLowered) и с центрированным текстом (Alignment = taCenter). 35. Аналогично создайте вторую панель неограниченной ширины (Width = -1), продавленной (Bevel = pbLowered) и с прижатым влево текстом (Alignment = taLeftJustify). 36. Поместите в обработчики команд меню Open... и Close действия для вывода информации на панель: Для меню Open… if image.Width<>0 then begin statusbar.Panels[0].Text:=format('%d x %d',[image.Picture.Width, image.Picture.Height]); statusbar.Panels[1].Text:=opendialog.FileName end; Для меню Close if image.Width=0 then begin statusbar.Panels[0].Text:=''; statusbar.Panels[1].Text:='' end; 40 Отдельная область прокрутки 37. Выделите на форме компонент Image и временно удалите его в буфер (команда меню Edit / Cut). Теперь опустите на форму компонент ScrollBox, выбрав его из палитры компонентов Additional. Назовите новый компонент ScrollBox и подгоните его под всю незанятую область формы, установив свойство Align в значение alClient. 38. Переключитесь на форму (так, чтобы компонент ScrollBox остался выделенным) и вставьте из буфера обмена компонент Image (команда меню Edit / Paste). Скомпилируйте проект и проверьте его работоспособность. 2.13 Лабораторная работа «Подсказки к кнопкам» Все визуальные компоненты в среде Delphi, в том числе и кнопки панели инструментов, могут иметь подсказки. Подсказки бывают двух видов: всплывающие подсказки и подсказки в строке состояния. Обе подсказки хранятся в свойстве Hint, которое имеет следующий формат: <всплывающая подсказка>|<подсказка в строке состояния> Всплывающая подсказка отделяется вертикальной чертой от подсказки для строки состояния. Если в программе есть строка состояния, то при попадании указателя мыши на визуальный компонент в ней автоматически отображается поясняющий текст, записанный справа от символа вертикальной черты. Это легко проверить. Впишите в свойстве Hint кнопки Open текст "Open an existing file...|Open an existing file...". После запуска программы вы обнаружите, что подсказка для кнопки работает точно так же, как и подсказка к пункту меню. Наиболее удобный вид подсказок – это всплывающие подсказки. Всплывающая подсказка появляется спустя секунду после того, как 41 пользователь задерживает указатель мыши над компонентом. Приятная особенность всплывающих подсказок состоит в том, что они вообще не требуют программирования – достаточно просто разрешить компоненту отображать всплывающую подсказку, и подсказка начнет работать. В каждом визуальном компоненте существует булевское свойство ShowHint, определяющее, появляется подсказка, или нет. Его значение может устанавливаться напрямую, а может копироваться из содержащего компонента (например, из формы). Копирование значения происходит тогда, когда вспомогательное свойство ParentShowHint установлено в True. Таким образом, появлением подсказок можно управлять из содержащего компонента. Принимая во внимание, что во всех компонентах свойство ParentShowHint изначально равно True, установите в компоненте ToolBar свойство ShowHint в значение True. В результате во всех кнопках свойство ShowHint тоже получит значение True и это заставит их отображать свои подсказки. Впишите для каждой кнопки текст подсказки (свойство Hint). Свойство Hint может содержать сразу две подсказки: всплывающую подсказку и подсказку в строке состояния (они разделяются символом вертикальной черты). Если вторая кажется вам лишней, просто не набирайте ее, но символ вертикальной черты поставьте. 42 Выполните компиляцию и запустите программу. Убедитесь, что панель инструментов работает правильно. Управление видимостью панели кнопок Для отображения панели инструментов и строки состояния необходимо у соответствующей панели изменить значение булевского свойства Visible на противоположное. При этом панель исчезает или появляется в окне вместе с изменением значения свойства. Окончательный вариант обработчиков будет следующим: procedure TPictureForm.ToolBarMenuItemClick(Sender: TObject); begin … ToolBar.Visible := not ToolBar.Visible; … end; procedure TPictureForm.StatusBarMenuItemClick(Sender: TObject); begin … StatusBar.Visible := not StatusBar.Visible; … end; Список команд Часто одна и та же команда дублируется в разных местах пользовательского интерфейса: и в главном меню, и в контекстном меню, и на панели инструментов. Например, команды управления масштабом рисунка присутствуют во всех перечисленных местах программы Picture Viewer. Это очень удобно для пользователя, но добавляет работы программисту, поскольку изменение команды в одном месте требует таких же изменений во всех других местах. На помощь приходит компонент ActionList, который централизованно управляет всеми командами пользовательского интерфейса. Создание списка команд Отыщите в палитре компонентов на вкладке Standart компонент ActionList и добавьте его в форму. Дайте компоненту имя ActionList. Создание списка команд начнем с команды Open. В контекстном меню компонента ActionList выберите команду Action List Editor… . 43 Перед вами откроется окно команд. Окно команд работает в паре с окном свойств. Создание и удаление команд осуществляется в окне команд, а свойства отдельно взятой команды устанавливаются в окне свойств. Щелчком на первой кнопке добавьте в список новую команду. Свойства команды немедленно появятся в окне свойств. Команды Когда создается очередная команда в компоненте ActionList, среда Delphi добавляет в описание формы компонент Action. Компонент Action не существует отдельно от компонента ActionList и поэтому отсутствует в палитре компонентов. 44 Перейдем к настройке команды, созданной на предыдущем шаге. Дайте команде имя OpenAction, в свойстве Caption впишите текст Open... и в свойстве ShortCut выберите значение Ctrl+O. Команда может иметь значок. Он определяется значением свойства ImageIndex (номер значка в списке Images компонента ActionList). Прежде чем выбрать значение для свойства ImageIndex, нужно указать список значков компоненту ActionList. Выделите на форме компонент ActionList и перейдите к окну свойств. Выберите в свойстве Images значение ImageList. Теперь установим компоненту OpenAction соответствующий значок. Перейдите к окну команд и выделите команду OpenAction. Затем в окне 45 свойств отыщите свойство ImageIndex и выберите значок с соответствующим номером. По аналогии самостоятельно создайте команды SaveAsAction, CloseAction, ExitAction, ToolBarAction, StatusBarAction, HalfSizeAction, NormalSizeAction, DoubleSizeAction с соответствующими заголовками (свойство Caption). Привязка команд Кнопки, пункты меню и некоторые другие визуальные компоненты имеют свойство Action, с помощью которого к ним привязываются команды. В результате установки свойства Action визуальный компонент копирует к себе значения свойств команды (надпись, значок, подсказку и др.). Кроме того, команда запоминает, к каким компонентам она привязана с тем, чтобы изменение свойств команды вызывало изменение соответствующих свойств во всех связанных с ней компонентах. 46 Привязку команд начнем с кнопки Open на панели инструментов. Выделите ее и в раскрывающемся списке свойства Action выберите значение OpenAction. Обратите внимание, что надпись на кнопке изменилась. Это результат копирования значения свойства Caption из компонента OpenAction в компонент OpenToolButton. Аналогичным образом привяжите команду OpenAction к пункту Open… главного меню. Выполните компиляцию и запустите программу. Обратите внимание: и кнопка Open… на панели инструментов, и пункт Open… в главном меню недоступны. Это объясняется отсутствием у компонента OpenAction обработчика события OnExecute. Реакция на команды Когда пользователь нажимает кнопку или выбирает пункт меню, происходит событие OnExecute. Если для команды не определен обработчик 47 события OnExecute, то все компоненты, использующие эту команду, становятся недоступными (свойство Enabled устанавливается в значение False). Определим в компоненте OpenAction обработчик события OnExecute. Обратитесь к контекстному меню компонента ActionList и вызовите окно команд. В этом окне выберите команду OpenAction, после чего в окне свойств выберите вкладку Events. Теперь сделайте двойной щелчок мыши на значении события OnExecute. Среда Delphi создаст заготовку для будущего обработчика. procedure TPictureForm.OpenActionExecute(Sender: TObject); begin end; Обработчик у нас уже есть в виде метода OpenMenuItemClick, поэтому мы просто перенесем код этого метода (слегка подправив его) в только что созданный метод, удалив код метода OpenMenuItemClick. procedure TPictureForm.OpenMenuItemClick(Sender: TObject); begin end; ... procedure TPictureForm.OpenActionExecute(Sender: TObject); begin if OpenDialog.Execute then begin Image.Picture.LoadFromFile(OpenDialog.FileName); EnableCommands(True); NormalSizeAction.Execute; // Вместо NormalSizeMenuItem.Click; end; if Image.Width <> 0 then begin StatusBar.Panels[0].Text := Format('%d x %d', [Image.Picture.Width, Image.Picture.Height]); StatusBar.Panels[1].Text := OpenDialog.FileName; end; end; Сохраните проект; пустой метод OpenMenuItemClick будет автоматически удален из исходного текста. Обратите внимание, что компонент Action автоматически подменяет обработчики OnClick в связанных с ним компонентах. Поэтому если вы перейдете к окну свойств и посмотрите на событие OnClick в компоненте OpenMenuItem, то обнаружите там метод OpenActionExecute (обработчик события OnExecute компонента OpenAction). 48 Выполните компиляцию и запустите программу. Команда Open снова доступна пользователю. Закрыв программу, вернитесь к проекту в среде Delphi, чтобы продолжить настройку оставшихся команд. Обойдите все пункты меню (не забудьте про контекстное меню) и кнопки панели инструментов и установите в каждом из них свойство Action в соответствующее значение. Попутно значения некоторых других свойств тоже изменятся, например свойство Enabled получит значение True. Пусть вас это не беспокоит, так и должно быть. Восстановим правильную логику работы кнопок и пунктов меню. Сделайте недоступной команду SaveAsAction, установив ее свойство Enabled в значение False. Одновременно кнопка и пункт меню Save As... станут недоступными. Создайте для компонента SaveAsAction обработчик события OnExecute и перенесите код метода SaveAsMenuItemClick в только что созданный метод SaveAsActionExecute: 49 procedure TPictureForm.SaveAsMenuItemClick(Sender: TObject); begin end; procedure TPictureForm.SaveAsActionExecute(Sender: TObject); begin if SaveDialog.Execute then Image.Picture.SaveToFile(SaveDialog.FileName); end; Доработку команды SaveAsAction мы закончили и теперь по аналогии доработаем команды ExitAction и CloseAction: procedure TPictureForm.ExitMenuItemClick(Sender: TObject); begin end; procedure TPictureForm.CloseMenuItemClick(Sender: TObject); begin end; procedure TPictureForm.ExitActionExecute(Sender: TObject); begin Close; end; procedure TPictureForm.CloseActionExecute(Sender: TObject); begin with Image do begin Picture := nil; Width := 0; Height := 0; end; NormalSizeAction.Execute; // Вместо NormalSizeMenuItem.Click; EnableCommands(False); if Image.Width = 0 then begin StatusBar.Panels[0].Text := ''; StatusBar.Panels[1].Text := ''; end; end; Теперь обработаем команды ToolBarAction и StatusBarAction: 50 procedure TPictureForm.ToolBarMenuItemClick(Sender: TObject); begin end; procedure TPictureForm.StatusBarMenuItemClick(Sender: TObject); begin end; procedure TPictureForm.ToolBarActionExecute(Sender: TObject); begin ToolBarAction.Checked := not ToolBarAction.Checked; ToolBar.Visible := not ToolBar.Visible; end; procedure TPictureForm.StatusBarActionExecute(Sender: TObject); begin StatusBarAction.Checked := not StatusBarAction.Checked; StatusBar.Visible := not StatusBar.Visible; end; Теперь восстановим логику работы команд, отвечающих за масштаб рисунка. Вернитесь к окну редактирования списка команд и выделите команду HalfSizeAction. После этого нажмите клавишу Ctrl и, удерживая ее, выделите команды NormalSizeAction и DoubleSizeAction. Перейдите к окну свойств и установите свойство GroupIndex в значение 1. Свойство Checked компонента NormalSizeAction установите в значение True – при запуске программы рисунок не масштабируется. Установите свойство Enabled команд HalfSizeAction, NormalSizeAction и DoubleSizeAction в значение False – при запуске программы рисунок еще не загружен, поэтому команды переключения масштаба должны быть недоступны. 51 Теперь создадим обработчики команд HalfSizeAction, NormalSizeAction и DoubleSizeAction. Для каждой команды определите обработчик события OnExecute и перенесите код из уже имеющихся методов: procedure TPictureForm.HalfSizeMenuItemClick(Sender: TObject); begin end; procedure TPictureForm.NormalSizeMenuItemClick(Sender: TObject); begin end; procedure TPictureForm.DoubleSizeMenuItemClick(Sender: TObject); begin end; ... procedure TPictureForm.HalfSizeActionExecute(Sender: TObject); begin HalfSizeToolButton.Down := True; HalfSizeMenuItem.Checked := True; HalfSizePopupItem.Checked := True; with Image do begin AutoSize := False; Width := Picture.Width div 2; Height := Picture.Height div 2; Stretch := True; end; end; procedure TPictureForm.NormalSizeActionExecute(Sender: TObject); begin NormalSizeToolButton.Down := True; NormalSizeMenuItem.Checked := True; NormalSizePopupItem.Checked := True; Image.AutoSize := True; end; procedure TPictureForm.DoubleSizeActionExecute(Sender: TObject); begin DoubleSizeToolButton.Down := True; DoubleSizeMenuItem.Checked := True; DoubleSizePopupItem.Checked := True; 52 with Image do begin AutoSize := False; Width := Picture.Width * 2; Height := Picture.Height * 2; Stretch := True; end; end; Обработчики можно упростить за счет управления состоянием пунктов меню и кнопок через компоненты Action, т.е. первые три оператора каждого обработчика заменяются на один оператор: procedure TPictureForm.HalfSizeActionExecute(Sender: TObject); begin HalfSizeAction.Checked := True; with Image do begin AutoSize := False; Width := Picture.Width div 2; Height := Picture.Height div 2; Stretch := True; end; end; procedure TPictureForm.NormalSizeActionExecute(Sender: TObject); begin NormalSizeAction.Checked := True; Image.AutoSize := True; end; procedure TPictureForm.DoubleSizeActionExecute(Sender: TObject); begin DoubleSizeAction.Checked := True; with Image do begin AutoSize := False; Width := Picture.Width * 2; Height := Picture.Height * 2; Stretch := True; end; end; А теперь воспользуемся свойством AutoCheck компонентов Action, чтобы избавиться от необходимости программно переключать метку в пунктах 53 Toolbar и Status bar главного меню. Когда свойство AutoCheck равно True, то при выполнении команды свойство Checked автоматически меняет свое значение на противоположное. Это отражается на связанных с командой пунктах меню и кнопках-переключателях. У команд ToolBarAction и StatusBarAction установите свойства AutoCheck и Checked в значение True. Подправьте методы ToolBarActionExecute и StatusBarActionExecute: procedure TPictureForm.ToolBarActionExecute(Sender: TObject); begin ToolBar.Visible := ToolBarAction.Checked; end; procedure TPictureForm.StatusBarActionExecute(Sender: TObject); begin StatusBar.Visible := StatusBarAction.Checked; end; Управление состоянием команд Компонент ActionList имеет удобный механизм управления состоянием команд (например, доступна/недоступна). После выполнения очередной команды и во время простоя программы в компоненте возникает событие OnUpdate. Реакцией на это событие может быть изменение состояния отдельных команд, например переключение в них свойства Enabled. Напомним, что сейчас для этих целей используется метод EnableCommand, вызываемый при открытии и закрытии файла. Избавимся от него. Выделите на форме компонент ActionList, и в окне свойств на вкладке Events отыщите событие OnExecute. Двойным щелчком мыши создайте обработчик: procedure TPictureForm.ActionListUpdate(Action: TBasicAction; var Handled: Boolean); var NonEmpty: Boolean; begin NonEmpty := Image.Picture.Graphic <> nil; SaveAsAction.Enabled := NonEmpty; CloseMenuItem.Enabled := NonEmpty; HalfSizeAction.Enabled := NonEmpty; NormalSizeAction.Enabled := NonEmpty; DoubleSizeAction.Enabled := NonEmpty; Handled := True; end; Удалите метод EnableCommands и обращения к нему из методов OpenActionExecute и CloseActionExecute. Вот, что должно получиться: 54 procedure TPictureForm.OpenActionExecute(Sender: TObject); begin if OpenDialog.Execute then begin Image.Picture.LoadFromFile(OpenDialog.FileName); NormalSizeAction.Execute; end; if Image.Width <> 0 then begin StatusBar.Panels[0].Text := Format('%d x %d', [Image.Picture.Width, Image.Picture.Height]); StatusBar.Panels[1].Text := OpenDialog.FileName; end; end; procedure TPictureForm.CloseActionExecute(Sender: TObject); begin with Image do begin Picture.Graphic := nil; Width := 0; Height := 0; end; NormalSizeAction.Execute; if Image.Width = 0 then begin StatusBar.Panels[0].Text := ''; StatusBar.Panels[1].Text := ''; end; end; 2.14 Лабораторная работа «Создание панели инструментов» 1. Добавить в меню View пункт ToolBar присвоив ему имя ToolBarMenuItem. Обработать событие: procedure TPictureForm.ToolBarMenuItemClick(Sender: TObject); begin // Спрятать или показать панель инструментов ToolBarMenuItem.Checked := not ToolBarMenuItem.Checked; end; 2. Установите в пункте Toolbar свойство Checked в значение True. 3. Активизируйте форму и поместите на нее компонент ToolBar (вкладка Win32). Дайте новому компоненту имя ToolBar. 55 4. Перейдите к окну Object TreeView и найдите в нем компонент ToolBar. Захватите его с помощью мыши и перетащите к элементу PictureForm в этом же окне. 5. В окне свойств установите свойство AutoSize в значение True. После этого панель инструментов будет автоматически подгонять свои размеры в зависимости от размеров и количества размещенных на ней компонентов. 6. Для добавления кнопки вызовите контекстное меню компонента ToolBar и выберите команду New Button. На панели инструментов появится кнопка, свойства которой будут тут же показаны в окне свойств. Дайте компоненту имя OpenToolButton. 7. Аналогичным образом создайте еще четыре кнопки с программными идентификаторами SaveAsToolButton, HalfSizeToolButton, NormalSizeToolButton и DoubleSizeToolButton. 8. Выделите на форме компонент ToolBar, перейдите к окну свойств и установите свойству Images значение ImageList. Надписи на кнопках 9. Текст надписи устанавливается в свойстве Caption. Сначала он не виден и, чтобы его показать, задайте в компоненте ToolBar свойству ShowCaptions значение True. 10. Чтобы текст расположился справа от рисунка нужно в окне свойств переключить свойство List в значение True. 11. Измените надписи на кнопках: Open, Save As, Half Size, Normal Size, Double Size. 12. Для каждой кнопки перейдите к окну свойств и установите свойство AutoSize в значение True. 13. Выделите на форме компонент ToolBar и переключите его свойство Flat в значение True. 14. В примере логично отделить группу кнопок, отвечающих за размеры рисунка (Half Size, Normal Size и Double Size), от кнопок Open и Save As. Для этого вызовите контекстное меню панели инструментов и выберите команду New Separator. Кнопки-переключатели 15. Сгруппируйте кнопки Half Size, Normal Size и Double Size. Они уже находятся рядом друг с другом, поэтому просто установите их свойства Grouped – True, Style – tbsCheck. 16. У кнопки Normal Size установите свойство Down в значение True, предварительно убрав выделение кнопок Half Size и Normal Size. 17. Выполните компиляцию и запустите программу. Проверьте, что кнопки Half Size, Normal Size и Double Size работают как трехпозиционный переключатель. 18. Сделайте кнопки Save As, Half Size, Normal Size и Double Size недоступными, установив у них свойство Enabled в значение False. Эти кнопки будут оставаться недоступными, пока не будет открыт какой-нибудь рисунок. Обработка нажатий кнопок 56 19. Группа кнопок, управляющих масштабом рисунка, должна правильно переключаться даже тогда, когда пользователь устанавливает масштаб с помощью команд меню. Поэтому дополните обработчики событий так, как показано ниже: procedure TPictureForm.HalfSizeMenuItemClick(Sender: TObject); begin HalfSizeToolButton.Down := True; // кнопка согласуется с пунктом меню ... end; procedure TPictureForm.NormalSizeMenuItemClick(Sender: TObject); begin NormalSizeToolButton.Down := True; // кнопка согласуется с пунктом меню ... end; procedure TPictureForm.DoubleSizeMenuItemClick(Sender: TObject); begin DoubleSizeToolButton.Down := True; // кнопка согласуется с пунктом меню ... end; 20. Чтобы кнопки становились доступными или недоступными в зависимости от того, открыт рисунок или нет, подправьте метод EnableCommands: procedure TPictureForm.EnableCommands(Enable: Boolean); begin ... SaveAsToolButton.Enabled := Enable; HalfSizeToolButton.Enabled := Enable; NormalSizeToolButton.Enabled := Enable; DoubleSizeToolButton.Enabled := Enable; end; 57 3 Рекомендуемая литература 1 Бадд Т. Объектно-ориентированное программирование в действии / Перев. с англ. Бадд Т. Объектно-ориентированное программирование в действии. – СПб.: Питер, 1997. – 270с. – ISBN 5-88782-270-8. 2 Грэди Буч Объектно-ориентированный анализ и проектирование с примерами приложений на С++ = Object-Oriented Analysis and Design with Applications / Пер. И.Романовский, Ф.Андреев. – 2-е изд. – М., СПб.: Бином, Невский диалект, 1998. – 560с. – ISBN 5-7989-0067-3. 3 Лаптев, В. В. C++. Объектно-ориентированное программирование. / В.В. Лаптев. – СПб: Питер, 2008. – 464с. – ISBN: 978-5-91180-200-4. 4 Пышкин, Е.В. Основные концепции и механизмы объектноориентированного программирования/ Е.В. Пышкин. – СПб.: БХВ-Петербург, 2005. – 640с. – ISBN 589-0-371-9752-44. 5 Нил Дж. Рубенкинг. Язык программирования Delphi для «чайников». Введение в Borland Delphi 2006 Delphi for Dummies. – М.: Диалектика, 2007. – 336с. – ISBN 0-7645-0179-8. 6 Хавьер Пашеку. Программирование в Borland Delphi 2006 для профессионалов. Delphi for .NET Developer’s Guide. – М.: Вильямс, 2006. –944с. – ISBN 0-672-32443-X. 7 Шелест, В Программирование / В. Шелест. – СПб: БХВ-Петербург, 2002. – 592с. – ISBN 589-0-371-9874-34. 8 Ианова, Г.С., Ничушкина, Т.Н., Пугачев Е.К. Объектноориентированное программирование / Г. С. Иванова, Т.Н. Ничушкина, Е.К. Пугачев. – СПб: МГТУ им. Баумана, 2001 – 320с. – ISBN 589-0-332-969271. 9 Архангельский, А.Я. Программирование в Delphi. / А.Я. Архангельский. – М.: Нолидж, 2000, – 658с. –ISBN 093-04-0543-003-89. 10 Карчевская, М.П., Рамбургер, О.Л., Тархов, С.В., Хамзина, Е.А. Разработка приложений в среде Borland Delphi: лабораторный практикум по дисциплине «Информатика» / М.П. Карчевская, Е.А. Хамзина. – Уфа: УГАТУ, 2005, – 314с. – ISBN 563-6-890-2318-90. 11 Белов, В.В. Программирование в Delphi: процедурное, объектноориентированное, визуальное. / В.В. Белов. – М: Горячая Линия-Телеком, 2009. – 240с. 12 Культин, Н.Б. Основы программирования в Delphi 7. / Н.Б. Культин. – СПб.: БХВ-Петербург, 2005, – 291с. – ISBN 956-43-98340-0095-65. 13 Ревич, Ю. Нестандартные приемы программирования на Delphi. / Ю. Ревич. – СПб.: БХВ-Петербург, 2005. –323с. – ISBN 009-78-734-0989-67. 14 Сухарев, О.Т. Основы Delphi. Профессиональный подход. / О.Т. Сухарев. – СПб.: Питер Наука и Техника, 2004. – 582с. – ISBN 008-559045-00543-07. 15 Фленов, Р.О. Библия Delphi. / Р.О. Фленов. – СПб.: БХВ-Петербург, 2008. – 374с. – ISBN 0083-58-008-06065-04. 58 16 Шпак, Ю.А. Delphi 7 на примерах. / Ю. Шпак. – Киев: Юниор, 2003. – 248с. – ISBN 008-43-226-0301-61. 17 Дарахвелидзе, П., Марков, Е. Программирование в Delphi 7. / П. Дарахвелидзе, Е. Марков.– СПб.: БХВ-Петербург, 2003. – 248с. – ISBN 87605-9054-0542-41 18 Пачек, К. Программирование в Delphi 5. Руководство разработчика. / К. Пачек Программирование в Delphi 5. – М.: Нолидж, 2000, 248с. ISBN 121976-003-9321-07. 19 Фаранов, В.В. Учебное пособие по Delphi 4. / В.В. Фаранов. – СПб.: 1999. – 193с. – ISBN 437-0431-945-780. 59