- •Delphi
- •Краткий экскурс в историю
- •Языки программирования
- •Объектно-ориентированное программирование
- •Визуальное программирование
- •Среда программирования Delphi
- •Технология Java
- •Среда программирования Kylix
- •Технология .NET
- •... и опять среда Delphi
- •Что вы найдете в этой книге
- •Возможные трудности освоения
- •Глава 1. Основы визуального программирования
- •1.1. Краеугольные камни визуального программирования
- •1.2. Подготовка к работе
- •1.3. Первый запуск среды Delphi
- •1.4. Исследуем среду разработки программ
- •1.5. Первая программа
- •1.6. Итоги
- •Глава 2. Основы языка Delphi
- •2.1. Алфавит
- •2.1.1. Буквы
- •2.1.2. Числа
- •2.1.3. Слова-идентификаторы
- •2.1.4. Комментарии
- •2.2. Данные
- •2.2.1. Понятие типа данных
- •2.2.2. Константы
- •2.2.3. Переменные
- •2.3. Простые типы данных
- •2.3.1. Целочисленные типы данных
- •2.3.2. Вещественные типы данных
- •2.3.3. Символьные типы данных
- •2.3.4. Булевские типы данных
- •2.3.5. Определение новых типов данных
- •2.3.6. Перечисляемые типы данных
- •2.3.7. Интервальные типы данных
- •2.3.8. Временной тип данных
- •2.3.9. Типы данных со словом type
- •2.4. Операции
- •2.4.1. Выражения
- •2.4.2. Арифметические операции
- •2.4.3. Операции отношения
- •2.4.4. Булевские операции
- •2.4.5. Операции с битами
- •2.4.6. Очередность выполнения операций
- •2.5. Консольный ввод-вывод
- •2.5.1. Консольное приложение
- •2.5.2. Консольный вывод
- •2.5.3. Консольный ввод
- •2.6. Структура программы
- •2.6.1. Заголовок программы
- •2.6.2. Подключение модулей
- •2.6.3. Программный блок
- •2.7. Операторы
- •2.7.1. Общие положения
- •2.7.2. Оператор присваивания
- •2.7.3. Оператор вызова процедуры
- •2.7.4. Составной оператор
- •2.7.5. Оператор ветвления if
- •2.7.6. Оператор ветвления case
- •2.7.7. Операторы повтора — циклы
- •2.7.8. Оператор повтора for
- •2.7.9. Оператор повтора repeat
- •2.7.10. Оператор повтора while
- •2.7.11. Прямая передача управления в операторах повтора
- •2.7.12. Оператор безусловного перехода
- •2.8. Подпрограммы
- •2.8.1. Общие положения
- •2.8.2. Стандартные подпрограммы
- •2.8.3. Процедуры программиста
- •2.8.4. Функции программиста
- •2.8.5. Параметры процедур и функций
- •2.8.6. Опущенные параметры процедур и функций
- •2.8.7. Перегрузка процедур и функций
- •2.8.8. Соглашения о вызове подпрограмм
- •2.8.9. Рекурсивные подпрограммы
- •2.8.10. Упреждающее объявление процедур и функций
- •2.8.11. Процедурные типы данных
- •2.9. Программные модули
- •2.9.1. Структура модуля
- •2.9.2. Стандартные модули языка Delphi
- •2.9.3. Область действия идентификаторов
- •2.10. Строки
- •2.10.1. Строковые значения
- •2.10.2. Строковые переменные
- •2.10.3. Строки в формате Unicode
- •2.10.4. Короткие строки
- •2.10.5. Операции над строками
- •2.10.6. Строковые ресурсы
- •2.10.7. Форматы кодирования символов
- •2.10.8. Стандартные процедуры и функции для работы со строками
- •2.11. Массивы
- •2.11.1. Объявление массива
- •2.11.2. Работа с массивами
- •2.11.3. Массивы в параметрах процедур и функций
- •2.11.4. Уплотнение структурных данных в памяти
- •2.12. Множества
- •2.12.1. Объявление множества
- •2.12.2. Операции над множествами
- •2.13. Записи
- •2.13.1. Объявление записи
- •2.13.2. Записи с вариантами
- •2.14. Файлы
- •2.14.1. Понятие файла
- •2.14.2. Работа с файлами
- •2.14.3. Стандартные подпрограммы управления файлами
- •2.15. Указатели
- •2.15.1. Понятие указателя
- •2.15.2. Динамическое распределение памяти
- •2.15.3. Операции над указателями
- •2.15.4. Процедуры GetMem и FreeMem
- •2.16. Представление строк в памяти
- •2.17. Динамические массивы
- •2.18. Нуль-терминированные строки
- •2.19. Переменные с непостоянным типом значений
- •2.19.1. Тип данных Variant
- •2.19.2. Значения переменных с типом Variant
- •2.20. Delphi + ассемблер
- •2.20.1. Встроенный ассемблер
- •2.20.2. Подключение внешних подпрограмм
- •2.21. Итоги
- •Глава 3. Объектно-ориентированное программирование (ООП)
- •3.1. Краеугольные камни ООП
- •3.1.1. Формула объекта
- •3.1.2. Природа объекта
- •3.1.3. Объекты и компоненты
- •3.1.4. Классы объектов
- •3.1.5. Три кита ООП
- •3.2. Классы
- •3.3. Объекты
- •3.4. Конструкторы и деструкторы
- •3.5. Методы
- •3.6. Свойства
- •3.6.1. Понятие свойства
- •3.6.2. Методы получения и установки значений свойств
- •3.6.3. Свойства-массивы
- •3.6.4. Свойство-массив как основное свойство объекта
- •3.6.5. Методы, обслуживающие несколько свойств
- •3.7. Наследование
- •3.7.1. Понятие наследования
- •3.7.2. Прародитель всех классов
- •3.7.3. Перекрытие атрибутов в наследниках
- •3.7.4. Совместимость объектов различных классов
- •3.7.5. Контроль и преобразование типов
- •3.8. Виртуальные методы
- •3.8.1. Понятие виртуального метода
- •3.8.2. Механизм вызова виртуальных методов
- •3.8.3. Абстрактные виртуальные методы
- •3.8.4. Динамические методы
- •3.8.5. Методы обработки сообщений
- •3.9. Классы в программных модулях
- •3.10. Разграничение доступа к атрибутам объектов
- •3.11. Указатели на методы объектов
- •3.12. Метаклассы
- •3.12.1. Ссылки на классы
- •3.12.2. Методы классов
- •3.12.3. Виртуальные конструкторы
- •3.13. Классы общего назначения
- •3.13.1. Классы для представления списка строк
- •Свойства:
- •Методы:
- •События:
- •3.13.2. Классы для представления потока данных
- •Общие свойства:
- •Общие методы:
- •3.14. Итоги
- •Глава 4. Исключительные ситуации и надежное программирование
- •4.1. Ошибки и исключительные ситуации
- •4.2. Классы исключительных ситуаций
- •4.3. Обработка исключительных ситуаций
- •4.3.1. Создание исключительной ситуации
- •4.3.2. Распознавание класса исключительной ситуации
- •4.3.3. Пример обработки исключительной ситуации
- •4.3.4. Возобновление исключительной ситуации
- •4.3.5. Доступ к объекту, описывающему исключительную ситуацию
- •4.4. Защита выделенных ресурсов от пропадания
- •4.4.1. Утечка ресурсов и защита от нее
- •4.5. Итоги
- •Глава 5. Динамически загружаемые библиотеки
- •5.1. Динамически загружаемые библиотеки
- •5.2. Разработка библиотеки
- •5.2.1. Структура библиотеки
- •5.2.2. Экспорт подпрограмм
- •5.2.3. Соглашения о вызове подпрограмм
- •5.2.4. Пример библиотеки
- •5.3. Использование библиотеки в программе
- •5.3.1. Статический импорт
- •5.3.2. Модуль импорта
- •5.3.3. Динамический импорт
- •5.4. Использование библиотеки из программы на языке C++
- •5.5. Глобальные переменные и константы
- •5.6. Инициализация и завершение работы библиотеки
- •5.7. Исключительные ситуации и ошибки выполнения подпрограмм
- •5.8. Общий менеджер памяти
- •5.9. Стандартные системные переменные
- •5.10. Итоги
- •Глава 6. Интерфейсы
- •6.1. Понятие интерфейса
- •6.2. Описание интерфейса
- •6.3. Расширение интерфейса
- •6.4. Глобально-уникальный идентификатор интерфейса
- •6.5. Реализация интерфейса
- •6.6. Использование интерфейса
- •6.7. Реализация нескольких интерфейсов
- •6.8. Реализация интерфейса несколькими классами
- •6.9. Связывание методов интерфейса с методами класса
- •6.10. Реализация интерфейса вложенным объектом
- •6.11. Совместимость интерфейсов
- •6.12. Совместимость класса и интерфейса
- •6.13. Получение интерфейса через другой интерфейс
- •6.14. Механизм подсчета ссылок
- •6.15. Представление интерфейса в памяти
- •6.17. Итоги
- •Глава 7. Проект приложения
- •7.1. Проект
- •7.1.1. Понятие проекта
- •7.1.2. Файлы описания форм
- •7.1.3. Файлы программных модулей
- •7.1.4. Главный файл проекта
- •7.1.5. Другие файлы проекта
- •7.2. Управление проектом
- •7.2.1. Создание, сохранение и открытие проекта
- •7.2.2. Окно управления проектом
- •7.2.3. Группы проектов
- •7.2.4. Настройка параметров проекта
- •7.2.5. Компиляция и сборка проекта
- •7.2.6. Запуск готового приложения
- •7.3. Форма
- •7.3.1. Понятие формы
- •7.3.2. Имя и заголовок формы
- •7.3.3. Стиль формы
- •7.3.4. Размеры и местоположение формы на экране
- •7.3.5. Цвет рабочей области формы
- •7.3.6. Рамка формы
- •7.3.7. Значок формы
- •7.3.8. Невидимая форма
- •7.3.9. Прозрачная форма
- •7.3.10. Полупрозрачная форма
- •7.3.11. Недоступная форма
- •7.3.12. События формы
- •7.4. Несколько форм в приложении
- •7.4.1. Добавление новой формы в проект
- •7.4.2. Добавление новой формы из Хранилища Объектов
- •7.4.3. Переключение между формами во время проектирования
- •7.4.4. Выбор главной формы приложения
- •7.4.5. Вызов формы из программы
- •7.5. Компоненты
- •7.5.1. Понятие компонента
- •7.5.2. Визуальные и невизуальные компоненты
- •7.5.3. «Оконные» и «графические» компоненты
- •7.5.4. Общие свойства визуальных компонентов
- •7.5.5. Общие события визуальных компонентов
- •7.6. Управление компонентами при проектировании
- •7.6.1. Помещение компонентов на форму и их удаление
- •7.6.2. Выделение компонентов на форме
- •7.6.3. Перемещение и изменение размеров компонента
- •7.6.4. Выравнивание компонентов на форме
- •7.6.5. Использование Буфера обмена
- •7.7. Закулисные объекты приложения
- •7.7.1. Application — главный объект, управляющий приложением
- •7.7.2. Screen — объект, управляющий экраном
- •7.7.3. Mouse — объект, представляющий мышь
- •7.7.4. Printer — объект, управляющий принтером
- •7.7.5. Clipboard — объект, управляющий Буфером обмена
- •7.8. Итоги
- •Глава 8. Меню, строка состояния и панель инструментов
- •8.1. Меню
- •8.1.1. Идея меню
- •8.1.2. Главное меню
- •8.1.3. Дизайнер меню
- •8.1.4. Пункты меню
- •8.1.5. Разделительные линии
- •8.1.6. Комбинации клавиш
- •8.1.7. Обработка команд меню
- •8.1.8. Пункты-переключатели
- •8.1.9. Взаимоисключающие переключатели
- •8.1.10. Недоступные пункты меню
- •8.1.11. Контекстное меню
- •8.1.12. Значки в пунктах меню
- •8.2. Полноценное приложение для просмотра графических файлов
- •8.2.1. Диалоговые окна открытия и сохранения файла
- •8.2.2. Отображение рисунков
- •8.3. Строка состояния
- •8.3.1. Создание строки состояния
- •8.3.2. Подсказки в строке состояния
- •8.4. Прокрутка
- •8.4.1. Прокрутка рабочей области формы
- •8.4.2. Отдельная область прокрутки
- •8.4.3. Полосы прокрутки
- •8.5. Панель инструментов
- •8.5.1. Панель
- •8.5.2. Кнопки
- •8.5.3. Значки на кнопках
- •8.5.4. Надписи на кнопках
- •8.5.5. Разделительные линии
- •8.5.6. Кнопки-переключатели
- •8.5.7. Обработка нажатий кнопок
- •8.5.8. Подсказки к кнопкам
- •8.5.9. Управление видимостью панели кнопок
- •8.6. Список команд
- •8.6.1. Создание списка команд
- •8.6.2. Команды
- •8.6.3. Привязка команд
- •8.6.4. Реакция на команды
- •8.6.5. Управление состоянием команд
- •8.7. Итоги
- •Глава 9. Окна диалога
- •9.1. Понятие окна диалога
- •9.2. Окно "About"
- •9.2.1. Подготовка формы
- •9.2.2. Кнопка
- •9.2.3. Кнопка с рисунком
- •9.2.4. Украшение окна диалога рисунком
- •9.2.5. Текстовая надпись
- •9.2.6. Рельефная канавка
- •9.2.7. Рельефная панель
- •9.2.8. Выполнение диалога
- •9.3. Компоненты для ввода данных
- •9.3.1. Фокус ввода
- •9.3.2. Переключатели
- •9.3.3. Взаимоисключающие переключатели
- •9.3.4. Группа взаимоисключающих переключателей
- •9.3.5. Панель группы компонентов
- •9.3.6. Поле ввода и редактор текста
- •9.3.7. Редактор с шаблоном
- •9.3.8. Раскрывающийся список
- •9.3.9. Установка и получение данных
- •9.3.10. Список
- •9.4. Законченное приложение для выдачи сигналов в заданные моменты времени
- •9.4.1. Таймер
- •9.4.2. Файлы настроек
- •9.5. Многостраничные окна диалога
- •9.5.1. Страницы с закладками
- •9.5.2. Закладки без страниц
- •9.6. Итоги
- •Рекомендуется:
Рисунок 1.15. Панель для сохранения и восстановления внешнего вида среды Delphi
Вот вы и изучили основные элементы среды визуального программирования! Вы познакомились со средой Delphi только в самых общих чертах, но этого достаточно, чтобы попробовать написать первую программу.
1.5. Первая программа
Пора обрадовать ваших родственников и знакомых приятным сообщением о том, сколько они должны весить для поддержания хорошего здоровья. Для этого напишем программу вычисления оптимального веса по известному вам сценарию. Как вы помните, форма для задачи содержит две кнопки (для запуска вычислений и завершения работы) и два поля (для ввода значения роста в сантиметрах и вывода веса в килограммах).
Вы, конечно, уже запустили среду Delphi, и видите перед собой пустую форму. Начнем с кнопок. Наведите указатель мыши на палитру компонентов и щелкните на значке с подсказкой Button (рисунок 1.16).
Рисунок 1.16. Значок компонента Button
Затем наведите указатель мыши на форму и щелкните еще раз. Заготовка кнопки с надписью Button1 окажется на форме (рисунок 1.17):
Рисунок 1.17. Заготовка кнопки на форме
30
Ваше дело — сделать из заготовки "конфетку"! С помощью мыши подправьте ее местоположение. После этого перейдите к окну Object Inspector. Там вы увидите список свойств компонента Button. В нем нас интересует свойство Caption, так как именно оно определяет содержимое надписи. Заменим в свойстве Caption стандартное значение Button1 на
Compute (рисунок 1.18).
Рисунок 1.18. Кнопка Compute
Точно так же на форму помещается вторая кнопка с надписью Close
(рисунок 1.19):
Рисунок 1.19. Кнопка Close
Теперь возьмемся за поля ввода и вывода. Для этого покинем на время окно Object Inspector и перейдем к палитре компонентов. Там вы найдете компонент Edit (рисунок 1.20), который лучше всего отвечает нашим целям.
Рисунок 1.20. Значок компонента Edit
31
Щелкните на нем, затем наведите указатель мыши в нужное место формы и щелкните еще раз. На форме появится поле ввода. Изначально оно содержит текст Edit1 (рисунок 1.21):
Рисунок 1.21. Поле ввода исходных данных
Придайте компоненту нужные размеры и откорректируйте местоположение. Готово? Теперь снова перейдите к окну Object Inspector. Нас интересует свойство Text. Удалите в нем ненужное значение Edit1 и содержимое поля на форме сразу же очистится.
Точно так же приготовьте поле для вывода результата вычислений. Вот вы и получили форму, полностью отвечающую сценарию работы программы
(рисунок 1.22):
Рисунок 1.22. Поле вывода результата вычислений
Ба! Да мы забыли дать название нашей прекрасной форме и надписать поля для ввода и вывода! Исправим этот досадный пробел: присвоим свойству
32
Caption для формы в целом значение Weight Calculator и оно появится в заголовке формы. Теперь давайте озаглавим редактируемые поля. Над окном ввода данных напишем Specify your height, а над окном вывода результата Your ideal weight. Вы помните, что строка текста на форме — такой же компонент, как, например, кнопка. Поэтому обратитесь к палитре компонентов, выберите компонент Label (рисунок 1.23)
Рисунок 1.23. Значок компонента Label
и поместите его над полем ввода. Отрегулируйте местоположение компонента с помощью мыши и в значении свойства Caption наберите текст первой надписи. Затем повторите те же манипуляции для поля вывода. В результате получилась очень неплохая основа для будущей программы
(рисунок 1.24):
Рисунок 1.24. Форма для задачи вычисления оптимального веса человека
Все это хорошо, но работает ли на практике? Давайте проверим: на панели кнопок нажмите кнопку с подсказкой Run (Запуск) или выберите в меню команду Run | Run. Этим вы одновременно выполните компиляцию и запустите приложение. Понажимайте кнопки Compute и Close. Работают? Да. Перейдите в поле ввода и понажимайте цифровые клавиши. Нормальный ввод? Да. Однако вычислений никаких нет. Почему? Потому что события (нажатия кнопок) есть, а вот отклика на них нет — мы просто этим вопросом еще не занимались.
Закрыв приложение, приступим к обработке событий. Начнем с нажатия кнопки Compute. Активизируйте кнопку, с которой будем работать, затем перейдите к окну Object Inspector и переключитесь на вкладку Events (события). На ней вы обнаружите список всех возможных событий для
33
активного компонента (в данном случае кнопки). Нас интересует событие OnClick, возникающее при нажатии кнопки. Чтобы запрограммировать обработчик этого события, сделайте двойной щелчок мыши в поле значения. Появится окно редактора кода с заготовкой для нашего обработчика
(рисунок 1.25):
Рисунок 1.25. Заготовка в редакторе кода для обработки щелчка кнопки Compute
Вычисление оптимального веса делается в одну строку:
procedure TForm1.Button1Click(Sender: TObject); begin
Edit2.Text := IntToStr(StrToInt(Edit1.Text) - 100 - 10); end;
Теперь займемся кнопкой Close. Обработчик события для нее устанавливается аналогично: кнопка активизируется на форме, в окне Object Inspector выбирается вкладка Events и на значении события OnClick делается двойной щелчок мыши. Текст этого обработчика еще проще, чем текст предыдущего:
procedure TForm1.Button2Click(Sender: TObject); begin
Close;
end;
Процедура Close, вызываемая при нажатии кнопки Close, закрывает форму и завершает программу.
Теперь давайте сохраним результат нашей работы. Для этого выберите команду меню File | Save All. Сначала среда Delphi предложит ввести имя для модуля формы, а потом — имя для всего проекта. Модуль назовем
Unit1.pas (рисунок 1.26),
34
Рисунок 1.26. Окно, выдаваемое при сохранении нового модуля
а проект — Project1.dpr (рисунок 1.27):
Рисунок 1.27. Окно, выдаваемое при сохранении нового проекта
Все файлы, которые относятся к решению задачи и составляют проект, будут записаны на диск в заданный каталог. Сохраненный проект может быть открыт для доработки в любой момент.
Теперь давайте поработаем с программой по-настоящему. Запустите ее (с помощью команды меню Run | Run), активизируйте поле с надписью Specify your height и введите значение роста своего любимого дядюшки Джо (170 см). Исходный материал есть, пора начать вычисления. Нажмите кнопку Compute. В выходном поле появится значение 60 (рисунок 1.28):
35
Рисунок 1.28. Работающая программа вычисления оптимального веса человека
Что-то здесь не то. Дядя Джо весит 90 кг... Может быть, наша программа неправильно считает? Нет, дело здесь не в программе, просто дядюшке нужно немного похудеть — килограмм на 30.
Очевидно, что программа работает. А как насчет отказоустойчивости? Давайте проверим: запустим программу и вместо значения роста введем какую-нибудь строку, например, JOHN. Что случилось? На экране появилось сообщение об ошибке (рисунок 1.29) и программа временно прекратила работу.
Рисунок 1.29. Сообщение об ошибке
Причина: при попытке обработать строку вместо числа, система попала в исключительную ситуацию. В нашем случае программа запускалась из среды Delphi, которая перехватывает исключительную ситуацию и показывает вам приведенное выше окно Error. Нажмите OK и вы увидите то место в программе, где возникла исключительная ситуация. Программа приостановлена, продолжить ее выполнение можно, нажав в среде Delphi кнопку Run. Приложение выдаст сообщение о том, что JOHN — это неверное числовое значение (рисунок 1.30):
36