- •Министерство образования и науки
- •Введение 13
- •Глава 1. Язык программирования Delphi 22
- •Глава 2. Среда разработки Delphi 88
- •Глава 3. Работа с базами данных 143
- •Глава 4. Взаимодействие приложений 207
- •Глава 5. Дополнительные возможности 229
- •Except application.Messagebox('приложение будет закрыто', 'ошибка!', 0); 233
- •Глава 8. Лабораторный практикум 289
- •Приложения 333
- •Лабораторные работы
- •Методы структурного программирования
- •Объектно-ориентированное программирование
- •Сравнительный анализ объектно-ориентированных языков программирования
- •Глава 1. Язык программированияDelphi
- •1.1. Типы данных
- •1.1.1. Константы
- •1.1.2. Переменные
- •1.1.3. Простые типы данных
- •1.1.3.1. Целые типы
- •1.1.3.2. Вещественные типы
- •1.1.3.3. Логические типы
- •1.1.3.4. Символьныетипы
- •1.1.3.5. Тип дата ‑ время (tDateTime)
- •1.1.3.6. Перечисляемые типы
- •1.1.3.7. Интервальные типы
- •1.1.3.8. Порядковые типы
- •1.1.4.Структурированные типы данных
- •1.1.4.1. Статические массивы
- •1.1.4.2. Динамические массивы
- •1.1.4.3. Записи
- •1.1.4.4. Множества
- •1.1.5. Типы строк
- •1.1.6. Универсальные типы -Variant
- •1.1.7. Массивы типаVariant
- •1.1.8. Указатели
- •1.1.9. Процедурные типы
- •1.1.10. Процедурные указатели
- •Вопросы для самопроверки и контроля
- •1.2. Операции
- •1.2.1. Арифметические операции
- •1.2.2. Операции присвоения и сравнения
- •1.2.3. Логические операции
- •1.2.4. Логические поразрядные операции
- •1.2.5. Операции со строками
- •1.2.6. Операции над множествами
- •1.2.7. Операции с указателями
- •1.2.8. Порядок вычисления выражений
- •1.2.9. Преобразование типов
- •Вопросы для самопроверки и контроля
- •1.3. Структура и этапы разработки проекта
- •1.3.1. Структура проекта
- •1.3.1.1. Основные типы файлов
- •1.3.1.2. Файлы ресурсов
- •1.3.2. Программа
- •1.3.2.1. Структура программы
- •1.3.2.2. Структура головной программы проекта
- •1.3.3. Подпрограммы
- •1.3.3.1. Типы подпрограмм
- •1.3.3.2. Процедуры и функции, определенные пользователем
- •1.3.4. Модули
- •Interfac e //интерфейсная часть с объявлением типов и процедур
- •Implementation //исполнимая часть с текстами процедур
- •1.3.5. Компилятор
- •1.3.5.1. Общее описание компилятора
- •1.3.5.2. Основные директивы компилятора
- •1.3.5.3. Директивы условной компиляции
- •1.3.6. Этапы разработки проекта
- •1.3.6.5. Выполнение консольного приложения иDos‑программ
- •1.3.7. Отладка
- •1.3.7.1. Максимальный контроль ошибок
- •1.3.7.2. Оптимизация кода программы
- •1.3.7.3. Пошаговое выполнение программы
- •1.3.7.4. Протокол событий
- •1.3.7.5. Просмотр и изменение значений
- •1.3.7.6. Просмотр программного кода
- •1.3.7.7. Отладка внешних процессов
- •1.3.7.8. Отладка в машинных кодах
- •1.3.7.9. Инспектор отладки
- •1.3.8. Редактор кода
- •Вопросы для самопроверки и контроля
- •1.4. Операторы
- •1.4.1.Общие сведения
- •1.4.2.Оператор присваивания
- •Примеранализа односимвольного ответа пользователя:
- •1.4.8.Операторы цикла
- •1.4.8.1. Счетный цикл For
- •1.4.8.2. Цикл Repeat‑ Until
- •1.4.8.3. ЦиклWhile
- •1.4.9. Оператор присоединения имени ‑With
- •1.4.10. Вставка команд ассемблера
- •Вопросы для самопроверки и контроля
- •1.5. Объектно‑ориентированное программирование
- •1.5.1. Определение
- •1.5.2. Объявление класса и объекта
- •1.5.3. Динамическое создание и удаление объекта
- •1.5.4. Динамическое конструирование объектов
- •1.5.5. Свойства
- •1.5.6. Методы
- •1.5.7. Конструкторы и деструкторы
- •1.5.8. События
- •Вопросы для самопроверки и контроля
- •1.6. Обработка исключительных ситуаций
- •1.6.1. Исключения
- •1.6.2. Иерархия классов исключений
- •1.6.3. Свойства и конструкторы исключений
- •1.6.4. Блок зачисткиTry‑Finally‑End
- •1.6.5. Зачистка в разделе модуляFinalization
- •1.6.6. Блок обработки исключенийTry‑Except‑End
- •1.6.7. Искусственная генерация исключений
- •1.6.8. ИсключенияEAbortи функцияAbort
- •1.6.9. Создание нового типа исключения
- •Вопросы для самопроверки и контроля
- •1.7.2.2. Функция форматированияFormat
- •1.7.3. Преобразование дат и времени
- •1.7.4. Обработка строк с нулевым символом в конце
- •1.7.5. Обработка строк без нулевого символа в конце
- •1.7.6.Диалоговые окна ввода и вывода сообщений
- •1.7.7.Воспроизведение звуков
- •1.7.8. Запуск из приложения внешних программ
- •1.7.9.Специальные процедуры и функции
- •1.7.10.СообщенияWindows
- •Вопросы для самопроверки и контроля
- •1.8. Файлы
- •1.8.1. Типы файлов
- •1.8.2. Файлы Паскаля
- •1.8.2.1. Любые файлы
- •1.8.2.2. Типизированные файлы
- •1.8.2.3. Текстовые файлы
- •1.8.2.4. Печать текста
- •1.8.2.5. Нетипизированные файлы
- •1.8.3. Объектный подход к файлам
- •1.8.4. ФайлыWindows
- •1.8.5. Обслуживание внешних файлов и каталогов
- •Вопросы для самопроверки и контроля
- •1.9. Динамические структуры данных
- •1.9.1.Общие сведения
- •1.9.2. Процедуры и функции динамического распределения памяти
- •1.9.3. Формирование стека
- •1.9.4. Формирование очереди
- •Вопросы для самопроверки и контроля
- •Глава 2. Среда разработкиDelphi
- •2.1. Общие сведения
- •2.1.1. Окна
- •2.1.2. Панели компонентов и их настройка
- •2.1.3. Архив объектов (репозиторий)
- •2.1.4. Справочная система
- •2.1.5. Характеристика компонентов
- •2.1.6. Размещение и настройка компонентов на форме
- •2.1.7. Свойства
- •2.1.7.1. Имя объекта
- •2.1.7.2. Внешний вид объекта
- •2.1.7.3. Размеры объекта
- •2.1.7.4. Местоположение объекта
- •2.1.7.5. Перемещение объекта
- •2.1.7.6. Доступ к объекту
- •2.1.7.7. Значение объекта
- •2.1.7.8. Меню
- •2.1.7.9. Вид указателя мыши
- •2.1.7.10. Справочная система
- •2.1.7.11. Наследование родительских свойств
- •2.1.8. События
- •2.1.8.1. Процедуры обработки событий
- •2.1.8.2. Мышь
- •2.1.8.3. Клавиатура
- •2.1.8.4. Перемещение объектов
- •2.1.8.5. Другие события
- •2.1.9. Методы
- •2.2. Глобальные объекты
- •2.2.1. Формы (Form)
- •2.2.1.1. Свойства
- •2.2.1.2. Методы
- •2.2.1.3. События
- •2.2.1.4. Некоторые приемы работы с формами
- •2.2.2. Приложение (Application)
- •2.2.2.1. Свойства
- •2.2.2.2. Методы
- •2.2.2.3. События
- •2.2.3. Экран (Screen)
- •2.2.3.1. Свойства
- •2.2.3.2. Методы
- •2.2.3.3. События
- •2.2.4. Принтер (Printer)
- •2.2.4.1. Свойства
- •2.2.4.2. Методы
- •2.2.5. Буфер обменаWindows(Clipboard)
- •2.2.5.1. Свойства
- •2.2.5.2. Методы
- •2.2.6. Списки (tList)
- •2.2.6.1. Свойства
- •2.2.6.2. Методы
- •2.2.6.3. Схема создания списка
- •2.2.7.Список строк и объектов (tStringList)
- •2.2.7.1. Свойства
- •2.2.7.2. События
- •2.2.7.3. Методы
- •2.2.8. Графика
- •2.2.8.1. Шрифт (tFont)
- •2.2.8.2. Перо (tPen)
- •2.2.8.3. Кисть (tBrush)
- •2.2.8.4. Канва, ее свойства и графические методы (tCanvas)
- •2.2.8.5. Изображение (tGraphic,tPicture)
- •2.2.8.6. Анимация
- •2.3. Основные компоненты
- •2.3.1. Вывод текста
- •2.3.1.1. Текстовая надпись (Label)
- •2.3.1.2. Статическая текстовая надпись (StaticText)
- •2.3.1.3. Строка состояния (StatusBar)
- •2.3.2. Ввод и редактирование данных
- •2.3.2.1. Одностроковый текст (Edit)
- •2.3.2.2. Одностроковый текст с маской (MaskEdit)
- •2.3.2.3. Многостроковый текст (Memo)
- •2.3.2.4. Таблица строк (StringGrid)
- •2.3.2.5. Рисуемая таблица (DrawGrid)
- •2.3.2.6. Многострочный редактор текста в форматеRtf(RichEdit)
- •2.3.2.7. Дата и время (DateTimePicker)
- •2.3.3. Списки
- •2.3.3.1. Простой список (ListBox)
- •2.3.3.2. Комбинированный список (ComboBox)
- •2.3.4. Командные кнопки
- •2.3.4.1. Стандартная кнопка (Button)
- •2.3.4.2. Кнопка с рисунком (BitBtn)
- •2.3.4.3. Кнопка быстрого доступа (SpeedButton)
- •2.3.4.4. Независимый переключатель (CheckBox)
- •2.3.4.5. Зависимый переключатель (RadioButton)
- •2.3.5.3. Группа независимых переключателей (CheckListBox)
- •2.3.5.4. Панель (Panel)
- •2.3.5.5. Область прокрутки (ScrollBox)
- •2.3.5.6. Фрейм (Frame)
- •2.3.5.7. Разделители контейнеров (Splitter)
- •2.3.5.8. Прокрутка страниц (PageScroller)
- •2.3.6. Счетчики
- •2.3.6.1. Полоса прокрутки ‑ счетчик (ScrollBar)
- •2.3.6.2. Ползунок (TrackBar)
- •2.3.6.3. Счетчик (UpDown)
- •2.3.6.4. Редактируемое поле со счетчиком (SpinEdit)
- •2.3.6.5. Индикаторы процесса выполнения программы (ProgressBar,Gauge)
- •2.3.7. Графика
- •2.3.7.1. Изображение (Image)
- •2.3.7.2. Список изображений (ImageList)
- •2.3.7.3. Геометрическая фигура (Shape)
- •2.3.7.4. Фаска (Bevel)
- •2.3.7.5. Окно рисования (PaintBox)
- •2.3.7.6. Простая диаграмма (Gauge)
- •2.3.7.7. Диаграмма (Chart)
- •2.3.8. Меню
- •2.3.8.1. Главное меню (MainMenu)
- •2.3.8.2. Контекстное меню (PopupMenu)
- •2.3.8.3. Программная настройка меню
- •2.3.8.4. Горячие клавиши (HotKey)
- •2.3.8.5. Синхронизация объектов (ActionList)
- •2.3.8.6. События приложения (ApplicationEvents)
- •2.3.9. Структурированные компоненты
- •2.3.9.1. Панели инструментов (ToolBar)
- •2.3.9.2. Панель управления (ControlBar)
- •2.3.9.3. Расширенная панель управления (CoolBar)
- •2.3.9.4. Набор страниц (PageControl)
- •2.3.9.5. Переключаемые страницы (TabControl)
- •2.3.9.6. Список элементов (ListView)
- •2.3.9.7. Дерево элементов (TreeView)
- •2.3.10. Системные компоненты
- •2.3.10.1. Таймер (Timer)
- •2.3.10.2. Мультимедийный проигрыватель (MediaPlayer)
- •2.3.10.3. АнимацияAvi(Animation)
- •2.3.11. Стандартные диалоги
- •2.3.11.1. Открытие и сохранение файла (OpenDialog,SaveDialog)
- •2.3.11.2. Открытие и сохранение графического файла (OpenPictureDialog,SavePictureDialog)
- •2.3.11.3. Выбор шрифта (FontDialog)
- •2.3.11.4. Выбор цвета (ColorDialog)
- •2.3.11.5. Настройка печати (PrintDialog)
- •2.3.11.6. Настройка принтера (PrinterSetupDialog)
- •2.3.11.7. Поиск (FindDialog)
- •2.3.11.8. Поиск и замена (ReplaceDialog)
- •2.3.11.9. Выбор диска (DriveComboBox)
- •2.3.11.10. Выбор каталога (DirectoryListBox)
- •Вопросы для самопроверки и контроля
- •Глава 3. Работа с базами данных
- •3.1. Основные понятия
- •3.2. Создание базы данных
- •3.3. Создание модуля данных
- •3.4. Компоненты доступа к данным (DataAccess)
- •3.4.1. Таблица (Table)
- •3.4.2. Источник данных (DataSource)
- •3.4.3. Описание и доступ к полям записи базы данных
- •3.4.4. Компоненты работы с базой (DataControl)
- •3.5. Установка связей между таблицами
- •3.6. Установка полей соответствия (Lookup)
- •3.7. Создание запросов
- •3.7.1. Визуальные средства
- •3.7.2. Командные средстваSql
- •3.8. Основные операции с записями
- •3.9. Мастер форм
- •3.10. Формирование отчетов средствамиQuickReports
- •3.10.1. Быстрый отчет (QuickRep)
- •3.10.2. Компоненты отчета
- •3.10.3. Простой отчет
- •3.10.4. Отчет из нескольких таблиц с группировкой данных и итогами
- •3.10.5. Отчет типа «мастер/детальный»
- •3.10.6. Составной отчет
- •3.11. Формирование отчетов средствамиRaveReports
- •3.11.1. Компоненты отчета
- •3.11.2. Конструктор отчетов
- •3.11.3. Компоненты панели инструментов
- •3.11.4. Отчет из нескольких таблиц с группировкой данных и итогами
- •3.12. Формирование отчетов средствамиFastReports
- •3.12.1. Компоненты отчета
- •3.12.2. Конструктор отчетов
- •3.12.3. Компоненты панели инструментов
- •3.12.4. Отчет из нескольких таблиц с группировкой данных и итогами
- •3.13. Анализ данныхcредствами многомерного кубаDecisionCube
- •3.14. Клиент‑серверные субд
- •3.15. Доступ к данным по технологииAdo
- •Вопросы для самопроверки и контроля
- •Глава 4. Взаимодействие приложений
- •4.1. Создание динамически подключаемых библиотек (dll)
- •4.2. Создание новых компонентов
- •4.3. Создание и установкаActiveX‑элементов
- •4.4. Создание и установка пакетов
- •4.5. Использование пакетов
- •4.6. Технология связывания и внедрения объектов (ole)
- •4.7. Многопоточные приложения
- •4.8. Технология применения объектовCom,dcom
- •4.9. Распределенные двухуровневые клиент‑серверные приложения
- •4.10.2. Создание сервера приложений доступа к базе данных
- •4.10.3. Связь с сервером приложений по протоколуDcom
- •4.10.4. Связь с сервером приложений по протоколу ИнтернетTcp/ip
- •4.10.5. Связь с сервером приложений по протоколуHttp
- •4.10.6. Основы разработки приложений Internet
- •Глава 5. Дополнительные возможности
- •5.1. Создание справочной системы
- •5.2. Обзор остальных возможностей
- •5.3. Формирование отчетов, диаграмм и анализа данных пакетомCrystalReports
- •5.4. Работа сExcel
- •5.5. Работа с Word
- •Except application.Messagebox('приложение будет закрыто', 'ошибка!', 0);
- •5.6. Основные отличия новых версий Delphi
- •6.1. Лексические структуры языка
- •6.1.1. Элементы
- •6.1.2. Константы
- •6.1.3. Типы данных
- •Простейшие скалярные стандартные типы
- •6.1.4. Массивы
- •6.1.5. Структуры (записи)
- •6.1.6. Объединенияunion
- •6.2.3. Директива #define
- •6.2.4. Функция вывод на терминал -Printf
- •6.2.5. Функция ввод с клавиатуры -Scanf
- •6.2.6. ФункцияMainв консольных приложениях
- •6.2.7. Функции
- •Int main(int argc,char **argv) // основная функция
- •Int main(int argc, char **argv) // основная функция
- •6.2.8. Классы памяти
- •6.2.8.1. Автоматические переменные
- •6.2.8.2. Регистровые переменные
- •6.2.8.3. Статические переменные и функции
- •6.2.8.4. Внешние переменные
- •6.2.9. Операции
- •6.2.9.1.Арифметические операции
- •6.2.9.2.Операции отношения
- •6.2.9.3. Логические операции
- •6.2.9.4.Операции присваивания
- •6.2.10. Операторы
- •6.2.10.6.Оператор безусловного перехода ‑goto
- •6.2.10.7. Цикл с предусловием ‑while
- •Int main(int argc, char **argv) // основная функция
- •6.2.10.9.Итерационный цикл ‑For
- •Int main(int argc, char **argv) { // основная функция
- •Int main(int argc, char **argv) { // основная функция
- •Int main(int argc, char **argv) { // основная функция
- •Void bubble_sort( float a [ ], int s ) { // функция сортировки массива
- •6.2.10.10. Пустой оператор
- •6.3. Указатели
- •6.4. Функции, методы и макросы
- •6.4.1. Математика
- •6.4.2. Обработка статистических данных
- •6.4.3. Взаимное преобразование чисел и строк типа char
- •Long double _strtold(const char *s, char**endptr) ‑ строки s в действительное число.
- •Char *gcvt(double value, int ndec, char *buf) ‑ value в строку buf с числом цифр ndec.
- •6.4.4. Взаимное преобразование чисел и строк типа AnsiString
- •6.4.5. Преобразования дат и времени
- •6.4.6. Методы обработки строк типа AnsiString
- •6.4.7. Функции обработки строк типа AnsiString
- •6.4.8. Макросы обработки символов
- •6.4.9. Обработка строк с нулевым символом в конце
- •6.4.10. Управление каталогами и файлами на дисках
- •6.4.11.Диалоговые окна ввода и вывода сообщений
- •6.4.12.Воспроизведение звуков
- •6.4.13. Управление текущим процессом
- •6.4.14. Запуск из приложения внешних программ
- •6.5. Работа с файлами
- •6.5.1. Файлы в с
- •Int main(int argc, char **argv) // основная функция
- •Void __fastcall tForm1::Button1Click(tObject *Sender) // процедура
- •6.6. Объектно‑ориентированное программирование
- •6.6.1. Создание классов и объектов
- •6.6.2. Виртуальные методы
- •6.6.3. Дружественные функции
- •6.6.4. Шаблоны
- •6.6.5. Пространство имен
- •6.6.6. Явные объявления конструкторов
- •6.6.7. Непостоянные объявления
- •6.6.8. Быстрый вызов функций -_fastcall
- •6.6.9. Блок обработки исключенийtry‑catch-_finally
- •Вопросы для самопроверки и контроля
- •7.1. Создание консольного приложения
- •7.2. Основные элементы управления
- •7.3. Списки
- •Void cPrimDlg::OnAdd() //обработка кнопки «Добавить»
- •Void cPrimDlg::OnDelete()//обработка кнопки «Удалить»
- •Void cPrimDlg::OnDblclkList1() //обработка двойного щелчка по списку
- •7.4. Линейные регуляторы и индикаторы
- •Void cPrimDlg::OnCheck2()//обработка переключателя «Сброс»
- •Var // раздел переменных модуля Unit1
- •8.1.2. Секундомер (Delphi)
- •Var // раздел переменных модуля Unit1
- •8.1.3. Бегущая строка (Delphi)
- •8.1.4. Рисование на экране (Delphi)
- •Var AllowChange: Boolean); // изменение счетчика UpDown1
- •8.1.5. Тестирование по арифметике (Delphi)
- •Var // раздел переменных модуля Unit1
- •8.1.6. Игра «Морской бой» (Delphi)
- •Var // раздел переменных модуля Unit1
- •8.1.7. Вывод диаграммы (Delphi)
- •Var // раздел переменных модуля Unit1
- •8.1.8. Работа компонентов панелейStandard,AdditionalиWin32 (Delphi)
- •Void __fastcall tForm1::Button1Click(tObject *Sender) / /кнопка «Выход»
- •Void __fastcall tForm1::Button3Click(tObject *Sender) // кнопка «Загадать»
- •Void __fastcall tForm1::Button4Click(tObject *Sender) //кн.»Назвать слово»
- •Void __fastcall tForm1::Button5Click(tObject *Sender) // Вращать барабан
- •Void __fastcall tForm1::Button6Click(tObject *Sender) //кн. «Подтвердите»
- •Void __fastcall tForm2::Button1Click(tObject *Sender) //кн. «Подтвердите»
- •Void __fastcall tForm3::Button1Click(tObject *Sender) // кн. «Сохранить»
- •Void cPerevozkaPredmetovDlg::OnButton2() //кнопка «Очистить»
- •Void cPerevozkaPredmetovDlg::OnButton3() //кнопка «Перевезти»
- •8.2. Задачи для программирования
- •8.2.1. Числовые типы, оператор присваивания
- •8.2.2. Алгоритмы линейной структуры
- •8.2.3. Алгоритмы разветвляющей структуры
- •8.2.3. Алгоритмы циклической структуры
- •8.2.5. Алгоритмы работы с рядами
- •8.2.6. Алгоритмы работы с массивами
- •8.2.7. Обработка символьных данных
- •8.2.8. Организация подпрограмм
- •8.2.9. Работа с файлами
- •8.2.10. Работа с формами и диаграммами
- •8.2.11. Контрольные работы
- •1. Учет семейного бюджета.
- •28. Учет успеваемости студентов.
- •3. Работа с базами данных
- •П р и л о ж е н и е 2. Вопросы для экзаменационных билетов
- •Тематический указатель
- •Библиографический список
- •Учебное издание
4.10.5. Связь с сервером приложений по протоколуHttp
ТехнологииDCOMиTCP/IPтребуют установки прямой связи между клиентом и сервером, что в перегруженных сетях может вызвать большие задержки в установке такой связи. В таких случаях лучше использовать компонентWebConnectionс панелиMidas, который организует связь с сервером по протоколу передачи гипертекстаHTTPв Интернете со средствами защиты данных. При отсутствии реальногоWeb‑сервера можно создать для отладки собственныйWeb‑сервер на локальном компьютере. Для этого нужно присвоить уникальное сетевое имя компьютеру:
Выполним команду Пуск/Настройка/Панель управления/Сеть.
На странице Конфигурациявыберем протоколTCP/IP и нажмем кнопкуСвойства.
На странице Конфигурация DNSустановим флажокВключить DNS. В полеИмя компьютераустановим, например,MyHost, а в полеДомен‑MyDomain.ru. Перегрузим компьютер.
Изменим в клиентском приложении (п. 4.10.2) установку связи с сервером по протоколу DCOMна протоколHTTP.
Разместим компонент WebConnection. В свойствеServerGUIDэтого компонента указывается идентификационный номерGUIDсервера приложений (п. 4.10.1). Скопируем его одноименное свойство компонентаDCOMConnection1через буфер, предварительно указав для него свойствоConnected=False. После этого свойствуServerNameприсвоится имя сервераProject1.IStroiki.
Запустим Web‑сервер, если он еще не запущен. Скопируем библиотекуDelphi5\Bin\httpsrvr.dll в виртуальный каталогWeb‑сервера, допускающий вызов серверных приложений, например:Cgi-Bin. В свойствеURLкомпонентаWebConnection1 укажем полный адрес этой библиотеки, например,http://myhost/cgi-bin/httpsrvr.dllиConnected=True. Произойдет запуск сервера приложений.
Для компонента ClientDataSet1установим свойстваRemoteServer=WebConnection1 иActive=Trueи выполним клиентское приложение.
4.10.6. Основы разработки приложений Internet
Предполагается, что пользователь имеет базовые понятия об языке разметки гипертекстa HTML [8] (этот пункт подготовлен А. Кочетовым).
Протокол HTTP, язык HTML и универсальный локатор ресурса URL составляют основу WWW[4]. HTTP (HyperText Transfer Protocol) - протокол передачи гипертекста, основанный на идее «ссылки», реализованной в универсальном идентификаторе ресурса (URL) и универсальном имени ресурса (URN). Второй основной частью протокола HTTP является идея запроса-ответа.
Динамически формируемые Web‑документы создаются сервером в процессе обработки клиентского запроса. Серверные программы, выполняющие эту функцию, подразделяются на два типа: Web-сервер может вызывать исполняемую программу или поручить это дело вызываемой процедуре из библиотеки динамической загрузки (DLL). Delphi поддерживает все четыре интерфейса приложений, выполняемых на сервере и позволяющих создавать динамические документы HTML: ISAPI и NSAPI (использует .DLL), CGI и Win-CGI (использует .EXE). Исходный текст для всех интерфейсов может быть один. Различия лишь при создании «проекта», т.е. имея исходный код приложения CGI, вы можете получить приложение интерфейса ISAPI, лишь создав таковое (File/New/Web Server application/ISAPI) и перенеся код. Никаких изменений не требуется.
Примерсоздания Web-приложения типа CGI вывода текущего времени (рис. 4.10.6.1):
Рис. 4.10.6.1. Окно приложения
1. Выберите пункт меню File/New/Web Server application/CGI. Мастер создаст для вас приложение иWebModule, который является потомкомTDataModuleи наследует его свойства, и если вы имели проект по работе с базами данных с использованиемTDataModule, то вы можете произвести публикацию данных в Internet, лишь добавив вDataModuleкомпонентWebDispatcher. Он же и встроен вTWebModule.
2. Дважды щелкните в Инспекторе Объектов на свойстве Actions. Добавьте новую строку в таблицу действий кнопкойAdd New.
3. Дважды щелкните на событии OnAction. Отредактируйте текст обработчика так, как он представлен ниже:
Procedure TWebModule1WebActionItem1Action(Sender:TObject;
Request:TwebRequest; Response:TwebResponse; var Handled:Boolean);
Begin
{ Sender - определяет вызвавший его объект.
Request - содержит запрос пользователя.
Response - содержит ответ сервера.
Handled - флаг, определяющий обработано или нет событие.
}
Response.Content:=’<HTML> <H1> Пример приложения CGI</H1>’+
‘<B> Текущее время: ‘+ TimeToStr(SysUtils.Time) +’</B></HTML>’;
End;
4. Сохраните проект и откомпилируйте (^F9).
5. Поместите EXE-файл приложения в «исполняемый каталог» вашего Web-сервера (Wins2000)
6. Выполните EXE-файл приложения, указав его имя в поле Адреспроводника Интернета.
Одна из популярных задач Internet ‑ это получение каких-либо данных от клиента, обработка на сервере и отправка клиенту документа-ответа. В HTML-документах это обычно решается при помощи формы. Сервер обрабатывает события OnAction, которые, в свою очередь, получают два параметра-объектаResponse иRequest. Если форма использует методPost,то данные помещаются в свойствоContentFields. Если в запросе применяется методGet, то данные запроса будут находиться в свойствеQueryFields.
Рассмотрим общую структуру приложения Web-сервера. Когда приложение получает от Web-клиента запрос, оно создает объекты TwebRequestиTWebResponseдля размещения в них HTTP-запроса и ответа сервера соответственно. Затем эти объекты передаются диспетчеру Web, встроенному в Web-модуль или компонентуTWebDispatcher. Диспетчер поддерживает набор объектов-действий классовTwebActionItem, каждый из которых выполняет обработку различных видов запросов. Этот класс имеет свойствоMethodType, предоставляющее различные варианты обработки запроса:mtGet, mtHead, mtPost, mtPut, mtAny. Запрос считается обработанным, если возвращается значениеtrueчерез параметрHandled; также возможна обработка событийBeforeDispatch, AfterDispatch.
На инструментальной панели Internet имеется три компонента, предназначенные для работы с базами данных в приложениях для Web-серверов:
TqueryTableProducer ‑используется для представления в виде HTML-таблицы результата SQL-запроса к базе данных. Этот объект может получать параметры SQL-запроса из HTTP-запроса. Если запрос использует методPost,то параметры запроса по SQL помещаются в свойствоContentFields. Если в запросе применяется методGet, то данные запроса будут находиться в свойствеQueryFields.
TdataSetTableProducer ‑ занимается аналогичным делом, но используя объектTDataSet.
TdataSetPageProducer ‑ заменяет шаблоны в заготовке HTML-документа на значения соответствующих полей базы данных. При этом используются значения полей текущей записи базы данных.
Пример создания Web-приложения просмотра таблицы базы данных (рис. 4.10.6.2):
Рис. 4.10.6.2. Окно просмотра таблицы базы данных
1. Создадим для базы данных алиас средствами Администратора BDE непосредственно на сервере.
2. Создадим новое Web-приложение.
3. Поместим в модуль компонент TTable и подключим его к заранее созданной таблице базы данных (установим свойстваDatabaseиTableNameсоответствующие значения). В свойствеDatabase укажем алиас БД или ее полный путь, а вTableName соответственно имя таблицы.
Добавим на форму компонент TDataSetTableProducer.
Создадим объект-действие со свойствами PathInfo=’’,Enabled=true.
Редактором столбцов компонента TDataSettableProducer проведем настройку оформления таблицы, заголовков (рис. 4.10.6.3). Изменения видны непосредственно в этом же редакторе.
Рис. 4.10.6.3. Окно редактора столбцов таблицы базы данных
7. Свяжем объекты DataSetTableProducer1 и Table1. Для этого укажем имяTable1в свойствеDataSetпоставщика данных. В свойствахFooterиHeaderзадаются необходимые заголовочные и заключительные теги, чтобы получить корректный HTML-документ, понятный броузеру Web. В нашем случае можно использовать следующий фрагмент:
Для Header:
<!DOCTYPEHTMLPUBLIC«-//W3C//DTDHTML3.2//EN»>
<HTML> <HEAD><TITLE> Пример 2 </TITLE> </HEAD> <BODY>
Для Footer:
</BODY> </HTML>
8. Затем щелкнем на свойстве Columns. Отбираем нужные поля для вывода в таблицу. Кроме этого можно дать имена для выводимых колонок и настроить цвет и обрамление. Заметим, что компонентTqueryTableProducerработает и настраивается аналогично.
9. Введем следующий код в обработчик созданного ранее события:
procedure TwebModule1WebActionItem1Action(Sender:TObject;
Request:TwebRequest; Response:TwebResponse; var Handled:Boolean);
Begin
Response.Content:=DataSetTableProducer1.Content;
{Содержимому ответа сервера присваивается содержимое компонента типа TDataSetTableProducer}
Response.SendResponse; //отправляет ответ пользователю
End;
В этом примере клиент может отправить запрос к базе данных на наш сервер и получить всю информацию базы данных в окне броузера.
Однако наше приложение посылает всегда одно и то же и никакого диалога с пользователем не ведет. Это можно исправить, используя публикацию данных в стиле навигатора: пользователь сможет перемещаться по таблице, используя ссылки «вперед», «назад» и т.д. Все это и многое другое мы можем реализовать при помощи компонента TdataSetPageProducer. Этот компонент работает с компонентамиTDataSet и имеет свойствоHTMLDoc форматаTstrings. Он заполняется текстом вашего документа, а также шаблонами (<#шаблон>), которые, если и имеют одинаковые имена с полями таблицы/запроса, указанные в свойствеDataSet, то они заменяются на значение соответствующего поля текущей записи источника данных или чем-либо иным при условии, что вы это запрограммировали в обработчике событияOnHTMLTag.
Примерсоздания Web-приложения типа CGI просмотра таблицы базы данных (рис. 4.10.6.4):
Рис. 4.10.6.4. Окно просмотра таблицы базы данных
1. Помещаем в WebModuleобъектTTable.
2. Создадим объекты-действия с именем first, next, previousи с соответствующими значениямиPathInfoи свойствомEnabled=true, также объект-действиеinitial с пустым значениемPathInfo.
3. Свяжем объекты DataSetPageProducer1 и Table1. Для этого укажем свойствоDataSet=Table1.
4. Теперь сформируем вышеупомянутое свойство HTMLDoc.
<HTML>
<BODY>
<TABLE WIDTH="50%" BORDER=1 BGCOLOR="SILVER">
<TR><TH ALIGN="RIGHT">Код</TH><TH ALIGN="LEFT"><#KOD>
<TR><TH ALIGN="RIGHT">Наименование</TH>
<TH ALIGN="LEFT"><#NAIM>
<TR><TD ALIGN="CENTER">
<A href= "http://wins2000.usue.ru\pleshev\ваше приложение\first">
первая </A> </TD>
<TD><#CCC>предыдущая</A> </TD>
<TD><#BBB>следующая</A> </TD></TR>
</TABLE>
</BODY>
</HTML>
Шаблоны <#CCC> и <#BBB> используются, чтобы динамически указать ссылку на приложение с указанием пути и информации о текущей записи отображаемой базы данных.
5. Далее для объектов initialиfirst создаем обработчик:
procedure TWebModule1.WebModule1firstAction (Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
Begin Table1.First; //переходит на первую запись таблицы,
//соответствующей компоненту Table1
Response.Content:=DataSetPageProducer1.Content;
Response.SendResponse; //отправляется ответ сервера
end;
procedure TWebModule1.WebModule1initialAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
Begin
Table1.First;
Response.Content:=DataSetPageProducer1.Content;
Response.SendResponse;
end;
6. С объектом first, конечно, все понятно. Но как быть сnext и previous? Необходимо дать знать серверу значение текущего поля. Тут‑то мы и используем событие OnHTMLTag и шаблоны. Обратите внимание на шаблоны, определенные в свойстве HTMLDoc <#BBB> и <#CCC>. Они‑то нам и понадобятся. Добавим обработчик события OnHTMLTag (будем считать, что поле KOD является первичным ключом):
procedure TWebModule1.DataSetPageProducer1HTMLTag(Sender: TObject;
Tag: TTag; const TagString: String; TagParams: TStrings;
var ReplaceText: String);
{ Обработчик содержит 4 параметра, определяющие текущий HTML тег.
TagString типа string содержит строковое представление тега. ReplaceText
также типа string используется при замене тега динамически}
var s:string; //строка содержащая текущее значение поля KOD
begin
s:=IntToStr(Table1.FieldValues['KOD']);
if CompareText(TagString,'BBB')=0 then
Replacetext:='<a href="http://wins2000.usue.ru\pleshev\’+
‘ваше приложение\next?KOD='+s+'">'; //ссылка на ваше приложение с
//информацией о текущей записи
else if CompareText(TagString,'BBB')=0 then
Replacetext:='<a href="http://wins2000.usue.ru\pleshev\’+
‘ваше приложение\previous?KOD='+s+'">'; //ссылка на ваше
//приложение c информацией о текущей записи
end;
7. Теперь приложение формирует законченный HTML документ, и осталось лишь добавить обработчики для next, previous:
procedure TWebModule1.WebModule1nextAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var q1:string; opt:TLocateOptions;
begin
q1:=Request.QueryFields.Values['KOD'];
Table1.Locate('KOD',q1,opt);
Table1.Next; //переход на следующую запись
Response.Content:=DataSetPageProducer1.Content;
Response.SendResponse;
end;
procedure TWebModule1.WebModule1previousAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var q1:string; opt:TLocateOptions;
begin
q1:=Request.QueryFields.Values['KOD'];
Table1.Locate('KOD',q1,opt);
Table1.Prior; // переход на предыдущую запись
Response.Content:=DataSetPageProducer1.Content;
Response.SendResponse;
end;
Теперь мы имеем законченное CGI приложение публикации данных в форме навигатора.
ВDelphi имеется компонент Web-броузер (TWebBrowser). Работа с ним интуитивна и вполне доступна пользователю Delphi.
Примерсоздания собственного Web‑броузера компонентомTwebBrowser(рис. 4.10.6.4):
1. Создаем обычное приложение Delphi.
2. Помещаем на форму компоненты TEdit, TStatusBar, TWebBrowser.
3. Введем следующий код в обработчик события Edit1.OnKeyDown:
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
Begin
if Key=13 then WebBrowser1.Navigate(Edit1.Text); //клавиша Enter
end;
Рис. 4.10.6.5. Окно Web‑броузера
4. Добавим Panel кнопкой с троеточием в свойствеPanels и затем кнопкойAdd New. ДляStatusbar1 укажемWidth=150 иText=‘Status: ‘.
5. Добавим следующий код в обработчик события WebBrowser1.OnTitleChange:
procedure TForm1.WebBrowser1TitleChange(Sender: TObject;
const Text: WideString);
begin
Form1.Caption:='Пример Web Browser''р ['+Text+']';
end;
6. Добавим следующий код в обработчик события WebBrowser1.OnProgressChange:
procedure TForm1.WebBrowser1ProgressChange(Sender: TObject; Progress, ProgressMax: Integer);
begin
if ProgressMax<>0 then
StatusBar1.Panels.Items[0].Text:='Status:'+
IntToStr(Progress*100 div ProgressMax)+'%'
else StatusBar1.Panels.Items[0].Text:='Status: Готово';
end;
7.Теперь осталось откомпилировать, и получим Web‑броузер.