ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



 

Часть 14

ННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН
ЦДДДДДДДї          Авторский коллектив "*.*"
є  ХНН» і                   ЦДї                         ЦДї
є  і  є і                   є і                         є і
є  АДДј Аї ЦДДДДДї ЦДДДДДї  є і   ЦДДДДДї  ЦДДї ЦДї ЦДДДЅ і
є  ХНН»  і є ХН» і є ХН» і  є і   є ХН» і  є  Аїє і є ХН» і
є  і  є  і є і є і є АДј µ  є і   є АДј і  є Х»АЅ і є і є і
є  АДДј  і є АДј і є ХН» Аї є Аї ЦЅ ХН» і  є іИ»  і є АДј і
ИННННННННѕ ИНННННѕ ИНѕ ИННѕ ИННѕ ИННѕ ИНѕ  ИНѕ ИННѕ ИНННННЩ
                 РЕЗИДЕНТНАЯ ПРОГРАММА-СПРАВОЧНИК
ЦДДДДДДДДДДї          ПО  ObjectWindows +
є  ХНННН»  і
є  і    є  і ЦДДДДДїЦДДДДДїЦДї ЦДДї  ЦДДДДДї ЦДДДДДїЦДї
є  і    є  і є ХН» іє ХНННѕє АДЅ Хѕ  є ХН» і є ХН» іє АДДДї
є  і    є  і є АДЅ іє і    є ХН» Аї  є АДЅ і є і є іє ХНН»і
є  і    є  іЙј ХН» іє АДДДїє і И» АїЙј ХН» іЙј і є іє АДДЅі
ИННѕ    ИННѕИННѕ ИНѕИНННННѕИНѕ  ИННѕИННѕ ИНѕИННѕ ИНѕИНННННѕ
               г.Москва, 1993 г.           (ВЕРСИЯ 7)
ННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН

                 Оглавление

Введение..................................................
Что такое ObjectWindows?..................................
Для чего предназначена ObjectWindows?.....................
Что нужно знать...........................................
Как работать с данным руководством........................
О чем рассказывается в данном руководстве.................
Часть 1. Изучение ObjectWindows...........................
Глава 1. Знакомство с Windows.............................
Шаг 1: Создание базового приложения.......................
Требования к приложению...................................
Определение типа приложения...............................
Инициализация основного окна..............................
Объект основного окна.....................................
Что такое объект окна?....................................
Описатели.................................................
Порождающие и дочерние окна...............................
Создание нового типа окна.................................
Реакция на сообщения......................................
Завершение прикладной программы...........................
Переопределение CanClose..................................
Дальнейшее изменение закрытия.............................
Глава 2. Заполнение окна..................................
Шаг 2: Отображение текста в окне..........................
Вывод в контексте дисплея.................................
Что такое контекст дисплея?...............................
Получение контекста дисплея...............................
Использование контекста дисплея...........................
Освобождение контекста дисплея............................
Координаты Windows........................................
Параметры сообщений.......................................
Очистка окна..............................................
Шаг 3: Изображение линий в окне...........................
Буксировка линии..........................................
Сообщения wm_MouseMove....................................
Реакция на сообщения буксировки...........................
Изображение точек и линий.................................
Перехват "мыши"...........................................
Изменение размера пера....................................
Отслеживание размера пера.................................
Получение пера нового размера.............................
Глава 3. Меню и диалоговые ресурсы........................
Шаг 4: Добавление строки меню.............................
Ресурсы меню..............................................
Загрузка ресурса меню.....................................
Перехват сообщений меню...................................
Определение методов реакции на команду....................
Связывание клавиш с командами.............................
Реакция на команды меню...................................
Добавление диалогового блока..............................
Добавление поля объекта...................................
Шаг 5: Добавление диалогового блока.......................
Создание ресурсов диалогового блока.......................
Идентификаторы управляющих элементов......................
Построение объекта диалогового блока......................
Выполнение диалогового блока..............................
Режимные и безрежимные диалоговые блоки...................
Глава 4. Работа с диалоговым блоком.......................
Шаг 6: Изменение атрибутов пера...........................
Создание объекта пера.....................................
Создание сложного диалогового блока.......................
Управляющие объекты.......................................
Использование интерфейсных объектов.......................
Конструктор InitResource..................................
Создание буфера передачи..................................
Передача данных...........................................
Чтение возвращаемых значений..............................
Вызов диалогового блока пера..............................
Глава 5. Повторное отображение графики....................
Шаг 7: Вывод на экран графики.............................
Изображение и рисование...................................
Сохранение графики в объектах.............................
Добавление поля объекта...................................
Определение объекта линии.................................
Изменение методов работы с "мышью"........................
Вывод сохраненной графики.................................
Шаг 8: Сохранение рисунка в файле.........................
Отслеживание состояния....................................
Сохранение и загрузка файлов..............................
Шаг 9: Печать графического образа.........................
Построение объекта принтера...............................
Создание объекта распечатки...............................
Запись в контекст устройства..............................
Создание распечатки окна..................................
Вывод распечатки..........................................
Выбор другого принтера....................................
Глава 6. Вывод всплывающего окна..........................
Шаг 10: Добавление всплывающего окна......................
Добавление к окну дочернего окна..........................
Построение окна палитры...................................
Назначение порождающего окна..............................
Создание элементов экрана.................................
Вывод и сокрытие палитры..................................
Шаг 11: добавление специализированных управляющих элементо
Добавление к палитре командных кнопок.....................
Объекты управляющих элементов как поля....................
Работа с управляющими элементами..........................
Сокрытие вместо закрытия..................................
Разрешение специализированных управляющих элементов.......
Создание для командных кнопок графических изображений.....
Нумерация ресурсов графических изображений................
Шаг 12: Создание специализированного управляющего элемента
 окна.....................................................
Динамическое изменение размеров палитры...................
Реакция на события управляющих элементов..................
Имена методов реакции на сообщения управляющих элементов..
Добавление "кнопок" палитры...............................
Определение объекта палитры...............................
Создание и уничтожение палитры............................
Размещение в порождающем окне.............................
Добавление и удаление перьев..............................
Отображение содержимого палитры...........................
Выбор перьев с помощью "мыши".............................
Что дальше?...............................................
Многодокументальный интерфейс.............................
Сглаживание линий.........................................
Отмена....................................................
Поведение палитры.........................................
Прокрутка.................................................
Часть 2. Использование ObjectWindows......................
Глава 7. Иерархия ObjectWindows...........................
Соглашения Windows........................................
Имена объектов............................................
Имена методов.............................................
Обзор объектов............................................
Иерархия объектов.........................................
Файлы ObjectWindows.......................................
Файлы ресурсов............................................
Файлы Windows 3.1.........................................
Взаимодействие с Windows..................................
Функции API Windows.......................................
Вызов в ObjectWindows функций API.........................
Доступ к функциям API.....................................
Константы Windows.........................................
Записи данных Windows.....................................
Комбинирование констант стилей............................
Типы функций Windows......................................
Функции системного вызова.................................
Глава 8. Объекты приложения...............................
Минимальные требования....................................
Поиск объекта приложения..................................
Минимальное приложение....................................
Методы Init, Run и Done...................................
Конструктор Init..........................................
Метод Run.................................................
Деструктор Done...........................................
Инициализация приложения..................................
Инициализация основного окна..............................
Специальный вывод основного окна..........................
Инициализация первого экземпляра..........................
Инициализация каждого экземпляра..........................
Выполнение приложений.....................................
Закрытие приложений.......................................
Модификация поведения при закрытии........................
Глава 9. Интерфейсные объекты.............................
Для чего нужны интерфейсные объекты?......................
Что делают интерфейсные объекты?..........................
Общий интерфейсный объект.................................
Создание интерфейсных объектов............................
Допустимость описателя окна...............................
Видимость на экране.......................................
Уничтожение интерфейсных объектов.........................
Связь порождающего и дочернего объектов...................
Список дочерних окон......................................
Построение дочерних окон..................................
Создание дочерних элементов экрана........................
Уничтожение дочерних окон.................................
Запрещение автоматического создания.......................
Итерация дочерних окон....................................
Поиск определенного дочернего окна........................
Глава 10. Объекты окон....................................
Что такое объекты окон?...................................
Окна, которые не являются окнами..........................
Где найти объекты окон....................................
Инициализация объектов окон...............................
Установка атрибутов создания..............................
Используемые по умолчанию атрибуты окна...................
Переопределение используемых по умолчанию атрибутов.......
Атрибуты порожденного окна................................
Создание элементов окна...................................
Задание атрибутов регистрации.............................
Классы окон...............................................
Используемые по умолчанию атрибуты регистрации............
Регистрация нового класса.................................
Изменение имени класса....................................
Определение новых атрибутов регистрации...................
Использование специализированных окон.....................
Использование окон редактирования.........................
Использование файловых окон...............................
Прокрутка содержимого окон................................
Что такое объект прокрутки?...............................
Задание для окна объекта прокрутки........................
Пример прокрутки..........................................
Запрещение автоматической прокрутки.......................
Отслеживание полос прокрутки..............................
Модификация единиц прокрутки и диапазона..................
Изменение позиции прокрутки...............................
Установка размеров страницы...............................
Оптимизация методов Paint для прокрутки...................
Глава 11. Объекты диалоговых блоков.......................
Использование объектов диалоговых блоков..................
Построение объекта........................................
Вызов конструктора........................................
Выполнение диалоговых блоков..............................
Режимные и безрежимные диалоговые блоки...................
Выполнения режимных диалоговых блоков.....................
Выполнение безрежимных диалоговых блоков..................
Работа с безрежимными диалоговыми блоками.................
Завершение диалогов.......................................
Работа с управляющими элементами..........................
Взаимодействие с управляющим элементом....................
Реакция на сообщения управляющих элементов................
Пример связи..............................................
Ассоциирование объектов управляющих элементов.............
Использование диалоговых окон.............................
Использование предопределенных диалоговых окон............
Использование диалоговых блоков ввода.....................
Файловые диалоговые блоки.................................
Инициализация файлового диалогового блока.................
Выполнение файловых диалоговых блоков.....................
Глава 12. Объекты управляющих элементов...................
Где можно использовать объекты управляющих элементов?.....
Что такое объекты управляющих элементов?..................
Построение и уничтожение объектов управляющих элементов...
Построение объекта управляющего элемента..................
Вызов конструкторов объектов управляющих элементов........
Присваивание полям объекта................................
Изменение атрибутов объекта управляющего элемента.........
Инициализация управляющего элемента.......................
Сохранение управляющих элементов..........................
Уничтожение управляющих элементов.........................
Связь с управляющими элементами...........................
Работа с управляющими элементами окна.....................
Реакция на управляющие элементы...........................
Действие, аналогичное диалоговому блоку...................
Использование конкретных управляющих элементов............
Использование блока списка................................
Построение объектов блока списка..........................
Модификация блоков списка.................................
Запрос в блоках списка....................................
Реакция на блок списка....................................
Пример программы: LBoxTest................................
Использование статических управляющих элементов...........
Построение статических управляющих элементов..............
Пример программы StatTest.................................
Использование командных кнопок............................
Построение командных кнопок...............................
Реакция на командные кнопки...............................
Использование блоков выбора...............................
Построение кнопок с зависимой и независимой фиксацией.....
Модификация блоков выбора.................................
Опрос блоков выбора.......................................
Использование групповых блоков............................
Построение групповых блоков...............................
Группирование управляющих элементов.......................
Реакция на групповые блоки................................
Пример программы: BtnTest.................................
Использование полос прокрутки.............................
Построение полос прокрутки................................
Управление диапазоном полосы прокрутки....................
Управление параметрами полосы прокрутки...................
Опрос полосы прокрутки....................................
Модификация полос прокрутки...............................
Реакция на полосы прокрутки...............................
Пример программы: SBarTest................................
Использование управляющих элементов редактирования........
Построение управляющих элементов редактирования...........
Использование буфера вырезанного изображения и меню Edit..
Опрос управляющих элементов редактирования................
Модификация управляющих элементов редактирования..........
Пример программы: EditTest................................
Использование комбинированных блоков......................
Три типа комбинированных блоков...........................
Выбор типа комбинированного блока.........................
Построение комбинированных блоков.........................
Модификация комбинированных блоков........................
Пример программы: CBoxTest................................
Установка значений управляющих элементов..................
Для чего используется буфер передачи?.....................
Определение буфера передачи...............................
Определение окна..........................................
Использование буфера передачи с диалоговым блоком.........
Использование буфера передачи с окном.....................
Передача данных...........................................
Передача данных в окно....................................
Передача данных из диалогового окна.......................
Передача данных из окна...................................
Поддержка передачи для специализированных управляющих
 элементов................................................
Пример программы: TranTest................................
Использование специализированных управляющих элементов....
Специализированные управляющие элементы Borland для Window
Использование стандартных BWCC............................
Средства BWCC.............................................
Расширение BWCC...........................................
Создание ваших собственных специализированных управляющих
 элементов................................................
Глава 13. Проверка допустимости данных....................
Три вида проверки допустимости данных.....................
Фильтрация ввода..........................................
Проверка допустимости каждого поля........................
Проверка допустимости полных экранов......................
Использование механизма проверки допустимости данных......
Построение объектов проверки допустимости.................
Добавление к управляющим элементам........................
Как работает проверка допустимости........................
Методы объекта проверки допустимости......................
Проверка допустимости данных..............................
Проверка полной строки....................................
Проверка допустимости нажатий клавиш......................
Сообщение о недопустимых данных...........................
Стандартные средства проверки допустимости................
Абстрактный объект проверки допустимости..................
Фильтрация................................................
Проверка диапазона........................................
Проверка допустимости с просмотром........................
Просмотр строк............................................
Проверка допустимости по шаблону..........................
Глава 14. Объекты MDI.....................................
Меню дочернего окна.......................................
Дочерние окна MDI.........................................
Окна MDI в ObjectWindows..................................
Построение приложения MDI.................................
Построение рамки MDI......................................
Создание меню дочерних окон...............................
Создание дочерних окон MDI................................
Автоматические дочерние окна..............................
Управление дочерним окном MDI.............................
Настройка активизации дочернего окна......................
Обработка сообщений в приложении MDI......................
Пример приложения MDI.....................................
Глава 15. Объекты печати..................................
Почему печать представляет трудности?.....................
Печать в ObjectWindows....................................
Построение объекта принтера...............................
Создание распечатки.......................................
Печать документа..........................................
Задание параметров печати.................................
Подсчет страниц...........................................
Печать каждой страницы....................................
Указание оставшихся страниц...............................
Другие соглашения по печати...............................
Печать содержимое окна....................................
Вывод распечатки на принтер...............................
Выбор другого принтера....................................
Выбор принтера пользователем..............................
Назначение конкретного принтера...........................
Часть 3. Продвинутое программирование с использование
 ObjectWindows............................................
Глава 16. Сообщения Windows...............................
Что такое сообщение?......................................
Именующие сообщения.......................................
Откуда поступают сообщения................................
Обычная диспетчеризация сообщений.........................
Способ, предлагаемый ObjectWindows........................
Динамические виртуальные методы...........................
Написание методов реакции на сообщение....................
Что такое сообщение?......................................
Поля параметров...........................................
Поле Result...............................................
Объектно-ориентированная обработка сообщения..............
Отмена поведения по умолчанию.............................
Замена поведения по умолчанию.............................
Дополнение поведения по умолчанию.........................
Вызов наследуемых методов.................................
Вызов процедур, используемых по умолчанию.................
Командные, уведомляющие и управляющие идентификаторы......
Командные сообщения.......................................
Уведомляющие сообщения....................................
Уведомления управляющих элементов.........................
Уведомление порождающего объекта..........................
Уведомления управляющих элементов и порождающих объектов..
Определение ваших собственных сообщений...................
Передача сообщений........................................
Передача и отправление сообщений..........................
Передача сообщения........................................
Отправление сообщения.....................................
Передача сообщения управляющему элементу..................
Диапазоны сообщений.......................................
Глава 17. Интерфейс с графическими устройствами...........
Запись на устройство вывода...............................
Чем отличаются контексты устройства?......................
Управление контекстом дисплея.............................
Работа с контекстом дисплея...............................
Что содержится в контексте устройства?....................
Побитовая графика.........................................
Изобразительные средства..................................
Цвет......................................................
Режимы отображения........................................
Обрезание областей........................................
Инструментальные средства рисования.......................
Основные инструментальные средства........................
Логические инструментальные средства......................
Логические перья..........................................
Логические кисти..........................................
Логические шрифты.........................................
Использование изобразительных инструментальных средств....
Отображение графики в окнах...............................
Изображение окон..........................................
Стратегия графики.........................................
Рисование в окнах.........................................
Графические функции GDI...................................
Функции изображения текста................................
Функции рисования линий...................................
Изображение фигур.........................................
Использование палитр......................................
Установка палитры.........................................
Рисование с палитрами.....................................
Запрос палитры............................................
Модификация палитры.......................................
Реакция на изменения палитры..............................
Глава 18. Более подробно о ресурсах.......................
Создание ресурсов.........................................
Добавление ресурсов к выполняемой программе...............
Загрузка ресурсов в приложение............................
Загрузка меню.............................................
Загрузка оперативных клавиш...............................
Загрузка блоков диалога...................................
Загрузка курсоров и пиктограмм............................
Загрузка строковых ресурсов...............................
Загрузка графических изображений..........................
Использование побитовых отображений для создания кистей...
Отображение графических изображений в меню................
Глава 19. Наборы..........................................
Объекты наборов...........................................
Динамическая установка размеров наборов...................
Полиморфизм наборов.......................................
Проверка типа и наборы....................................
Объединение в набор элементов, не являющихся объектами....
Создание набора...........................................
Методы итератора..........................................
Итератор ForEach..........................................
Итераторы FirstThat и LastThat............................
Отсортированные наборы....................................
Наборы строк..............................................
Пересмотренные итераторы..................................
Полиморфические наборы....................................
Наборы и управление памятью...............................
Глава 20. Потоки..........................................
Вопрос: объектный ввод-вывод..............................
Ответ: потоки.............................................
Полиморфизм потоков.......................................
Потоки обрабатывают объекты...............................
Смысл использования потоков...............................
Чтение из потока и запись в поток.........................
Закрытие потока...........................................
Как сделать объекты потоковыми............................
Методы загрузки и хранения................................
Регистрация потока........................................
Номера идентификаторов объектов...........................
Автоматические поля.......................................
Регистрация на месте......................................
Регистрация стандартных объектов..........................
Механизм потока...........................................
Процесс Put...............................................
Процесс Get...............................................
Обработка указателей объектов со значением nil............
Наборы в потоке: пример...................................
Добавление методов Store..................................
Регистрация записей.......................................
Регистрация...............................................
Запись в поток............................................
Как все хранится?.........................................
Поля в потоке.............................................
Родство экземпляров окон..................................
Копирование потока........................................
Потоки произвольного доступа..............................
Необъектные элементы потоков..............................
Разработка пользователем собственных потоков..............
Обработка ошибок потока...................................
Часть 4. Справочник по ObjectWindows......................
Глава 21. Объектные типы ObjectWindows....................
TSample                                            модуль
 TSample..................................................
Поля......................................................
Методы....................................................
Init......................................................
Zilch (иногда переопределяется)...........................
Процедура Sample                                  (модуль
 Sample)..................................................
Процедура Abstract                                 модуль
 Objects..................................................
Функция AllocMultiSel                             модуль
 ODialogs.................................................
Переменная Application                            модуль
 OWindows.................................................
Константы bf_XXXX                                 модуль
 ODialogs.................................................
Стили кнопок bs_XXXX                              модуль
 WinTypes.................................................
Переменная BWCCClassNames                         модуль
 OWindows.................................................
Стили комбинированного блока cbs_XXXX             модуль
 WinTypes.................................................
Константы cm_XXXX                                 модуль
 OWindows.................................................
Константы coXXXX                                   модуль
 Objects..................................................
Стили класса cs_XXXX                              модуль
 WinTypes.................................................
Константа cw_UseDefault                           модуль
 WinTypes.................................................
Процедура DoneMemory                               модуль
 OMemory..................................................
Константы em_XXXX                                 модуль
 OWindows.................................................
Переменная EmsCurHandle                            модуль
 Objects..................................................
Переменная EmsCurPage                              модуль
 Objects..................................................
Стили управляющих элементов es_XXXX               модуль
 WinTypes.................................................
Процедура FreeMultiSel                            модуль
 ODialogs.................................................
Константа tsFileSpec                              модуль
 OStdDlgs.................................................
Константы id_XXXX                                 модуль
 OWindows.................................................
Процедура InitMemory                               модуль
 OMemory..................................................
Стили блока списка lbs_XXXX                       модуль
 WinTypes.................................................
Функция LongDiv                                   модуль
 OWindows.................................................
Функция LongMul                                   модуль
 OWindows.................................................
Тип LongRec                                        модуль
 Objects..................................................
Функция LoMemory                                   модуль
 OMemory..................................................
Тип MakeIntResource                               модуль
 WinTypes.................................................
Переменная MaxCollectionSize                       модуль
 Objects..................................................
Флаги блоков mb_XXXX                              модуль
 WinTypes.................................................
Функция MemAlloc                                   модуль
 OMemory..................................................
Функция MemAllocSeg                                модуль
 OMemory..................................................
Константы nf_XXXX                                 модуль
 OWindows.................................................
Константы pf_XXX                                  модуль
 OPrinter.................................................
Тип PString                                        модуль
 Objects..................................................
Тип PtrRec                                         модуль
 Objects..................................................
Процедура RegisterODialogs                        модуль
 ODialogs.................................................
Процедура RegisterOStdWnds                        модуль
 OSrdWnds.................................................
Процедура RegisterOWindows                        модуль
 OWindows.................................................
Процедура RegisterType                             модуль
 Objects..................................................
Процедура RegisterValidate                        модуль
 Validate.................................................
Процедура RestoreMemory                            модуль
 OMemory..................................................
Переменная SafetyPoolSize                          модуль
 OMemory..................................................
Стили полосы прокрутки sbs_XXXX                   модуль
 WinTypes.................................................
Константы sd_XXXX                                 модуль
 OStdDlgs.................................................
Стили управляющего элемента ss_XXXX               модуль
 WinTypes.................................................
Пpедопpеделенные логические объекты               модуль
 WinTypes.................................................
Переменная StreamError                             модуль
 Objects..................................................
Константы stXXX                                    модуль
 Objects..................................................
Константы отображения окна sw_XXX                 модуль
 WinTypes.................................................
TApplication                                      модуль
 OWindows.................................................
Поля......................................................
Методы....................................................
Init (иногда переопределяется)............................
Done (иногда переопределяется)............................
CanClose (переопределяется редко).........................
Error (часто переопределяется)............................
ExecDialog (никогда не переопределяется)..................
ExecDialog (никогда не переопределяется)..................
IdleAction................................................
InitApplication (иногда переопределяется).................
InitInstance (иногда переопределяется)....................
InitMainWindow (всегда переопределяется)..................
MakeWindow (никогда не переопределяется)..................
MessageLooр (никогда не переопределяется).................
рrocessAccels (иногда переопределяется)...................
рrocessAppMsg (иногда переопределяется)...................
рrocessDlgMsg (иногда переопределяется)...................
рrocessDMIAccels (иногда переопределяется)................
Функция Run (переопределяется редко)......................
SetKBHandler (никогда не переопределяется)................
TBufStream                                         модуль
 Objects..................................................
Поля......................................................
Методы....................................................
Init......................................................
Done (никогда не переопределяется)........................
Flush (никогда не переопределяется).......................
Getрos (никогда не переопределяется)......................
GetSize (никогда не переопределяется).....................
Read (никогда не переопределяется)........................
Seek (никогда не переопределяется)........................
Truncate (никогда не переопределяется)....................
Write (никогда не переопределяется).......................
TButton                                           модуль
 ODialogs.................................................
Методы....................................................
Init......................................................
InitResource..............................................
GetClassName (никогда не переопределяется)................
Тип TByteArray                                     модуль
 Objects..................................................
TCheckBox                                         модуль
 ODialogs.................................................
Поля......................................................
Методы....................................................
Init (иногда переопределяется)............................
InitResource..............................................
Load......................................................
BNClicked (иногда переопределяется).......................
Check (переопределяется редко)............................
GetCheck (переопределяется редко).........................
GetClassName..............................................
SetCheck (переопределяется редко).........................
Store.....................................................
Toggle (переопределяется редко)...........................
Transfer (иногда переопределяется)........................
UnСheck (переопределяется редко)..........................
TCollection                                        модуль
 Objects..................................................
Поля......................................................
Методы....................................................
Init......................................................
Load......................................................
Done (часто переопределяется).............................
At........................................................
AtDelete..................................................
AtFree....................................................
AtInsert..................................................
Atрut.....................................................
Delete....................................................
DeleteAll.................................................
Error (иногда переопределяется)...........................
FirstThat.................................................
ForEach...................................................
Free......................................................
FreeAll...................................................
FreeItem (иногда переопределяется)........................
GetItem (иногда переопределяется).........................
IndexOf (никогда не переопределяется).....................
Insert (никогда не переопределяется)......................
Insert (никогда не переопределяется)......................
рutItem (иногда переопределяется).........................
SetLimit (переопределяется редко).........................
Store.....................................................
TComboBox                                         модуль
 ODialogs.................................................
Поля......................................................
Методы....................................................
Init (иногда переопределяется)............................
InitResource..............................................
Load......................................................
Clear.....................................................
GetClassName (никогда не переопределяется)................
GetEditSel................................................
GetText...................................................
GetTextLen................................................
HideList..................................................
SetEditSel................................................
SetText...................................................
SetuрWindow...............................................
ShowList..................................................
Store.....................................................
Transfer..................................................
TControl                                           модуль
 ODialogs.................................................
Методы....................................................
Init......................................................
InitResource..............................................
GetGlassName (всегда переопределяется)....................
Register (никогда не переопределяется)....................
WMрaint (переопределяется редко)..........................
TDialog                                            модуль
 ODialog..................................................
Поля......................................................
IsModal...................................................
Методы....................................................
Init (иногда переопеределяется)...........................
Load......................................................
Done (иногда переопределяется)............................
Cancel (иногда переопределяется)..........................
Create (никогда не переопределяется)......................
DefWndрroc (никогда не переопределяется)..................
EndDlg (никогда не переопределяется)......................
Execute (никогда не переопределяется).....................
GetItemHandle (никогда не переопределяется)...............
Ok (иногда переопределяется)..............................
SendDlgItemMsg (никогда не переопределяется)..............
Store.....................................................
WMClose...................................................
WMInitDialog (никогда не переопределяется)................
WMрostInvalid.............................................
WMQueryEndSession.........................................
Тип TDialogAttr                                   модуль
 ODialogs.................................................
TDlgWindow                                        модуль
 ODialogs.................................................
Методы....................................................
Init......................................................
Create (никогда не переопределяется)......................
GetWindowClass (часто переопределяется)...................
TDosStream                                         модуль
 Objects..................................................
Поля......................................................
Методы....................................................
Init......................................................
Done (никогда не переопределяется)........................
Getрos (никогда не переопределяется)......................
GetSize (никогда не переопределяется).....................
Read (никогда не переопределяется)........................
Seek (никогда не переопределяется)........................
Truncate (никогда не переопределяется)....................
Write (никогда не переопределяется).......................
TEdit                                             модуль
 ODialogs.................................................
Поля......................................................
Методы....................................................
Init......................................................
InitResource..............................................
Load......................................................
Done......................................................
CanClose..................................................
CanUndo (переопределяется редко)..........................
ClearModify (переопределяется редко)......................
CMEditClear (никогда не переопределяется).................
CMEditCoрy (никогда не переопределяется)..................
CMEditCut (никогда не переопределяется)...................
CMEditDelete (никогда не переопределяется)................
CMEditрaste (никогда не переопределяется).................
CMEditUndo (никогда не переопределяется)..................
Coрy (переопределяется редко).............................
Cut (переопределяется редко)..............................
DeleteLine (переопределяется редко).......................
DeleteSelection (переопределяется редко)..................
DeleteSubText (переопределяется редко)....................
GetClassName (никогда не переопределяется)................
GetLine (переопределяется редко)..........................
GetLineFromрos (переопределяется редко)...................
GetLineIndex (переопределяется редко).....................
GetLineLength (переопределяется редко)....................
GetNumLines (переопределяется редко)......................
GetSelection (переопределяется редко).....................
GetSubText (переопределяется редко).......................
Insert (переопределяется редко)...........................
IsModified (переопределяется редко).......................
IsValid...................................................
рaste (переопределяется редко)............................
Scroll (переопределяется редко)...........................
Search....................................................
SetSelection (переопределяется редко).....................
SetuрWindow...............................................
SetValidator..............................................
Store.....................................................
Transfer (иногда переопределяется)........................
Undo (переопределяется редко).............................
WMChar....................................................
WMGetDlgCode..............................................
WMKeyDown.................................................
WMKillFocus...............................................
TEditPrintout
 OPrinter.................................................
Поля......................................................
Методы....................................................
Init......................................................
BeginDocument.............................................
GetDialogInfo.............................................
HasHextPage...............................................
PrintPage.................................................
SetPrintParams............................................
TEditWindow                                       модуль
 OStdWnds.................................................
TEmsStream                                         модуль
 Objects..................................................
Поля......................................................
Методы....................................................
Init......................................................
Done (никогда не переопределяется)........................
GetPos (никогда не переопределяется)......................
GetSize (никогда не переопределяется).....................
Read (никогда не переопределяется)........................
Seek (никогда не переопределяется)........................
Truncate (никогда не переопределяется)....................
Write (никогда не переопределяется).......................
Константы tf_XXXX                                 модуль
 OWindows.................................................
TFileDialog                                       модуль
 OStdDlgs.................................................
Поля......................................................
Методы....................................................
Init......................................................
CanClose..................................................
SetupWindow...............................................
HandleFName...............................................
HandleFList...............................................
HandleDList...............................................
TFileWindow
 OStdWnds.................................................
TFilterValidator                                  модуль
 Validate.................................................
Поля......................................................
Методы....................................................
Init......................................................
Load......................................................
Error.....................................................
IsValid...................................................
IsValidInput..............................................
Store.....................................................
TGroupBox
 ODialogs.................................................
Поля......................................................
Методы....................................................
Init (иногда переопределяется)............................
InitResource..............................................
Load......................................................
GetClassName (иногда переопределяется)....................
SelectionChanged (иногда переопределяется)................
Store.....................................................
TInputDialog                                      модуль
 OStdDlgs.................................................
Поля......................................................
Методы....................................................
Init......................................................
CanClose..................................................
SetupWindow...............................................
Тип TItemList                                      модуль
 Objects..................................................
TListBox                                          модуль
 ODialogs.................................................
Методы....................................................
Init......................................................
AddString (иногда переопределяется).......................
ClearList (иногда переопределяется).......................
DeleteString (иногда переопределяется)....................
GetClassName (переопределяется редко).....................
GetCount (никогда не переопределяется)....................
GetMsgID..................................................
GetSelIndex (переопределяется редко)......................
GetSelString (переопределяется редко).....................
GetString (переопределяется редко)........................
GetStringLen (переопределяется редко).....................
InsertString (иногда переопределяется)....................
SetSelIndex (переопределяется редко)......................
SetSelString (переопределяется редко).....................
Transfer (иногда переопределяется)........................
TLookupValidator                                  модуль
 Validate.................................................
Методы....................................................
IsValid (переопределяется редко)..........................
Lookup (часто переопределяется)...........................
TMDIClient                                        модуль
 OWindows.................................................
Поля......................................................
Методы....................................................
Init (переопределяется редко).............................
Load......................................................
ArrangeIcons (переопределяется редко).....................
CascadeChildren (переопределяется редко)..................
GetClassName (никогда не переопределяется)................
Register..................................................
Store.....................................................
TileChildren (переопределяется редко).....................
WMPaint (никогда не переопределяется).....................
TMDIWindow                                        модуль
 OWindows.................................................
Поля......................................................
Методы....................................................
Init (часто переопределяется).............................
Load......................................................
Done (иногда переопределяется)............................
ArrangeIcons (переопределяется редко).....................
CascadeChildren (переопределяется редко)..................
CloseChildren (переопределяется редко)....................
CMArrangeIcons (переопределяется редко)...................
CMCascadeChildren (переопределяется редко)................
CMCreateChild (никогда не переопределяется)...............
CMTileChildren (переопределяется редко)...................
CreateChild...............................................
DefWndProc................................................
GetClassName (иногда переопределяется)....................
GetClient (никогда не переопределяется)...................
GetWindowClass (иногда переопределяется)..................
InitChild (часто переопределяется)........................
InitClientWindow (иногда переопределяется)................
SetupWindow (часто переопределяется)......................
Store.....................................................
TileChildren (переопределяется редко).....................
Тип TMessage                                      модуль
 OWindows.................................................
Тип TMultiSelRec                                  модуль
 ODialogs.................................................
TObject                                            модуль
 Objects..................................................
Методы....................................................
Init......................................................
Free......................................................
Done......................................................
Тип TPaintStruct                                  модуль
 WinTypes.................................................
Тип TPicResult                                    модуль
 Validate.................................................
TPrintDialog                                      модуль
 OPrinter.................................................
Поля......................................................
Методы....................................................
Init......................................................
Тип TPrintDialogRec                               модуль
 OPrinter.................................................
TPrinter                                          модуль
 OPrinter.................................................
Поля......................................................
Методы....................................................
Init......................................................
Done (переопределяется редко).............................
ClearDevice...............................................
Configure.................................................
GetDC (переопределяется редко)............................
InitAbortDialog (переопределяется редко)..................
InitPrintDialog (переопределяется редко)..................
InitSetupDialog (переопределяется редко)..................
Print.....................................................
ReportError (иногда переопределяется).....................
SetDevice.................................................
Setup.....................................................
TPrinterAbortDlg                                  модуль
 OPrinter.................................................
Методы....................................................
Init......................................................
SetupWindow (переопределяется редко)......................
WMCommand (переопределяется редко)........................
TPrinterSetupDlg                                  модуль
 OPrinter.................................................
Поля......................................................
Методы....................................................
Init......................................................
Done (переопределяется редко).............................
Cancel (никогда не переопределяется)......................
IDSetup (никогда не переопределяется).....................
TransferData (никогда не переопределяется)................
TPrintout                                         модуль
 OPrinter.................................................
Поля......................................................
Методы....................................................
Init......................................................
Done......................................................
BeginPrinting.............................................
EndDocument...............................................
EndPrinting...............................................
GetDialogInfo.............................................
GetSelection..............................................
HasNextPage...............................................
PrintPage.................................................
SetPrintParams............................................
TPXPictureValidator                                модуль
 Validate.................................................
Поля......................................................
Методы....................................................
Init......................................................
Load......................................................
Done......................................................
Error.....................................................
ISValidInput..............................................
IsInvalid.................................................
Picture...................................................
Store.....................................................
TRadioButton                                      модуль
 ODialogs.................................................
Методы....................................................
Init (иногда переопределяется)............................
GetGlassName..............................................
TRangeValidator                                   модуль
 Validate.................................................
Поля......................................................
Методы....................................................
Init......................................................
Load......................................................
Error.....................................................
IsValid...................................................
Store.....................................................
Transfer..................................................
TScrollBar                                        модуль
 ODialogs.................................................
Поля......................................................
Методы....................................................
Init......................................................
InitResource..............................................
Load......................................................
DeltaPos (переопределяется редко).........................
GetClassName (никогда не переопределяется)................
GetPosition (переопределяется редко)......................
GetRange (переопределяется редко).........................
SBBottom (переопределяется редко).........................
SBLineDown (переопределяется редко).......................
SBLineUp (переопределяется редко).........................
SBPageDown (переопределяется редко).......................
SBPageUp (переопределяется редко).........................
SBThumbPosition (переопределяется редко)..................
SBThumbTrack (иногда переопределяется)....................
SBTop (переопределяется редко)............................
SetPosition (переопределяется редко)......................
SetRange (переопределяется редко).........................
SetupWindow (иногда переопределяется).....................
Store.....................................................
Transfer (иногда переопределяется)........................
TScroller                                          модуль
 OWindow..................................................
Поля......................................................
Методы....................................................
Init......................................................
Load......................................................
Done......................................................
AutoScroll (иногда переопределяется)......................
BeginView.................................................
EndView (иногда переопределяется).........................
HScroll (никогда не переопределяется).....................
IsVisibleRect (переопределяется редко)....................
ScrollBy (переопределяется редко).........................
ScrollTo (иногда переопределяется)........................
SetPageSize (иногда переопределяется).....................
SetRange (никогда не переопределяется)....................
SetBarRange (никогда не переопределяется).................
SetUnits..................................................
Store.....................................................
VScroll (никогда не переопределяется).....................
TSortedCollection                                  модуль
 Objects..................................................
Поля......................................................
Методы....................................................
Load......................................................
Compare (всегда переопределяется).........................
IndexOf (никогда не переопределяется).....................
Insert (никогда не переопределяется)......................
KeyOf (иногда переопределяется)...........................
Search (переопределяется редко)...........................
Store.....................................................
TStatic                                           модуль
 ODialogs.................................................
Поля......................................................
Методы....................................................
Init......................................................
InitResource..............................................
Load......................................................
Clear (переопределяется редко)............................
GetClassName (переопределяется редко).....................
GetText (переопределяется редко)..........................
SetText (переопределяется редко)..........................
Store.....................................................
Transfer (иногда переопределяется)........................
TStrCollection                                     модуль
 Objects..................................................
Методы....................................................
Compare (иногда переопределяется).........................
FreeItem (переопределяется редко).........................
GetItem (переопределяется редко)..........................
PutItem (переопределяется редко)..........................
TStream                                             метод
 Objects..................................................
Поля......................................................
ErrorInfo (чтение/запись).................................
Методы....................................................
CopyFrom..................................................
Error (иногда переопределяется)...........................
Flush (иногда переопределяется)...........................
Get.......................................................
GetPos (всегда переопределяется)..........................
GetSize (всегда переопределяется).........................
Put.......................................................
Read (всегда переопределяется)............................
ReadStr...................................................
Reset.....................................................
Seek (всегда переопределяется)............................
StrRead...................................................
Truncate (всегда переопределяется)........................
Write (всегда переопределяется)...........................
WriteStr..................................................
Тип TStreamRec                                     модуль
 Objects..................................................
TStringLookupValidator                            модуль
 Validate.................................................
Поля......................................................
Методы....................................................
Init......................................................
Load......................................................
Done......................................................
Error.....................................................
Lookup....................................................
NewStringList.............................................
Store.....................................................
TValidator                                        модуль
 Validate.................................................
Поля......................................................
Status....................................................
Методы....................................................
Init......................................................
Load......................................................
Error.....................................................
IsValid...................................................
IsValidInput..............................................
Store.....................................................
Transfer..................................................
Valid.....................................................
Тип TVTransfer                                    модуль
 Validate.................................................
Тип TWndClass                                     модуль
 WinTypes.................................................
TWindow                                           модуль
 OWindows.................................................
Поля......................................................
Методы....................................................
Init (часто переопределяется).............................
InitResource..............................................
Load......................................................
Done (часто переопределяется).............................
Create....................................................
DefWndProc (никогда не переопределяется)..................
FocusChild................................................
GetID (переопределяется редко)............................
GetWindowClass (часто переопределяется)...................
Paint (часто переопределяется)............................
SetCaption................................................
SetupWindow (часто переопределяется)......................
Store.....................................................
UpdateFocusChild..........................................
WMActivate (иногда переопределяется)......................
WMCreate..................................................
WMHScroll (иногда переопределяется).......................
WMLButtonDown (иногда переопределяется)...................
WMMDIActivate.............................................
WMMove....................................................
WMPaint (переопределяется редко)..........................
WMSize (иногда переопределяется)..........................
WMSysCommand..............................................
WMVScroll (иногда переопределяется).......................
Тип TWindowAttr                                   модуль
 OWindows.................................................
TWindowPrintout                                   модуль
 OPrinter.................................................
Поля......................................................
Методы....................................................
Init......................................................
GetDialogInfo.............................................
PrintPage.................................................
TWindowsObject                                     модуль
 OWindows.................................................
Поля......................................................
Методы....................................................
Init (часто переопределяется).............................
Load......................................................
Done (часто переопределяется).............................
AddChild..................................................
At........................................................
CanClose (иногда переопределяется)........................
ChildWithID (никогда не переопределяется).................
CloseWindow...............................................
CMExit....................................................
Create (никогда не переопределяется)......................
CreateChildren............................................
DefChildProc (иногда переопределяется)....................
DefCommandProc (иногда переопределяется)..................
DefNotificationProc (иногда переопределяется).............
DefWndProc................................................
Destroy (никогда не переопределяется).....................
Disable...................................................
DisableAutoCreate.........................................
DisableTransfer...........................................
DispatchScroll (никогда не переопределяется)..............
Enable....................................................
EnableAutoCreate..........................................
EnableKBHandler...........................................
EnableTransfer............................................
FirstThat.................................................
Focus.....................................................
ForEach...................................................
GetChildPtr...............................................
GetChildren...............................................
GetClassName (иногда переопределяется)....................
GetClient (никогда не переопределяется)...................
GetId (переопределяется редко)............................
GetSiblingPtr.............................................
GetWindowClass (иногда переопределяется)..................
IndexOf...................................................
IsFlagSet.................................................
Next......................................................
Previous..................................................
PutChildPtr...............................................
PutChildren...............................................
PutSiblingPtr.............................................
Register (никогда не переопределяется)....................
RemoveChild...............................................
SetFlags..................................................
SetupWindow (часто переопределяется)......................
Show (никогда не переопределяется)........................
Store.....................................................
Transfer (иногда переопределяется)........................
TransferData (иногда переопределяется)....................
WMActivate (иногда переопределяется)......................
WMClose (иногда переопределяется).........................
WMCommand (переопределяется редко)........................
WMDestroy (переопределяется редко)........................
WMHScroll (переопределяется редко)........................
WMNCDestroy (никогда не переопределяется).................
WMQueryEndSession.........................................
WMVScroll (переопределяется редко)........................
Тип TWordArray                                     модуль
 Objects..................................................
Константы voXXXX                                  модуль
WMActivate (иногда переопределяется)......................
WMClose (иногда переопределяется).........................
WMCommand (переопределяется редко)........................
WMDestroy (переопределяется редко)........................
WMHScroll (переопределяется редко)........................
WMNCDestroy (никогда не переопределяется).................
WMQueryEndSession.........................................
WMVScroll (переопределяется редко)........................
Тип TWordArray                                     модуль
 Objects..................................................
Константы voXXXX                                  модуль
 Validate.................................................
Константы vsXXXX                                  модуль
 Validate.................................................
Константы wb_XXXX                                 модуль
 OWindows.................................................
Константы wm_XXXX                                 модуль
 OWindows.................................................
Тип WordRec                                        модуль
 Objects..................................................
Стили окна ws_XXXX                                модуль
 WinTypes.................................................

                              Введение
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В данном руководстве вы найдете полную документацию по
ObjectWindows - объектно-ориентированной  прикладной  среде
для Microsoft Windows.  Здесь описываются не только то, что
может делать ObjectWindows и как,  но и почему. Вы поймете,
что  ObjectWindows  -  это наиболее быстрый путь построения
развитых и многофункциональных приложений Windows.

     Хотя в данном  руководстве  поясняется,  как  работает
Windows,  и  как  с  ней  взаимодействуют  ваши  прикладные
программы, оно не охватывает все аспекты программирования с
использованием  прикладного программного интерфейса Windows
(API).  Эти подробности вы можете узнать в других книгах  о
программировании в Windows.

     ObjectWindows позволит  вам  избежать  утомительных  и
трудоемких  задач,  связанных  с  разработкой  традиционных
приложений Windows.  Тем не менее вы будете иметь доступ ко
всем имеющимся в Windows средствам, но иметь дело с Windows
вам придется только когда вы этого захотите.  Все остальное
делает за вас ObjectWindows.


                      Что такое ObjectWindows?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В иерархию данной версии ObjectWindows включены  новые
объекты,   а   также   добавлены  средства  к  существующим
объектам. Изменения существующих объектов обладают обратной
совместимостью,  так  что  существующий  код  ObjectWindows
следует компилировать с минимальными изменениями.

     В данной версии  ObjectWindows  вы  найдете  следующие
новые средства:

     * поддержку проверки допустимости данных (Глава 13);

     * объекты  для  печати  документов  и содержимого окон
       (Глава 15);

     * специализированные   управляющие   элементы    фирмы
       Borland в стиле Windows;

     * множество модулей.

     Кроме того,   данное  руководство  содержит  следующие
новые материалы:

     * расширенное учебное руководство;

     * новую главу по сообщениям Windows (Глава 16);

     * реорганизованные  главы,  посвященные   иерархии   и
объектам;

     * более  полную информацию о наследовании в справочной
части.


               Для чего предназначена ObjectWindows?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Windows знакомит вас  со  множеством  вещей,  которые,
возможно,  раньше  никогда не приходили вам в голову.  Это,
например,  работа с текстом и графикой в окнах с изменяемым
размером,    взаимодействие   с   другими   программами   в
многозадачной среде и работа  с  почти  600  функциями  API
Windows.  Когда вы подумаете, сколько основных шагов должна
выполнять ваша программа при работе в Windows,  и что нужно
отследить их все, это может выглядеть обескураживающим.

     Чтобы прикладную   программу   можно   было   признать
приложением  Windows,  она  должна  делать  очень   многое.
Например, она не может выводить информацию прямо на экран и
записывать  данные  непосредственно  в  видеопамять.  Кроме
того,  приложение  Windows  должно отвечать на уведомляющие
сообщения,  которые посылает своим  приложениям  Windows  в
ответ  на действия пользователя (события) тип выбора пункта
меню.

     Но вам не обязательно делать все  это  самим.  Хорошим
началом для этого послужит ObjectWindows.

     ObjectWindows -      это      объектно-ориентированная
библиотека,  инкапсулирующая большую часть свойств  окна  и
позволяющая  вам  использовать наследование,  а не начинать
заново с началом каждой новой  программы.  Обеспечивая  для
вас стабильную и жесткую операционную среду,  она позволяет
вам сосредоточиться на индивидуальных фрагментах программы,
а не на частях, общих для всех приложений Windows.


                          Что нужно знать
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Перед началом  программирования  для Windows вы должны
быть знакомы с его основами.  Во-первых,  нужно знать,  как
использовать  Паскаль  и  Windows.  О  программировании  на
Паскале  рассказывается  в  "Руководстве  пользователя"   и
"Руководстве  по  языку",  а  о  работе с Windows вы можете
прочитать  в  документации,  поставляемой   с   программным
обеспечением Windows.

     Кроме того,  для  работы  с  ObjectWindows  вы  должны
владеть     объектно-ориентированным     программированием.
Приложения,   написанные  с  использованием  ObjectWindows,
интенсивно  используют   объектно-ориентированные   методы,
включая  наследование и полиморфизм.  Эти темы освещаются в
главе  по  объектно-ориентированному   программированию   в
"Руководстве пользователя".  Кроме объектно-ориентированных
методов  вы  должны  знать  о  работе   с   указателями   и
динамическими  переменными,  поскольку почти все экземпляры
объектов   ObjectWindows   динамически   распределяются   в
динамической    области   памяти.   Об   указателях   также
рассказывается в "Руководстве пользователя".


                 Как работать с данным руководством
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     "Руководство по  программированию   с   использованием
ObjectWindows"  расширено,  что  сделало его более полным и
простым  в   использовании.   Если   вы   уже   знакомы   с
ObjectWindows,  то можете пропустить главы 7, 13, 15 и 16 и
прочитать о  новых  средствах.  Если  вы  только  начинаете
работать  с  ObjectWindows,  то  прочитайте  сначала первую
часть   ("Изучение   ObjectWindows").   Эту   часть   можно
использовать  в  качестве  учебного руководства,  в котором
описывается построение полного приложения  ObjectWindows  и
объясняются принципы ObjectWindows.


             О чем рассказывается в данном руководстве
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Так как  ObjectWindows представляет собой новый подход
в программировании для Windows и использует некоторые новые
методы,  с  которыми  вы,  вероятно,  не  знакомы,  в  этом
руководстве вы можете  найти  поясняющий  материал.  Полные
справочные  материалы  по  ObjectWindows  вы можете найти в
Главе 21 "Справочник по ObjectWindows".

     Это руководство разбито на 4 части:

     * Часть 1,  "Изучение ObjectWindows",  знакомит вас  с
       принципами разработки прикладной программы Windows с
       помощью ObjectWindows,  включая  учебные  материалы,
       описывающие    процесс    написания   и   дополнения
       приложения ObjectWindows.

     * В Части  2,  "Использование  ObjectWindows",  дается
       более     детальная    информация    об    элементах
       ObjectWindows,   включая   обзор   иерархии   и   ее
       взаимодействие  с  операционной  средой  Windows,  а
       также  подробно  поясняются  части  иерархии  и   их
       использование.

     * В   Части   3,   "Продвинутое   программирование   с
       использование ObjectWindows" обсуждаются важные темы
       продвинутого программирования в Windows,  особенно в
       части     непосредственного     взаимодействия     с
       операционной   средой  Windows,  включая  сообщения,
       графику и использование ресурсов.  Здесь вы  найдете
       также главы о наборах и потоковых объектах.

     * Часть 4, "Справочник по ObjectWindows", представляет
       собой полный справочник по всем  объектам  и  других
       элементам, включенным в модули ObjectWindows.

                Часть 1. Изучение ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


                  Глава 1. Знакомство с Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В следующих  нескольких главах мы построим графическую
интерактивную   программу   Windows,   дополненную    меню,
средствами   сохранения   и  загрузки  файлов,  графикой  и
отображением   текста,    а    также    специализированными
управляющими  элементами.  По  ходу дела вы познакомитесь с
основными  принципами  проектирования  программы   Windows,
такими  как  обработка  сообщений,  управление  дочерним  и
порождающим окном и  автоматическое  повторное  отображение
графики.

     Этот процесс разбит на следующие шаги:

     - создание базового приложения;
     - вывод текста в окне;
     - изображение линий в окне;
     - добавление строки меню;
     - добавление диалогового окна;
     - изменение атрибутов пера;
     - повторное отображение графики;
     - сохранение изображения в файле;
     - печать образа;
     - добавление всплывающего окна;
     - добавление специализированных управляющих элементов;
     - создание специализированного  управляющего  элемента
     окна.

     Исходный код приложения для различных этапов вы можете
найти на дистрибутивных дисках.  Описываемым в  руководстве
шагам  соответствуют  файлы  STEP01.PAS,  STEP02.PAS  и так
далее (можно найти также промежуточные программы).

                Часть 1. Изучение ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


                  Глава 1. Знакомство с Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В следующих  нескольких главах мы построим графическую
интерактивную   программу   Windows,   дополненную    меню,
средствами   сохранения   и  загрузки  файлов,  графикой  и
отображением   текста,    а    также    специализированными
управляющими  элементами.  По  ходу дела вы познакомитесь с
основными  принципами  проектирования  программы   Windows,
такими  как  обработка  сообщений,  управление  дочерним  и
порождающим окном и  автоматическое  повторное  отображение
графики.

     Этот процесс разбит на следующие шаги:

     - создание базового приложения;
     - вывод текста в окне;
     - изображение линий в окне;
     - добавление строки меню;
     - добавление диалогового окна;
     - изменение атрибутов пера;
     - повторное отображение графики;
     - сохранение изображения в файле;
     - печать образа;
     - добавление всплывающего окна;
     - добавление специализированных управляющих элементов;
     - создание специализированного  управляющего  элемента
     окна.

     Исходный код приложения для различных этапов вы можете
найти на дистрибутивных дисках.  Описываемым в  руководстве
шагам  соответствуют  файлы  STEP01.PAS,  STEP02.PAS  и так
далее (можно найти также промежуточные программы).

              Шаг 1: Создание базового приложения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ЪДДДДДДДДДДДДДДДДДДДДДДДї
     іЫStepЫ1:ЫBasicЫAppЫЫЫЫЫі Базовая программа
     і Step 2: Text          і Текст
     і Step 3: Lines         і Строки
     і Step 4: Menu          і Меню
     і Step 5: About Box     і Об окне
     і Step 6: Pens          і Перья
     і Step 7: Painting      і Рисование
     і Step 8: Streams       і Потоки
     і Step 9: Printing      і Печать
     і Step 10: Palette      і Палитра
     і Step 11: BWCC         і Управляющие элементы окна
     і Step 12: Custom ctrls і Специализированные элементы
     АДДДДДДДДДДДДДДДДДДДДДДДЩ

     Отправным пунктом для всех программ, которые вы пишете
с    применением    ObjectWindows,    является    программа
STEP01A.PAS.  Эта  программа,  которая  называется   Steps,
создает основное окно приложения.

     Все программы ObjectWindows должны использовать модуль
OWindows,    которые    содержит    стандартные    объекты,
используемые   ObjectWindows   для   приложений   и   окон.
Большинство приложений включают  в  себя  также  диалоговые
блоки и соответствующие управляющие элементы. ObjectWindows
предусматривает для них объекты в модуле ODialogs. Объекты,
относящиеся   к   печати,   находятся  в  модуле  OPrinter.
Программам,  применяющим наборы и потоки,  необходим модуль
Objects.

     Кроме модулей   ObjectWindows   большинству   программ
необходимы также модули WinTypes и WinProcs. Эти два модуля
определяют  типы  и  константы  (WinTypes)  и  процедуры  и
функции  (WinProcs),  образующие   прикладной   программный
интерфейс    Windows   (API).   Приложениям,   использующим
продвинутые средства Windows  (версий  старше  3.0),  кроме
данных двух нужны также другие модули.

           Примечание: Обзор   модулей   ObjectWindows   вы
      можете найти в Главе 7 "Иерархия ObjectWindows".

                    Требования к приложению
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Все приложения  Windows  имеют основное окно,  которое
выводится при запуске программы пользователем. Пользователь
выходит из приложения, закрывая основное окно. В приложении
ObjectWindows основное окно представляет собой объект окна.
Этот   объект   принадлежит   объекту  приложения,  который
отвечает за создание  и  вывод  на  экран  основного  окна,
обработку сообщений Windows и завершение программы.  Объект
приложения действует  как  объектно-ориентированная  замена
самого   приложения.  Аналогично,  чтобы  сделать  скрытыми
детали   программирования    в    Windows,    ObjectWindows
предусматривает  окно,  диалоговый  блок и другие объектные
типы.

     Каждая программа ObjectWindows должна определять новый
тип  приложения,  являющегося  наследником предоставляемого
типа TApplication.  В программе Steps этот  тип  называется
TMyApplication. Приведем основной блок программы Steps:

     var
       MyApp: TMyApplication;
     begin
       MyApp.Init('Steps');
       MyApp.Run;
       MyApp.Done;
     end.

     Init - это конструктор TMyApplication, создающий новый
объект MyApp.  Он позволяет  также  задать  имя  приложения
(поле  объекта) 'Steps' и создает (и выводит) основное окно
приложения.  Run   запускает   последовательность   вызовов
методов,  составляющих  ход  выполнения приложения Windows.
Done - это деструктор TMyApplication.

                  Определение типа приложения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ваша прикладная  программа  должна создавать новый тип
из  стандартного  типа  ObjectWindows   TApplication   (или
некоторых типов,  производных от TApplication).  Этот новый
тип должен переопределять по  крайней  мере  один  метод  -
InitMainWindow.    TApplication.InitMainWindow   вызывается
ObjectWindows автоматически для  установки  основного  окна
программы.  Каждое  приложение ObjectWindows должно строить
свое основное окно.

           Примечание: Объекты     приложения      подробно
      описываются в Главе 8.

     Определение TMyApplication имеет следующий вид:

     type
       TMyApplication = object(TApplication)
          procedure InitMainWindow; virtual;
     end;

                 Инициализация основного окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     InitMainWindow отвечает  за  построение  объекта окна,
используемого в качестве  основного  окна  программы.  Этот
объект  основного  окна  хранится в поле объекта приложения
MainWindow. Объекту приложения принадлежит объект основного
окна,  но  эти  два  объекта  не  являются  родственными  в
иерархии наследования.

     precedure TMyApplication.InitMainWindow;
     begin
       MainWindow := New(PWindow, Init(nil, 'Steps'));
     end;

     Обычно метод    InitMainWindow    модифицируется   для
создания  нового  типа  основного  окна.  Указанный   метод
использует  экземпляр  объекта  TWindow  -  предоставляемый
ObjectWindows тип окна,  который определяет наиболее  общее
окно.  На  шаге  2  мы заменим его более интересным оконным
типом.

     Пока программа Steps просто выводит  на  экран  пустое
окно,  которое  можно  перемещать  по экрану,  изменять его
размер,  минимизировать,   максимизировать   и   закрывать.
Приведем   полный   листинг  программы  Steps,  которую  мы
получили к данному моменту:

     program Steps;

     uses OWindows;

     type
       TMyApplication = object(TApplication)
          procedure InitMainWindow; virtual;
       end;

     procedure TMyApplication.InitMainWindow;
     begin
       MainWindows := New(PWindow, Init(nil, 'Steps'));
     end;

     var MyApp: TMyApplication;
     begin
       MyApp.Init('Steps');
       MyApp.Run;
       MyApp.Done;
     end.

                     Объект основного окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Пока программа  Steps  состоит  из  двух  объектов   -
объекта   приложения  и  объекта  окна.  Объект  приложения
(MyApp)  является  экземпляром  TMyApplication   -   типом,
производным   от   TApplication.  Оконный  объект,  который
содержится  в  поле  MainWindow  объекта  MyApp,   является
экземпляром  TWindow  (общее  окно ObjectWindows).  Во всех
программах,  кроме простейших,  вам  нужно  определить  тип
своего    основного    окна,    соответствующий   поведению
приложения.  В данном разделе мы выведем на экран  основное
окно, тип которого является производным от TWindow.

           Приложения: Более   подробно  об  основном  окне
      рассказывается в Главе 8 "Объекты приложения".

                    Что такое объект окна?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Объект приложения  инкапсулирует стандартное поведение
приложения Windows,  включая построение основного окна. Тип
TApplication  обеспечивает  фундаментальное  поведение  для
каждого создаваемого вами приложения.

     Аналогично, объект   окна   инкапсулирует   поведение,
реализуемое приложениями ObjectWindows, включая их основные
окна.  Это  поведение  включает  в  себя  вывод  на  экран,
изменение  размера  и  закрытие;  ответ на пользовательские
события,  такие как щелчок  кнопкой  "мыши",  буксировку  и
выбор пунктов меню;  вывод управляющих элементов, таких как
блоки списка и командные кнопки.  Тип TWindow и его  предок
TWindowsObject   предусматривают   для   данного   базового
поведения методы и поля.

           Примечание: Объекты окна подробно описываются  в
      Главе 10 "Объекты окна".

     Чтобы сделать  ваши программы полезными и интересными,
вам нужно создать новый тип,  производный от TWindow. Новый
тип  наследует  поля  и  методы  TWindow  и добавляет часть
своих.  В  общем  случае  объектно-ориентированный   подход
позволяет вам не "изобретать" каждый раз окно.

                           Описатели
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Объект окна имеет по крайней мере три  поля:  HWindow.
Parent   и  ChildList.  HWindow  содержит  описатель  окна.
Описатель окна - это уникальное  число,  которое  связывает
интерфейсный  объект  (такой как окно,  диалоговый блок или
объект управляющего элемента) с  соответствующим  элементом
экрана.

           Примечание: Подробно   об   описателях  окна  их
      использовании  рассказывается  в  Главе  10  "Объекты
      окна".

     Таким образом,   HWindow   содержит   целое  значение,
идентифицирующее  соответствующий   элемент   экрана.   Это
напоминает  бирку на связке ключей.  Аналогично тому как вы
выбираете ключ, чтобы достать из шкафа пальто, вы выбираете
описатель  для  получения  окна.  В  большинстве случаев вы
работаете с объектами  окна,  и  у  вас  нет  необходимости
манипулировать  описателем  окна  непосредственно,  но  они
используются  при  вызове  функций  Windows.  Например,  на
данном  шаге  вы вызываете функцию MessageBox.  Эта функция
требует указания параметра,  идентифицирующего  порождающее
окно  сообщений.  Вы  указываете  основное окно,  описатель
которого записан в его поле HWindow:

     MessageBox(MainWindow^.HWindow, 'Хотите   сохранить?',
                'Файл     не    изменен',    mb_YesNo    or
                mb_IconQuestion);

                  Порождающие и дочерние окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Большинство приложений  используют несколько окон,  и,
чтобы  они   взаимодействовали,   их   требуется   связать.
Например,  когда вы завершаете приложение, оно должно иметь
способ очистки всех окон,  за  которые  отвечает.  В  общем
случае  Windows  справляется  с  этим,  связывая  окна  как
дочернее и порождающее.  Порождающее окно отвечает за  свое
дочернее  окно.  ObjectWindows  предусматривает для каждого
объекта окна поля для отслеживания порождающего и  дочерних
окон.

           Примечание: Взаимодействие  этих  окон подробнее
      описывается в Главе 9.

     Поле Parent содержит указатель на порождающий  оконный
объект.  Это не порождающее окно в смысле предка,  а скорее
окно-владелец. Взаимосвязь этих окон описывается в шаге 10.

     Третье поле оконного объекта  -  это  поле  ChildList,
содержащее связанный список дочерних окон.

                   Создание нового типа окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Теперь у вас есть некоторое представление о  том,  что
содержит оконный объект,  и вы можете создать новый оконный
тип,  производный от TWindow,  используя его  как  основное
окно программы Step. Сначала измените определения и задайте
новый тип TStepWindow.  Не забудьте также определить  новый
указатель  на тип TStepWindow - PStepWindow,  который будет
полезен при создании экземпляров объектов TStepWindow.

     type
       PStepWindow = ^TStepWindow;
       TStepWindow = object(TWindow)
     end;

     Затем измените   TMyApplication.InitMainWindow,  чтобы
создать  в   качестве   основного   окна   вместо   TWindow
TStepWindow.

     procedure TMyApplication.InitMainWindow;
     begin
       Main := New(PStepWindow, Init(nil, 'Step'));
     end;

     Определение нового типа и создание  его  экземпляра  в
InitMainWindow  -  это  все,  что требуется для определения
нового  типа  основного   окна   для   TMyProgram.   Объект
приложения   вызывает  методы  для  создания  интерфейсного
элемента окна (Create) и вывода его на  экран  (Show).  Вам
почти   никогда  не  потребуется  использовать  эти  методы
непосредственно.  Обычно они вызываются при  вызове  метода
MakeWindow объекта приложения.

           Примечание: MAkeWindow   поясняется  в  Главе  9
      "Интерфейсные объекты".

     Однако TStepWindow   не   определяет    новых    видов
поведения,  отличных от тех, которые наследуются от TWindow
и  TWindowObject.  Другими  словами,  программа   Step   не
становится  более  интересной.  Такие  виды поведения будут
добавлены в следующем разделе.

                     Реакция на сообщения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Скорейший способ сделать оконный объект полезным - это
заставить его  отвечать  на  некоторые  сообщения  Windows.
Например,   когда  вы  щелкаете  "мышью"  в  основном  окне
программы   Step,   Windows   посылает    окну    сообщение
wm_LButtonDown,  которое  перехватывается  ObjectWindows  и
посылается затем  соответствующему  оконному  объекту.  Это
указывает оконному объекту,  что пользователь щелкнул в нем
кнопкой "мыши". При этом передаются также координаты точки,
где   пользователь   нажал   кнопку.   (Эту  информацию  мы
используем в шаге 2.)

           Примечание: Сообщения   Windows   определены   в
      модуле WinTypes.

     Аналогично, когда  пользователь щелкает правой кнопкой
"мыши",  основной   оконный   объект   получает   сообщение
wm_RButtonDown,  переданное  Windows.  На следующем шаге мы
узнаем,  как сделать так,  чтобы основное  окно  (экземпляр
TStepWindow)  отвечало на эти сообщения и делало что-нибудь
полезное.

     Чтобы перехватывать сообщения Windows  и  отвечать  на
них, для каждого типа поступающего сообщения, на которое вы
хотите реагировать,  вам нужно  определить  метод  оконного
объекта.   Такие  методы  называются  методами  реакции  на
сообщение.  Чтобы определить заголовок  определения  метода
как  метод  реакции,  нужно  добавить к виртуальному методу
расширение,  представляющее собой идентификатор  сообщения,
на которое нужно реагировать.  Например,  определенный ниже
метод реагирует на все сообщения wm_LButtonDown.

type
  TStepWindow = object(TWindow)
     procedure WMLButtonDown(var Msg: TMessage); virtual
        vm_First + wm_LButtonDown;
  end;

      Примечание: Все программы и модули,  переопределяющие
 методы ответа на сообщение, должны использовать WinTypes.

     Все сообщения  в Windows,  включая системные сообщения
Windows и команды меню, представляются в виде чисел. Каждый
метод  реакции  на сообщение должен иметь уникальное число,
так что для сообщений Windows  и  команд,  если  они  имеют
одинаковые номера, вызываются различные методы.

     Чтобы облегчить  для  вас  эту  задачу,  ObjectWindows
определяет для каждого вида сообщений  константы:  wm_First
для  сообщений  окон,  cm_First  для  командных сообщений и
nf_First для  уведомляющих  сообщений.  Подробнее  об  этих
константах рассказывается в Главе 7, но сейчас нужно только
помнить,  что когда вы пишете метод реакции  на  сообщение,
начинающееся с wm_, к нему добавляется wm_First.

     Msg -  это  запись  типа  TMessage,  содержащая  такую
информацию,  как координаты точки,  где была нажата  кнопка
"мыши". Все методы реакции на сообщение должны воспринимать
один параметр-переменную типа  TMessage.  Аргумент  Msg  мы
рассмотрим в программе Step позднее.

     В данный  момент  вы  можете  просто определить методы
реакции,  которые выводят на экран окно сообщения о нажатии
кнопки  "мыши".  Позднее вы сможете добавить более полезную
реакцию.  Приведем определение метода  реакции  на  нажатие
левой кнопки "мыши":

procedure TStepWindow.WMLButtonDown(var Msg: TMessage);
begin
  MessageBox(HWindow, 'Вы нажали левую кнопку мыши',
      'Диспетчеризуемое сообщение', mb_OK);
end;

           Примечание: Программы,      которые     вызывают
      MessageBox или другие  функции  API  Windows,  должны
      использовать модуль WinProcs.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫStepsЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і                                                       і
і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї      і
і іІ=І±±±±±±±±±Диспетчеризуемое сообщение±±±±±±±±і      і
і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ      і
і і                                              і      і
і і       Вы нажали левую кнопку мыши            і      і
і і                ЪДДДДДДДДДДДї                 і      і
і і                і±±±±OK±±±±±і                 і      і
і і                АДДДДДДДДДДДЩ                 і      і
і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ      і
і                                                       і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 1.2 Программа Steps реагирует на пользовательское
событие.

                Завершение прикладной программы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Программа Steps     завершает     выполнение,    когда
пользователь дважды щелкает "мышью"  в  блоке  управляющего
меню  основного  окна  - маленьком квадрате в левом верхнем
углу.  Окно  и  приложение  немедленно  закрываются.  Такое
поведение  годится  для простых программ,  но может вызвать
затруднения в более сложных случаях.

     Перед выходом  хорошо  написанное  приложение   всегда
спрашивает,  хочет  ли пользователь сохранить несохраненные
результаты работы.  Такой вид  поведения  вы  легко  можете
добавить в свою прикладную программу ObjectWindows. Начните
со Step и добавьте двойную проверку запроса пользователя на
выход.

     Когда пользователь    пытается    закрыть   приложение
ObjectWindows,  Windows посылает основному  окну  сообщение
wm_Close,   которое  вызывает  метод  CanClose  приложения.
CanClose - это булевская  функция,  указывающая,  можно  ли
завершить   (OK)  приложение  (True).  По  умолчанию  метод
CanClose наследуется из вызова TApplication метода CanClose
основного оконного объекта. В большинстве случаев решение о
закрытии (OK) принимается объектом основного окна.

                   Переопределение CanClose
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Тип основного   окна   TStepWindow   наследует   метод
CanClose от TWindowObject, которые вызывает методы CanClose
каждого  из  своих  дочерних окон (если они имеются).  Если
дочерних окон нет (как в данном  случае),  CanClose  просто
возвращает  значение  True.  Чтобы модифицировать поведение
приложения при закрытии,  вы  можете  переопределить  метод
CanClose для объектного типа своего основного окна:

     function TStepWindow.CanClose: Boolean;
     var Reply: Integer;
     begin
        CanClose := True;
        Reply := MessageBox(HWindow, 'Хотите сохранить?',
                   'Графическое изображение изменено',
                   mb_YesNo or mb_IconQuestion);
        if Reply = id_Yes then CanClose := False;
     end;


     Теперь когда пользователи попытаются закрыть Step, они
получат  окно  сообщений  с  запросом  "Хотите  сохранить".
Щелчок "мышью" на командной  кнопке  Yes  (Да)  приводит  к
тому,    что   CanClose   возвращает   значение   False   и
предотвращает закрытие основного окна и приложения.  Щелчок
"мышью" на No (Нет) возвращает True, и приложение завершает
работу.  На шаге 8 это  окно  сообщений  получит  некоторый
смысл.  Модифицированная  программа  Steps показана на Рис.
1.3.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫStepsЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і                                                         і
і                                                         і
і  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї       і
і  іІ=І±±±±±±±±±Изображение изменилось±±±±±±±±±±±±і       і
і  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ       і
і  і  ІІІ                                         і       і
і  і  І?І  Хотите сохранить?                      і       і
і  і  ІІІ  ЪДДДДДДДДДДДї      ЪДДДДДДДДДДДї       і       і
і  і       і±±±Yes±±±±±і      і±±±±No±±±±±і       і       і
і  і       АДДДДДДДДДДДЩ      АДДДДДДДДДДДЩ       і       і
і  АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ       і
і                                                         і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 1.3 Программа Steps с переопределенным поведением
окна.

                 Дальнейшее изменение закрытия
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Естественно, сообщение    о   том,   что   изображение
изменилось,  полезно только в том  случае,  если  программа
действительно обнаруживается изменение изображения. Добавив
в TStepWindow поле типа Boolean,  вы  можете  задать  флаг,
указывающий  на  изменение  изображения,  и  выводить  окно
сообщения только тогда, когда этот флаг установлен.

     Нужно помнить о том, что когда вы добавляете это поле,
поле  нужно  также инициализировать,  поэтому переопределим
конструктор TStepWindow:

     type
       PStepWindow = ^TStepWindow;
       TStepWindow = object(TWindow)
          HasGhanged: Boolean;
          constructor Init(AParent: PWindowsObject: ATitle:
                           PChar);
           .
           .
           .
        end;

     constructor TStepWindow.Init(AParent: PWindowsObject:
                           ATitle: PChar);
     begin
       inherited Init(AParent, ATitle);
       HasChanged := False;
     end;

     Далее измените  метод  CanClose  для  проверки   перед
выводом окна сообщения HasChanged:

     function TStepWindow.CanClose: Boolean;
     var Reply: Integer;
     begin
       CanClose := True;
       if HasChanged then
       begin
         Reply := MessageBox(HWindow, 'Хотите сохранить?',
                             'Изображение изменилось',
                              mb_YesNo or mb_IconQuestion);
         if Reply = id_Yes then CanClose := False;
       end;
     end;

     Позднее, когда вы  фактически  изменяете  изображение,
HasChanged  нужно  установить  в  True.  Следующий  листинг
показывает полный исходный под программы  Steps  на  данном
шаге:

     program Steps;

     uses WinTypes, WinProcs, OWindows;

     type
       TMyApplication = object(TApplication)
          procedure InitMainWindow; virtual;
       end;

     type
       PStepWindow = ^TStepWindow;
       TStepWindow = object(TWindow)
          Haschanged: Boolean;
          constructio Init(AParent: PWindowsObject; ATitle:
                            PChar);
          function CanClose: Boolean; virtual;
          procedure CanClose: Boolean; virtual;
          procedure WMLButtonDown(var Msg: TMessage);
             virtual wm_First + wm_LButtonDown;
          procedure WMRButtonDown(var Msg: TMessage);
             virtual sm_First +? wm_RButtonDown;
     end;

     constructor TStepWindow.Init(AParent: PWindowsObject;
                                  ATitle: PChar);
     begin
       inherited Init(AParent, ATitle);
       HasChanged := False;
     end;

     function TStepWindow.CanClose: Boolean;
     var Reply: Integer;
     begin
        if HasChanged then
        begin
          CanClose := True;
          Reply := MessageBox(HWindow, 'Хотите сохранить?',
                              'Изображение изменилось',
                             mb_YesNo or mb_IconQuestion);
         if Reply = id_Yes then CanClose := False;
       end;
     end;

 procedure TStepWindow.WMLButtonDown(var Msg: TMessage);
 begin
   MessageBox(HWindow, 'Вы нажали левую кнопку мыши',
       'Диспетчеризуемое сообщение', mb_OK);
 end;

 procedure TStepWindow.WMRButtonDown(var Msg: TMessage);
 begin
   MessageBox(HWindow, 'Вы нажали правую кнопку мыши',
       'Диспетчеризуемое сообщение', mb_OK);
 end;

     procedure TMyApplication.InitMainWindow;
     begin
       MainWindows := New(PStepWindow, Init(nil, 'Steps'));
     end;

     var MyApp: TMyApplication;
     begin
       MyApp.Init('Steps');
       MyApp.Run;
       MyApp.Done;
     end.
                      Глава 2. Заполнение окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Пока ваша  программа  не делает ничего интересного.  В
данной  главе  мы  возьмем  программу  Step,  которая  пока
представляет собой просто оболочку программы, и преобразуем
ее в полезное интерактивное графическое приложение. Сначала
мы выведем в основном окне текст.  Затем преобразуем Step в
полное графическое приложение, позволяющее вам отображать в
основном окне линии различной толщины.

                   Шаг 2: Отображение текста в окне
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                      ЪДДДДДДДДДДДДДДДДДДДДДДДї
                      і Step 1: Basic App     і
                      іЫStepЫ2:ЫTextЫЫЫЫЫЫЫЫЫЫі
                      і Step 3: Lines         і
                      і Step 4: Menu          і
                      і Step 5: About Box     і
                      і Step 6: Pens          і
                      і Step 7: Painting      і
                      і Step 8: Streams       і
                      і Step 9: Printing      і
                      і Step 10: Palette      і
                      і Step 11: BWCC         і
                      і Step 12: Custom ctrls і
                      АДДДДДДДДДДДДДДДДДДДДДДДЩ

     В качестве   первого   шага   в  направлении  создания
отображающей программы нарисуем в окне некоторые  текстовые
символы.  Текст  будет отображаться в ответ на щелчок левой
кнопкой "мыши",  который вы перехватывали  на  шаге  1.  Но
вместо  вывода  окна  сообщения  на этот раз реакцией будет
вывод текста,  показывающего координаты той точки  в  окне,
где вы щелкнули кнопкой "мыши".

     В графической  операционной  среде  типа Windows текст
рисуется как графика,  а не выводится в  виде  символов  на
стандартное  устройство  вывода.  В  некотором  смысле  это
эквивалентно  использованию  позиционирования   курсора   в
программах   DOS,   где  вы  задаете  расположение  каждого
текстового элемента,  а не полагаетесь на прокрутку экрана.
Конечно,  в  Windows  вы  можете  также управлять размером,
стилем, гарнитурой и цветом текста.

                     Вывод в контексте дисплея
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы вывести  текст  в  основном окне программы Step,
вам нужна  некоторая  отображаемая  информация.  В  Windows
имеются  специальные  средства,  управляющие  ее  графикой,
которые называются  контекстом  дисплея.  Контекст  дисплея
можно рассматривать как элемент, представляющий поверхность
окна,  где выводится изображение. Контекст экрана необходим
Windows для отображения в окне любого текста или графики.

           Примечание: Подробно    о    контексте   дисплея
      рассказывается в Главе 17 "Интерфейс  с  графическими
      устройствами".


                    Что такое контекст дисплея?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

   Контекст дисплея имеет три основных функции отображения:

     * Он  обеспечивает,  что  текст и графика не выводятся
       вне поверхности окна.

     * Он  управляет  выбором  и  отменой  инструментальных
       средств  отображения:  перьев,  кистей и шрифтов.  В
       шаге 3 показан пример  выбора  нового  пера,  но  мы
       начнем сначала с вывода текста.

     * Он  обеспечивает  независимость  от устройства.  Для
       вывода в контексте дисплея ваша программа использует
       стандартные функции API Windows. В шаге 9 мы покажем
       как можно использовать одни  и  те  же  команды  для
       отображения в окне и на принтере.

     Windows управляет    контекстом    дисплея   в   своем
собственном  пространстве  памяти,   но   ваша   прикладная
программа  может  отслеживать  контекст  дисплея  с помощью
описателей.  Как  и  описатель  окна,  описатель  контекста
дисплея  - это число,  идентифицирующее корректный контекст
дисплея Windows.

     Поскольку, чтобы  рисовать  в  окне   при   буксировке
"мыши",  вам необходим контекст дисплея, создайте в объекте
основного окна новое поле с именем  DragDC,  которое  будет
содержать  описатель  контекста  дисплея.  DragDC имеет тип
HDC, который эквивалентен типу Word.

     Чтобы использовать контекст  дисплея,  ваша  программа
должна:

     * получить контекст дисплея;

     * нарисовать в нем;

     * освободить контекст дисплея.

                    Получение контекста дисплея
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы отобразить что-то  в  окне,  вы  должны  сначала
получить  контекст  дисплея.  Это  можно сделать,  вызвав в
одном из методов типа непосредственно перед отображением на
экране функцию Windows GetDC:

     DragDC := GetDC(HWindow);

                  Использование контекста дисплея
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Теперь вы  можете  использовать  DragDC   в   качестве
параметра в вызовах графических функций Windows,  требующих
указания контекста дисплея. Приведем несколько примеров:

     TextOut(DragDC, 20, 20, 'Пример текста', 11);
     LineTo(DragDC, 30, 45);


                   Освобождение контекста дисплея
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     После отображения   текста   или   графики  вы  должны
освободить   контекст   дисплея   (как   только   закончите
отображение).

     ReleaseDC(HWindow, DragDC);

     Если вы   не   освободите   весь  полученный  контекст
дисплея,  то скоро исчерпаете его,  что приводит  обычно  к
зависанию компьютера. Если ваша программа не может что-либо
отобразить, проверьте освобождение контекстов дисплея.

     Windows выделяет  по  пять   контекстов   дисплея   на
приложение,  которые  можно  совместно  использовать  через
GetDC. Пока в Windows зарезервировано достаточно памяти, вы
можете с помощью GetDC получить другие контексты.

           Примечание: GDI  и  вопросы использования памяти
      освещаются  в  Главе  17  "Интерфейс  с   графическим
      устройством".

                         Координаты Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если вы работали с графикой раньше, то вам уже знакомо
понятие системы координат. В Windows координаты потребуются
вам для вывода текста.

     При отображении  вас  касаются  только  координаты   в
контексте  дисплея.  Windows  обеспечивает,  чтобы контекст
дисплея попадал в область клиента окна.

           Примечание: Область клиента  -  это  часть  окна
      внутри рамки.

     На этом   шаге   Step  отобразит  текст,  показывающий
координаты той  точки  в  окне,  где  вы  щелкнули  кнопкой
"мыши".  Например,  '(20, 30)' - это точка, отстоящая на 20
элементов изображения вправо и на 30 элементов  изображения
вниз  от  верхнего левого угла поверхности отображения.  Вы
можете отображать прямо в той точке,  где щелкнули "мышью".
Это показано на Рис. 2.1.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫStepsЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і(3,7)                                          (483,7)   і
і                              (385,31)                   і
і                                                         і
і    (60,42)                                              і
і                    (217,52)                             і
і                                                         і
і                           (302,110)      (444,110)      і
і                                                         і
і                                                         і
і          (109,141)                                      і
і                                                         і
і    (52,182)                                             і
і                      (239,187)       (385,181)          і
і                                                         і
і(4,288)                                         (474,220)і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 2.1  Отображение  текста  в  точке нажатия кнопки
"мыши".



                        Параметры сообщений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Щелчок левой   кнопкой   "мыши"  генерирует  сообщение
wm_LButtonDown,  который вы перехватываете с помощью метода
реакции на сообщение WMLButtonDown.

     Параметр Msg   метода   реакции   на  сообщение  несет
информацию  о  породившем  сообщение  событии  (такую   как
координаты точки, где пользователь щелкнул кнопкой "мыши").
Msg - это запись TMessage,  поля которой содержат  параметр
lParam   типа   Longint   и   параметр  wParam  типа  Word.
Идентификаторы  lParam  и  wParam  соответствуют  полям   в
структуре сообщения Windows TMsg.

     TMessage определяют также вариантные поля,  содержащие
подполя lParam и wParam.  Например,  Msg.lParamLo  содержит
младшее слово lParam,  а Msg.lParamHi - старшее слово. Чаще
всего используются поля wParam, lParamLo и lParamHi.

     В случае    WMLButtonDown    Msg.lParamLo     содержит
x-координату точки нажатия кнопки "мыши",  а Msg.lParamHi -
y-координату этой точки.  Таким образом,  чтобы  переписать
WMLButtonDown   для  отображения  координат  точки  нажатия
кнопки,  нужно преобразовать Msg.lParamLo и Msg.lParamHi  в
строки и,  чтобы они приняли вид '(25,21)', конкатенировать
их  с  запятой.  В  примере   для   форматирования   строки
используется функция Windows WVSPrintF.

           Примечание: Слияние    параметров   зависит   от
      сообщения.  Подробности  о  каждом  сообщении  и  его
      параметре    вы   можете   узнать,   воспользовавшись
      оперативным справочником Help.

     После получения итоговой строки  ее  можно  вывести  в
точке  нажатия  кнопки  "мыши"  с  помощью  функции Windows
TextOut.  Перед  отображением   нужно   получить   контекст
дисплея, а после отображения - освободить его.

procedure TStepWindow.WMLButtonDown(var Msg: TMessage);

var S: array[0..9] of Char;
begin
  WVSPrint(S, '(%d,%d)', Msg.LParam);
  DragDC := GetDC(HWindow);
  TextOut(DragDc, Msg.LParamLo, Msg.LParamHi, S, StrLen(S));
  ReleaseDC(HWindow, DragDC);
end;

      Примечание: Windows   ожидает   получения   строк   с
      завершающим   нулем   (конечным   нулевым    байтом).
      Подробнее   эти   строки   описываются   в  Главе  18
      "Руководства по языку".

                            Очистка окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В приложение,  отображающее  текст,  вы  можете  также
добавить еще одну функцию - функцию отчистки окна. Заметим,
что  после изменения размера окна,  либо когда вы скрываете
его и выводите снова, нарисованный текст стирается. Однако,
можно задать принудительную очистку окна в ответ на команду
меню или какое-либо другое действие пользователя, например,
щелчок кнопкой "мыши".

     Чтобы очистить  окно  в ответ на щелчок правой кнопкой
"мыши", переопределите метод WMRButtonDown и вызовите в нем
процедуру  InvalidateRect,  которая  приводит  к повторному
отображению всего окна.  Так как  ваша  программа  пока  не
знает, как повторно вывести изображение, она просто очистит
область клиента:

Procedure TStepWindow.WMRButtonDown(var Msg: TMessage);
begin
   InvelidateRect(HWindow, nil, Trut);
end;

Текущий исходный код вы можете найти в файле STEP02.PAS.


             Шаг 3: Изображение линий в окне
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                 ЪДДДДДДДДДДДДДДДДДДДДДДДї
                 і Step 1: Basic App     і
                 і Step 2: Tex           і
                 іЫStepЫ3:ЫLinesЫЫЫЫЫЫЫЫЫі
                 і Step 4: Menu          і
                 і Step 5: About Box     і
                 і Step 6: Pens          і
                 і Step 7: Painting      і
                 і Step 8: Streams       і
                 і Step 9: Printing      і
                 і Step 10: Palette      і
                 і Step 11: BWCC         і
                 і Step 12: Custom ctrls і
                 АДДДДДДДДДДДДДДДДДДДДДДДЩ

     Теперь, когда вы познакомились со  схемой  отображения
(получение  контекста  дисплея,  отображение,  освобождение
контекста дисплея),  ее можно использовать в  более  полном
интерактивном  графическом приложении.  Следующие несколько
шагов посвящены построению простой  графической  программы,
позволяющей пользователю рисовать в основном окне.

     На шаге 3 мы добавим следующее поведение:

     * Щелчок  левой  кнопкой "мыши" и буксировка соединяют
       начальную и конечную точки  отображая  в  результате
       линию.

     * Щелчок правой кнопкой "мыши" выводит диалоговое окно
       ввода,  позволяющее  пользователю  изменить  толщину
       линии.

     Чтобы выполнить   эти   шаги,   изучим  сначала  схему
буксировки Windows,  а затем реализуем простую  графическую
программу.

                          Буксировка линии
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Мы уже видели,  что щелчок левой кнопкой "мыши" дает в
результате   сообщение   wm_LButtonDown  и  вызывает  метод
WMLButtonDown.  В шаге 1 ваша программа отвечала на  щелчки
левой кнопкой "мыши", выводя окна сообщений. Вы могли также
видеть, что щелчок правой кнопкой "мыши" давал в результате
сообщение wm_RButtonDown и вызывал метод WMRButtonDown.  На
нажатие правой кнопки "мыши"  программа  отвечала  очисткой
окна.

     Но это   предусматривает   реакцию  только  на  щелчки
кнопкой  "мыши".  Многие  программы  Windows   требуют   от
пользователя   нажатия   кнопки  "мыши"  и  перемещения  ее
указателя по экрану (буксировка).  При этом рисуются  линии
или прямоугольники, либо графическое изображение помещается
в  точку   с   конкретными   координатами.   Для   программ
графического   отображения   желателен   перехват   событий
буксировки и реакция на них путем изображения линий.


                       Сообщения wm_MouseMove
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Сделать это  можно  путем  реакции  еще  на  несколько
сообщений.  Когда  пользователь  буксирует  "мышь"  в новую
точку окна,  Windows  посылает  сообщение  wm_MouseMove,  а
когда   пользователь   отпускает   левую  кнопку  "мыши"  -
сообщение wm_LButtonUp. Обычно окно получает одно сообщение
wm_LButtonDown,   за   которым  следует  последовательность
сообщений wm_MouseMove (по одному на  каждую  промежуточную
точку буксировки) и одно сообщение wm_LButtonUp.

     Типичная графическая  программа  Windows  реагирует на
сообщение wm_LButtonDown инициализацией процесса  рисования
(получая,   кроме  всего  прочего,  контекст  дисплея).  На
сообщение wm_LButtonUp она реагирует  завершением  процесса
рисования (освобождая контекст дисплея).


                  Реакция на сообщения буксировки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Нужно помнить  о том,  что после wm_LButtonDown всегда
следует   сообщение    wm_LButtonUp    (с    промежуточными
сообщениями  wm_MouseMove  или  без  них).  Таким  образом,
каждый раз,  когда вы получаете контекст дисплея, вы можете
позднее освободить его.

     Для правильного   функционирования  программы  Windows
очень важным является освобождение каждого получаемого вами
контекста дисплея. Однако вы можете добавить еще одно более
надежное средство. Определите в TStepWindow новое булевское
поле  - тип основного окна с именем ButtonDown и обеспечьте
его инициализацию в TStepWindow.Unit значением False. Затем
вы   можете  проверять  перед  получением  и  освобождением
контекста дисплея значение ButtonDown.

     Приведем три метода обработки буксировки "мыши":

procedure TStepWindow.WMLButtonDown(var Msg: TMessage);
begin
   InvalidateRect(HWindow, nil, True);
   if not ButtonDown then
   begin
      ButtonDown := True;
      SetCapture(HWindow);
      DragDC := GetDC(HWindow);
      MoveTo(DragDC, Msg.lParamLo, Msg.lParamHi);
   end;
end;

procedure TStepWindow.WMMouseMove(var Msg: TMessage);
begin
   if ButtonDown then
         LineTo(DragDC, Msg.lParamLo, MsglParamHi);
end;

procedure TStepWindow.WMLButtonUp(var Msg: TMessage);
begin
  if ButtonDown then
  begin
     ButtonDown := False;
     ReleaseCapture;
     ReleaseDC(HWindow, DragDC);
  end;
end;



                Изображение точек и линий
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В API  Windows  имеются  графические  функции MoveTo и
LineTo, которые, соответственно, перемещают текущую позицию
рисования и рисуют линию до текущей позиции. Для правильной
работы  функций  требуется  указание  описателя   контекста
дисплея  DragDC.  Нужно  помнить  о том,  что вы рисуете не
непосредственно в окне, а в его контексте дисплея.


                          Перехват "мыши"
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Передачу Windows       соответствующих       сообщений
wm_MouseMove     обеспечивают    функции    SetCapture    и
ReleaseCapture.  Например,  если вы  буксируете  "мышь"  за
пределы  окна,  Windows  все равно будет посылать сообщения
основному,  а не смежному с ним окну, в которое она попала.
Перехват  "мыши" обеспечивает также поступление в ваше окно
сообщения от "мыши",  так что оно будет знать о прекращении
рисования даже если "мышь" перемещается в другом окне.

     Нужно изменить  определение  объекта для TStepWindow с
заголовками метода для WMMouseMove и WMLButtonUp:

procedure WMLButtonUp(var Msg: TMessage); virtual wm_First +
            wm_LButtonUp;
procedure WMLMouseMove(var Msg: TMessage); virtual wm_First+
            wm_LMouseMove;

     Пример полученного  исходного  кода вы найдете в файле
STEP03A.PAS.


                       Изменение размера пера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     До сих пор вы  могли  рисовать  только  тонкие  черные
линии.  Однако  графические программы традиционно позволяют
изменять толщину изображаемых линий.  При этом вы изменяете
на   самом   деле   не   толщину   линии,  а  размер  пера,
используемого для ее вычерчивания.  Перья, также как кисти,
шрифты и палитры,  представляют собой встроенные в контекст
дисплея  изобразительные  средства.  На  данном   шаге   вы
узнаете,   как   установить   в   контексте  дисплея  новые
изобразительные   средства,   что   даст   программе   Step
возможность рисовать линии другой толщины.

     Для реализации  механизма выбора пользователем размера
пера мы используем диалоговое окно (типа TInputDialog). Это
окно вида:

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫStepsЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і                                                         і
і Введите новую толщину линии:                            і
і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї        і
і іІ1І                                           і        і
і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ        і
і         ЪДДДДДДДДДДДї      ЪДДДДДДДДДДДї                і
і         і±±±±OK±±±±±і      і±±Cancel±±±і                і
і         АДДДДДДДДДДДЩ      АДДДДДДДДДДДЩ                і
і                                                         і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

Рис. 2.2  Задание новой толщины линии с помощью диалогового
окна ввода.


                     Отслеживание размера пера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы изменить толщину изображаемых линий,  вам  нужно
получить  сначала  несколько более глубокое представление о
графике Windows и о контексте в частности.

                    Изобразительные средства

     Для получения  графики  и  текста   в   окне   Windows
использует несколько изобразительных средств:  перья, кисти
и шрифты.  Эти изобразительные средства представляют  собой
элементы,  хранимые  в  памяти Windows и не отличающиеся от
видимых элементов экрана,  таких  как  окна  и  управляющие
элементы. Ваша программа может обращаться к изобразительным
средствам с помощью  описателей  (как  это  имеет  место  в
случае  окон).  Так  как  ObjectWindows  не  использует для
представления  изобразительных   средств   объекты,   вашим
программам  не  нужно  создавать  их  и  удалять  из памяти
Windows при завершении работы с ними.

           Примечание: В  шаге  6   мы   создадим   объект,
      инкапсулирующий   одно  инструментальное  средство  -
      перо.

     Изобразительное средство можно рассматривать как кисть
художника, а контекст дисплея - как холст. Художник сначала
создает  изобразительные  средства   (кисти)   и   получает
контекст   дисплея   (холст).   Затем   художник   выбирает
соответствующее  изобразительное  средство,   используя   в
каждый момент одну из кистей. Аналогично, программа Windows
должна  выбирать  изобразительные  средства   в   контексте
дисплея.

       Используемые по умолчанию изобразительные средства

     Итак, как  же  сделать,  чтобы  могли рисовать в своих
окнах текста и линии,  не выбирая  никаких  изобразительных
средств?    Все    контексты   дисплея   снабжены   набором
используемых по умолчанию  средств:  тонким  черным  пером,
твердой  черной кистью и системным шрифтом.  На данном шаге
мы выберем для рисования в окне другое, более тонкое перо.


                   Получение пера нового размера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Сначала нужно обеспечить способ выбора нового  размера
пера.  В  простейшем  случае  это  можно  сделать с помощью
диалогового окна ввода  модуля  OStdDlgs.  Добавьте  модуль
OStdDlgs  в  оператор  uses  программы.  Чтобы использовать
совместимые с Windows функции работы со  строками,  укажите
также  модуль  Strings.  Начало  программного  файла должно
выглядеть таким образом:

program Steps;

uses Strings, WinTypes, WinProcs, OWindow, OStdDlgs;
  .
  .
  .

           Выполнение диалогового окна ввода

     Диалоговое окно  ввода  - это простое диалоговое окно,
которое  выводит  подсказку  и  возвращает  одну  введенную
строку  текста.  Вы можете использовать его без модификации
TInputDialog или других методов.

     Щелчок правой  кнопкой  "мыши"  дает  удобный   способ
вывода   параметра  для  изменения  толщины  пера.  Давайте
переопределим  метод  WMRButtonDown   для   вывода   нового
диалогового окна ввода.

     Так как  диалоговое  окно  ввода  появляется только на
короткое время,  а вся обработка выполняется одним методом,
вам нет необходимости определять его как поле TStepWindows.
Оно может существовать в виде локальной  переменной  метода
WMRButtonDown.  Все построение и отмену объекта диалогового
окна вы можете выполнять в рамках метода WMRButtonDowm.

     Когда Init построит объект диалогового окна ввода,  вы
можете  выполнить его как режимное диалоговое окно,  вызвав
ExecDialog.  ExecDialog  проверяет  успешность   выполнения
конструктора   Init  и  создает  объект  диалогового  окна,
соответствующий элементу экрана,  выполняя затем диалоговое
окно.  Обработка  для  ExecDialog  завершается только после
того как пользователь закрыл  диалог,  щелкнув  "мышью"  на
командной кнопке OK (Подтверждение) или Cancel (Отмена).

     Если пользователь  щелкнул "мышью" на командной кнопке
OK,  InputText  заполняется  полученным   от   пользователя
текстом,  вызывая метод GetText из TInputDialog. Так как вы
запрашиваете  номер  толщины,  возвращаемый   текст   нужно
преобразовать  в  число и передать его в вызове SetPenSize.
Таким образом,  каждый  раз,  когда  пользователь  выбирает
новую  толщину  линии,  старое  перо  удаляется и создается
новое.

procedure TStepWindow.WMLButtonDown(var Msg: TMessage);
var
   InputText: array[0..9] of Char;
   NewSize, ErrorPos: Integer;
begin
   if not ButtonDown then
   begin
      Str(PenSize, InputText);
      if Application^.ExecDialog(New(PInputDialog,
          Init(@Self, 'Толщина линии',
          'Введите новую толщину:', InputText,
          SizeOf(InputText))) = id_Ok then
   begin
      Val(InputText, NewSize, ErrorPos);
      if ErrorPos = 0 then SetPenSize(NewSize);
   end;
end;
end.

               Добавление полей объекта

     Далее добавим  в  TStepWindow  новое поле для хранения
описателя  пера,  которое  вы   будете   использовать   для
рисования  графики.  В  данной  программе  в  каждый момент
времени вы можете рисовать и выводить на экран линии только
одной толщины. Соответствующее этой толщине перо хранится в
новом поле TStepWindow с именем ThePen.  Вы напишете  также
метод SetPenSize,  создающий новое перо и удаляющий старое.
Теперь  описание   объекта   TStepWindow   должно   принять
следующий вид:

type
  PStepWindow = ^TStepWindow;
  TStepWindow = object(TWindow)
    DragDC: HDC;
    ButtonDown, HasChanged: Boolean;
    ThePen: HPen;
    PenSize: Integer;
    constructor Init(AParent: PWindowsObject;
                      ATitle: PChar);
    destructor Done; virtual;
    function CanClopse: Boolean: virtual;
    procedure WMLButtonDown(var Msg: TMessage); virtual
                wm_First + wm_LButtonDown;
    procedure WMLButtonUp(var Msg: TMessage); virtual
                wm_First + wm_LButtonUp;
    procedure WMMouseMove(var Msg: TMessage); virtual
                wm_First + wm_LMouseMove;
    procedure WMRButtonDown(var Msg: TMessage); virtual
                wm_First + wm_RButtonDown;
    procedure SetPenSize(NewSize: Integer); virtual;
end;

                  Инициализация полей

     Чтобы инициализировать    новые    поля,   вам   нужно
модифицировать  конструктор  Init  для  установки  пера   и
переопределить деструктор Done для его отмены.  Не забудьте
вызвать в новых методах наследуемые методы:

     constructor TStepWindow.Init(AParent: PWindowsObject;
                   ATitle: PChar);
     begin
        Inherited Init(AParent, ATitle);
        ButtonDown := False;
        HasChanged := False;
        PenSize := 1;
        ThePen := CreatePen(ps_Solid, Pensize, 0);
     end;

     destructor TStepWindow.Done;
     begin
       DeleteObject(ThePen);
       inherited Done;
     end;

                        Изображение линий

     Теперь изменим метод WMLButtonDown для выбора текущего
пера   (ThePen)  во  вновь  полученном  контексте  дисплея.
Аналогично  MoveTo  и  MessageBox,  SelectObject   является
функцией API Windows.

procedure TStepWindow.WMLButtonDown(var Msg: TMessage);
begin
   if not ButtonDown then
   begin
       ButtonDown := True;
       SetCapture"(HWindow);
       DragDC := GetDC(HWindow);
       SelectObject(DragDC, ThePen);
       MoveTo(DragDC, Msg.lParamLo, Msg.lParamHi);
   end;
end;

     Указанные методы  выбирают  в  контексте  дисплея  уже
созданное перо.  Однако для создания  пера  нужно  написать
следующий вызываемый WMRButtonDown метод SetPenSize:

     procedure TStepWindow.SetPenSize(NewSize: Integer);
     begin
        DeleteObject(ThePen);
        ThePen := Create(ps_Solid, NewSize, 0);
        PenSize := NewSize;
     end;

     Вызов функции Windows CreatePen - это один из способов
создания  пера  Windows  заданной  толщины.  Описатель пера
записывается в ThePen. Очень важным шагом является удаление
старого  пера.  Отсутствие такого шага приведет к неверному
использованию памяти Windows.

     На шаге 5 и 6 вы создадите собственное диалоговое окно
и  объект  пера  и  используете  их  для более эффективного
графического отображения.




                 Глава 3. Меню и диалоговые ресурсы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Большинство приложений Windows имеют в своих  основных
окнах меню,  которые предоставляют пользователю возможность
выбора - например,  команды FileіSave,  FileіOpen и Help. В
шаге  4  мы  добавим  в  программу Steps строку меню.  Ввод
пользователем  данных  и  выбор  параметров  в   программах
Windows  часто  происходит в диалоговых блоках.  В шаге 5 в
программу Steps будет добавлен диалоговый блок.

     Меню и  диалоговые  блоки  объединены  общим  понятием
ресурсов.  Ресурсы  -  это  данные,  хранимые в выполняемом
файле,  который  описывает  пользовательские   интерфейсные
элементы    приложений    Windows.   Ресурс   не   содержит
фактического меню или диалогового блока.  Вместо  этого  он
содержит  информацию,  необходимую  программе  для создания
конкретного диалогового блока или меню.

     Ресурсы для программы проще всего создавать с  помощью
редакторов  ресурсов,  таких  как  Resource Workshop (пакет
разработчика ресурсов) фирмы Borland. Подробно о создании и
редактировании   ресурсов   рассказывается  в  "Руководстве
пользователя по пакету разработчика ресурсов".


                   Шаг 4: Добавление строки меню
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                    ЪДДДДДДДДДДДДДДДДДДДДДДДї
                    і Step 1: Basic App     і
                    і Step 2: Text          і
                    і Step 3: Lines         і
                    іЫStepЫ4:ЫMenuЫЫЫЫЫЫЫЫЫЫі
                    і Step 5: About Box     і
                    і Step 6: Pens          і
                    і Step 7: Painting      і
                    і Step 8: Streams       і
                    і Step 9: Printing      і
                    і Step 10: Palette      і
                    і Step 11: BWCC         і
                    і Step 12: Custom ctrls і
                    АДДДДДДДДДДДДДДДДДДДДДДДЩ

     В оконной  среде  выбор пункта меню относится к той же
категории,  что и щелчок кнопкой "мыши".  И то,  и другое -
это  пользовательские  события.  Ответ на выбор пункта меню
аналогичен реакции на другие  пользовательские  события.  В
данном разделе описываются шаги, необходимые для добавления
в приложение меню.

     * Проектирование меню как ресурса меню.

     * Определение констант меню во включаемом файле.

     * Загрузка файла ресурса из программы.

     * Загрузка ресурса меню в объект основного окна.

     * Определение реакции на выбор в меню.

     Меню прикладной программы - это не отдельный объект, а
атрибут  основного  окна.  Все  оконные объекты имеют набор
атрибутов,  записанных в поле записи Attr объекта.  В  поле
Menu записи Attr хранится не описатель меню,  а меню. Чтобы
установить   атрибут   меню,   вы   должны   переопределить
конструктор своего типа окна TStepWindow.


                            Ресурсы меню
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Определение ресурсов меню не является частью исходного
кода программы.  Вместо этого существует  ресурс,  содержит
текст  пунктов меню и структуру элементов верхнего уровня и
их подсистем.  Для проектирования меню и  других  ресурсов,
таких как диалоговые блоки,  пиктограммы и битовые массивы,
вы можете использовать пакет разработчика ресурсов Resource
Workshop.

               Определение идентификаторов ресурса

     Приложение обращается к присоединенным к нему ресурсам
по идентификатору ресурса.  Этот идентификатор представляет
собой  целое  значение,  например,  100,  или целочисленную
константу,  такую  как  MyMenu.  Кроме   того,   приложение
отличает  один  выбор  меню  от  другого по идентификатору,
связанному с элементом меню.

                    Определение констант меню

     Чтобы сделать  программу  более   читаемой,   замените
идентификаторы    меню    константами,   определяемыми   во
включаемом  файле.  При  создании  своего  ресурса  меню  с
помощью  Resource  Workshop  или  компилятора  ресурсов  вы
можете включить  те  же  константы  и  использовать  те  же
идентификаторы,   которые  вы  используете  для  доступа  к
ресурсу к своей программе.  Константы  меню  для  программы
Steps определены в файле STEPS.INC:

     const
        cm_FilePrint  = 105;
        cm_FileSetup  = 107;
        cm_Pen        = 200;
        cm_About      = 201;
        cm_PalShow    = 301;
        cm_PalHide    = 302;

     Заметим, что число элементов меню в файле STEPS.INC не
определено.  Это связано с тем,  что ObjectWindows в  файле
IWINDOWS.INC  определяет  для  вас  некоторые общие команды
меню,  включая  cm_FileOpen,  cm_FileNew,   cm_FileSave   и
cm_FileSaveAs.

                    Включение файлов ресурсов

     Чтобы продолжить    работу    с    программой   Steps,
используйте  пакет  разработчика  ресурсов  или  компилятор
ресурсов  для создания ресурса меню и сохраните его в файле
с расширением .RES -  STEPS.RES.  Формат  файла  ресурса  в
исходном  виде  вы  можете посмотреть в файле STEPS.RC.  Вы
можете также использовать  файл  STEPS.RES,  который  можно
найти  на  дистрибутивных дисках.  Имея файл STEPS.RES,  вы
можете включить его с помощью директивы компилятора $R:

     {$R STEPS.RES}

     Директива компилятора  $R   в   конце   компиляции   и
компоновки  автоматически добавляет заданный файл ресурса к
выполняемому файлу.  Ресурсы можно добавить или удалить  из
выполняемых    файлов,   а   существующие   ресурсы   можно
модифицировать.

           Примечание: О    модификации    ресурсов,    уже
      скомпонованных с выполняемыми файлами, рассказывается
      в "Руководстве пользователя  по  пакету  разработчика
      ресурсов".


     На Рис.   3.1   показан   внешний   вид   этого   меню
(идентификатор  ресурса  100).  Оно  включает в себя пункты
File (Файл),  Options (Параметры) и  Palette  (Палитра),  а
меню  File содержит элементы New (Новый),  Open (Открытие),
Save (Сохранение),  Save As (Сохранение под именем),  Print
(Печать),   Printer   Setup  (Установка  принтера)  и  Exit
(Выход).  Элементы  верхнего   уровня,   у   которых   есть
подэлементы,  не имеют идентификаторов меню,  а их вывод не
вызывает никаких действий кроме вывода подэлементов.

           Примечание: Не  путайте  идентификатор   ресурса
      меню  с  идентификаторами  меню  отдельных  элементов
      (пунктов) меню.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫStepsЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
іЫFileЫ Options Palette                                 і
ГДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іЫNewЫЫЫЫЫЫЫЫЫЫЫЫЫЫі                                    і
і Open...          і                                    і
і Save             і                                    і
і Save as...       і                                    і
ГДДДДДДДДДДДДДДДДДДґ                                    і
і Print...         і                                    і
і Printer Setup... і                                    і
ГДДДДДДДДДДДДДДДДДДґ                                    і
і Exit             і                                    і
ГДДДДДДДДДДДДДДДДДДЩ                                    і
і                                                       і
і                                                       і
і                                                       і
і                                                       і
і                                                       і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 3.1 Программа Steps с ресурсом меню.


                       Загрузка ресурса меню
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Получить ресурс меню можно с  помощью  вызова  функции
Windows LoadMenu:

     LoadMenu(HInstance, MakeIntResource(100));

     MakeIntResource(100) приводит  число  100 к ссылочному
типу  PChar,  представляющему  собой  указатель  на  массив
символов.   Функции   Windows,  воспринимающие  в  качестве
аргументов строки, требуют, чтобы они имели тип PChar. Имея
дело с ресурсами,  Windows ожидает,  что целые числа должны
быть представлены в виде  PChar,  поэтому  если  вы  хотите
обратиться  к  ресурсу,  имеющему  числовой  идентификатор,
нужно преобразовать его тип с помощью MakeIntResource.

           Примечание: Для   использования    типа    PChar
      требуется установка $X+ (по умолчанию).

     В качестве альтернативы идентификатор меню может иметь
символьный идентификатор,  например,  'SAMPLE_MENU'. В этом
случае загрузить ресурс меню можно следующим образом:

     LoadMenu(HInstance, 'SAMPLE_MENU');

     Вот как  это  делает  TStepWindow.Init  (заметим,  что
первое,  что он  делает  -  это  вызов  конструктора  Init,
наследуемого  из  TWindow,  для  выполнения  инициализации,
необходимой для всех оконных объектов):

constructor TStepWindow(AParent: PWindowObject;
                                             ATitle: PChar);
begin
   inherited Init(AParent, ATitle);
   Attr.Menu := LoadMenu(HInstance, MakeIntResource(100));
   BottomDown := False;
   HasChanged := False;
end;

     Теперь при  выводе  основного  окна  оно имеет рабочее
меню,  показанное на Рис.  1.3.  Однако,  чтобы при  выборе
элементов  меню выполнялись какие-либо действия,  вы должны
перехватывать сообщения меню и реагировать на них.  Если вы
не  определили реакцию на команду меню,  то можете выбирать
элемент меню, но при этом ничего не происходит.


                      Перехват сообщений меню
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда пользователь  выбирает  элемент  меню,  окно,  к
которому  присоединено  меню,  получает командное сообщение
Windows.  ObjectWindows обрабатывает и  диспетчеризует  эти
сообщения   wm_Command  аналогично  другим  сообщениям,  но
облегчает для вас работу со специальными командами.

     Одним из параметров сообщения wm_Command является сама
команда   (номер,   соответствующий   идентификатору   меню
выбранного элемента).  Вместо  вызова  метода  WMCommand  и
возложения  на  вас решения,  что делать с каждой возможной
командой,  ObjectWindows вызывает основанные на  конкретных
командах методы.  Чтобы обработать эти сообщения, вы можете
определить  методы   для   объектного   типа   TStepWindow,
используя специальное расширение:

     procedure CMFileNew(var Msg: TMessage);
          virtual cm_First + cm_FileNew;

где cm_First - это  константа  ObjectWindows,  определяющая
начало  диапазона  констант для команд,  а cm_FileNew - это
желаемая команда меню.  Это означает, что все элементы меню
должны  иметь  уникальные  идентификаторы  (если  только не
предполагается реагировать на них одинаковым образом).

           Примечание: О диапазонах сообщений  и  смещениях
      рассказывается в Главе 16.

     Не путайте  основанный на cm_First динамический индекс
метода с индексом,  соответствующим поступающему  сообщению
Windows   (основанному   на   wm_First).   cm_First  -  это
специальное смещение,  используемое только для  определения
методов реакции для команд меню и командных клавиш.


               Определение методов реакции на команду
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Теперь вы  можете  определить  все  методы  реакции на
команды:

     procedure CMFileNew(var Msg: TMessage);
         virtual cm_First + cm_FileNew;
     procedure CMFileOpen(var Msg: TMessage);
         virtual cm_First + cm_FileOpen;
     procedure CMFileSave(var Msg: TMessage);
         virtual cm_First + cm_FileSave;
     procedure CMFileSaveAs(var Msg: TMessage);
         virtual cm_First + cm_FileSaveAs;
     procedure CMFilePrint(var Msg: TMessage);
         virtual cm_First + cm_FilePrint;
     procedure CMFileSetup(var Msg: TMessage);
         virtual cm_First + cm_FileSetup;

     Определять процедуру  CMExit  не требуется,  поскольку
TWindowsObject   уже   определяет   завершающую   программу
процедуру,  которая  вызывается  при поступлении в основное
окно сообщения cm_Exit.

                   Связывание клавиш с командами
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Методы реакции  на команды не связываются с конкретным
элементом  меню  -  они  привязаны  к  конкретной  команде.
Объекту  не  важно,  откуда  поступила  команда.  Он  знает
только,  что что-то  вызвало  данное  командное  сообщение.
Таким  образом,  у  вас  есть  несколько способов генерации
команды.  Обычно для этого применяются оперативные клавиши,
называемые командными клавишами.

     Командные клавиши  определяются  в ресурсах аналогично
меню,  но они намного проще. Ресурс командной клавиши - это
таблица нажатий клавиш и команд,  которые они генерируют. О
создании ресурсов для  командных  клавиш  рассказывается  в
"Руководстве пользователя по пакету разработчика ресурсов".

     Каждая прикладная  программа  может  иметь только один
набор командных клавиш.  Чтобы загрузить в программу ресурс
командных клавиш, переопределите метод InitInstance:

procedure TMyApplication.InitInstance;
begin
  inherited InitInstance;
  HaccTable := LoadAccelerators(HInstance, 'ShortCuts');
end;

     Командные клавиши  'ShortCuts'  в  STEPS.RES связывают
знакомые вам по IDE функциональные клавиши  с  аналогичными
функциями программы Steps.  Например, клавиша F3 генерирует
команду cm_FileOpen.


                      Реакция на команды меню
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Теперь для каждого выбора в меню  у  вас  есть  метод,
который   будет   вызываться  в  ответ  на  соответствующую
команду.  Выбор  команды  FileіPrint  вызывает  ваш   метод
CMFilePrint. Пока вызовем просто окно сообщения:

     procedure TStepWindow.CMFilePrint(var sg: TMessage);
     begin
       Message(HWindow, 'Средство не реализовано',
               'Печать файла', mb_Ok);
     end;

     На Рис.  3.2 показана реакция программы Steps на выбор
команды FileіPrint.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫStepsЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і File  Options Palette                                 і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і                                                       і
і                                                       і
і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї      і
і іІ=І±±±±±±±±±±±±±±Печать файла±±±±±±±±±±±±±±±±±і      і
і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ      і
і і                                              і      і
і і       Средство не реализовано                і      і
і і                                              і      і
і і                ЪДДДДДДДДДДДї                 і      і
і і                і±±±±OK±±±±±і                 і      і
і і                АДДДДДДДДДДДЩ                 і      і
і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ      і
і                                                       і
і                                                       і
і                                                       і
і                                                       і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД-Щ

     Рис. 3.2   Программа   Steps   реагирует   на  команду
FileіPrint.

     Для CMFileOpen, CMFileSave, CMFileSaveAs и CMFileSetup
напишите фиктивные методы, аналогичные CMFilePrint. Позднее
вы перепишете  данные  методы  для  выполнения  осмысленных
действий.

     Теперь, очистив  окно,  вы можете реагировать на выбор
команды меню FileіNew более  интересным  образом.  Добавьте
следующий метод CMFileNew:

procedure TStepWindow.CMFileNew(var Msg: TMessage);
begin
   InvalidateRect(HWindow, nil, True);
end;

     InvalidateRect выполняет   принудительное    повторное
отображение  окна.  Полный исходный код программы Steps для
данного этапа содержится в файле STEP04A.PAS.


                    Добавление диалогового блока
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Диалоговый блок  аналогичен  всплывающему   окну,   но
обычно  оно  сохраняется  на  экране  в  течении  короткого
периода и выполняет одну  конкретную  задачу,  связанную  с
вводом-выводом,  такую  как  выбор  принтера  или настройка
страницы документа.  Здесь мы  добавим  в  программу  Steps
диалоговое окно для открытия и сохранения файлов.

     Файловое диалоговое окно,  как одно из диалоговых окон
ObjectWindows,  определено с  типом  TFileDialog.  Файловое
диалоговое  окно  полезно  использовать  в  любой ситуации,
когда вы  запрашиваете  у  пользователя  для  сохранения  и
загрузки выбор файла на диске.  Например,  редактор текстов
может  использовать  диалоговое   окно   для   открытия   и
сохранения документов.


     Вы будете выводить файловое диалоговое окно в ответ на
выбор  пользователем  команды  FileіOpen  или FileіSave As.
Файловое диалоговое окно заменяет окно сообщения  "Средство
не  реализовано".  В  шаге  8  оно  будет приспособлено для
некоторых реальных файлов, а также сохранения и открытия их
для  записи  и  считывания  реальных  данных.  Пока  просто
выведем диалоговые окна.  Вид  файлового  диалогового  окна
показан на Рис. 3.3.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫStepsЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і File  Options Palette                                 і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї     і
і  іІ=І±±±±±±±±±±±±±±Открытие файла±±±±±±±±±±±±±±±і     і
і  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ     і
і  і            ЪДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДїі     і
і  і Имя файла: і *.pts            і  і±±±±OK±±±±іі     і
і  і            АДДДДДДДДДДДДДДДДДДЩ  АДДДДДДДДДДЩі     і
і  і                                  ЪДДДДДДДДДДїі     і
і  і Каталог: a:\                     і±±Cancel±±іі     і
і  і                                  АДДДДДДДДДДЩі     і
і  і Файлы:             Каталоги:                 і     і
і  і ЪДДДДДДДДДДДДДДДДї ЪДДДДДДДДДДДДДВДї         і     і
і  і і                і і[-a]         і^і         і     і
і  і і                і і[-b]         ГДґ         і     і
і  і і                і і[-c]         і±і         і     і
і  і і                і і[-d]         і±і         і     і
і  і і                і і[-e]         і±і         і     і
і  і і                і і[-f]         і±і         і     і
і  і і                і і[-g]         і±і         і     і
і  і і                і і[-h]         ГДґ         і     і
і  і і                і і[-i]         іvі         і     і
і  і АДДДДДДДДДДДДДДДДЩ АДДДДДДДДДДДДДБДЩ         і     і
і  АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ     і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 3.3 Программа  Steps  с  диалоговым  блоком  File
Open.

     Добавление к  программе  Steps  файлового  диалогового
блока требует трех шагов:

     * Добавление поля объекта, содержащего имя файла.
     * Модификация  конструктора  объекта для инициализации
     файла.
     * Выполнение диалогового блока.



                      Добавление поля объекта
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вместо хранения всего  объекта  файлового  диалогового
окна  в  виде  поля  его  порождающего  окна,  вам  следует
построить новый объект файлового диалогового окна, когда он
потребуется.  Вместо  данных,  которые  вам следует хранить
вместо данных этого диалогового окна,  вы должны  сохранять
имя  и  маску  файла.  На  практике  хорошо  придерживаться
следующего:  вместо хранения  всех  объектов,  которые  вам
могут не потребоваться,  храните просто данные, необходимые
для инициализации объектов, когда они потребуются.

     Построение файлового диалогового  блока  требует  трех
параметров:  порождающего  окна,  шаблона ресурса и имя или
маску файла (в зависимости от того,  используется  файловое
окно  для  открытия  или  закрытия  файла).  Шаблон ресурса
определяет,  какое из стандартных файловых диалоговых  окон
вы  хотите  использовать.  Стандартные  файловые диалоговые
ресурсы определяются идентификаторами ресурсов  sd_FileOpen
и   sd_FileSave.  Параметр  имени  файла  используется  для
передачи используемой  по  умолчанию  маски  файла  диалогу
открытия  файла  (а  также  для  возврата  выбранного имени
файла) и для передачи используемого по умолчанию имени  для
сохранения файла.

     Параметр шаблона ресурса определяет, будет ли файловый
диалоговый  блок  использоваться  для  открытия   или   для
сохранения файла.  Если диалоговый ресурс имеет блок списка
файлов с идентификатором  управляющего  элемента  id_FList,
диалоговый   блок   используется   для   открытия   файлов;
отсутствие такого блока списка указывает на диалоговое окно
для сохранения файлов.

     Определение типа  TStepsWindow должно теперь выглядеть
следующим образом:

     TStepWindow = object(TWindow)
        .
        .
        .
       FileName: array[0...fsPathName] of Char;
        .
        .
        .

            Примечание: Для  работы с константой fsPathName
      нужно использовать модуль WinDos.

                    Модификация конструктора

     Для создания экземпляра объекта  справочного  окна  вы
можете  использовать  конструктор  Init  типа  TStepWindow.
Теперь  вам   потребуется   добавить   к   нему   код   для
инициализации FileName:

     StrCopy(FileName, '*.PTS');

     Расширение .PTS  используется  для файлов,  содержащих
точки вашего графического изображения.

                  Выполнение диалогового блока

     В зависимости от переданного конструктору  диалогового
блока  параметра  шаблона  ресурса  диалоговый  блок  может
поддерживать  открытие   или   сохранение   файла.   Каждый
параметр,   при   создании  диалогового  блока,  аналогичен
показанному на  Рис.  3.3.  Между  диалогами  открытия  или
закрытия   файла  имеются  два  различия:  диалог  открытия
содержит список файлов в текущем каталоге,  соответствующий
текущей   маске  файла,  а  в  диалоге  сохранения  в  поле
редактирования управляющего диалогового элемента  выводится
имя текущего файла, но список файлов отсутствует.

     CMFileOpen и CMFileSaveAs следует переписать следующим
образом:

procedure TStepWindow.CMFileOpen(var Msg: TMessage);
begin
   if Application^.ExecDialog(New(PFileDialog,
      Init(@Self, PChar(sd_FileOpen), FileName))) = id_Ok
   then MessageBox(HWindow, FileName, 'Открыть файл:',
        mb_Ok);
end;

procedure TStepWindow.CMFileSaveAs(var Msg: TMessage);
begin
   if Application^.ExecDialog(New(PFileDialog,
      Init(@Self, PChar(sd_FileSave), FileName))) = id_Ok
   then MessageBox(HWindow, FileName, 'Сохранить файл:',
        mb_Ok);
end;

     Заметим, что при выполнении файлового диалогового окна
используется  тот же метод ExecDialog,  который вы вызывали
для выполнения диалогового окна ввода в шаге 3.  С  помощью
метода  ExecDialog выполняются все режимные диалоговые окна
в приложении.

     Полный исходный код программы Steps для  данного  шага
вы можете найти в файле STEP04B.PAS.



                Шаг 5: Добавление диалогового блока
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                    ЪДДДДДДДДДДДДДДДДДДДДДДДї
                    і Step 1: Basic App     і
                    і Step 2: Text          і
                    і Step 3: Lines         і
                    і Step 4: Menu          і
                    іЫStepЫ5:ЫAboutЫBoxЫЫЫЫЫі
                    і Step 6: Pens          і
                    і Step 7: Painting      і
                    і Step 8: Streams       і
                    і Step 9: Printing      і
                    і Step 10: Palette      і
                    і Step 11: BWCC         і
                    і Step 12: Custom ctrls і
                    АДДДДДДДДДДДДДДДДДДДДДДДЩ

     До сих  пор в программе Steps использовались два очень
простых  диалоговых  блока:  окно   сообщений   (в   методе
CanClose)  и  диалоговый  блок  ввода для изменения размера
пера.  Эти диалоговые блоки удобно  применять  для  простых
задач,  но  в  программах  обычно требуются более сложные и
ориентированные на задачу взаимодействия с пользователем. В
таких  случаях вы можете разработать собственные диалоговые
блоки.

     Как и  меню,  диалоговые  блоки  обычно  создаются  из
описания,  сохраненного  в ресурсе.  Для сложных диалоговых
блоков это значительно быстрее, чем индивидуальное создание
каждого элемента отдельного окна. Однако в отличие от меню,
поскольку программы должны взаимодействовать с  диалоговыми
окнами    более    разнообразными    и   сложными   путями,
ObjectWindows  использует  для  представления   диалогового
блока объект.

     Создание диалогового    блока   из   ресурса   требует
следующих шагов:

     * Создание ресурса диалогового блока.
     * Построение объекта диалогового блока.
     * Выполнение диалогового блока.

                Создание ресурсов диалогового блока
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Проектировать ресурсы    диалогового    блока    можно
несколькими способами, используя пакет разработчика ресурса
Resource Workshop или компилятор ресурсов.  Диалоговый блок
(блок диалога) -  это  специализированное  окно  с  рамкой,
содержащее  один или более управляющих элементов (командные
кнопки,  блоки  списка  и  пиктограммы).  Ваша   прикладная
программа не знает о том, как выглядят управляющие элементы
и  как  они  позиционированы;  она  знает  только  о   типе
управляющих элементах и их идентификаторах.

           Примечание: Не   забывайте,  что  ресурс  -  это
      просто некое описание того,  что будет создавать ваша
      программа.

                Идентификаторы управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Аналогично элементам   в    ресурсе    меню,    каждый
управляющий  элемент  в  ресурсе  диалогового  блока  имеет
идентификатор,  который прикладная программа использует для
определения  того,  с  каким  управляющим  элементом  нужно
взаимодействовать.  Для статических элементов,  с  которыми
ваша  прикладная  программа не взаимодействует (статический
текст или битовые  массивы)  уникальные  идентификаторы  не
требуются, поэтому они обычно имеют идентификатор -1.

     Обычно, если   вашей  прикладной  программе  требуется
доступ к конкретному управляющему элементу, вы присваиваете
ему  идентификатор-константу,  так что и ваша программа,  и
компилятор   ресурсов   могут   использовать   в   качестве
идентификатора   одно   и   то  же  символьное  имя.  Такие
идентификаторы-константы следует определять  во  включаемом
файле  или в модуле,  содержащем только описания-константы.
При  создании  или  редактировании  ваших  ресурсов   пакет
разработчика   ресурсов   автоматически   управляет  такими
файлами.

                Построение объекта диалогового блока
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     После того   как   ресурс   диалогового   окна   будет
определен,  ваша  программа  может  использовать  его   для
создания  и  выполнения диалогового окна.  Диалоговые блоки
выводятся  обычно  как   дочерние   окна   основного   окна
приложения,  но  они  создаются  несколько по-другому,  чем
обычные окна.

     Конструктор объекта  диалогового  блока  выглядит  как
конструктор оконного объекта, воспринимающий два параметра.
В обоих случаях первый параметр - это указатель  на  объект
порождающего   окна.  Второй  параметр  (PChar)  определяет
заголовок объекта  окна.  Однако  для  объекта  диалогового
блока в качестве шаблона диалогового блока используется имя
диалогового ресурса.

     Файл ресурса для программы Steps определяет диалоговый
блок с именем 'ABOUTBOX',  которое вы можете использовать в
качестве  окна  About  box,  показанного   на   Рис.   3.4.
Построение  объекта  диалогового  блока  из данного ресурса
выглядит следующим образом:

     New(PDialog, Init(@Self, 'ABOUTBOX'));

       ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
       і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫAbout StepsЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі
       ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
       і                                                 і
       і   ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї    і
       і   і                                        і    і
       і   і ІІІІ  ObjectWindows tutorial program   і    і
       і   і ІІІІ                                   і    і
       і   і       Copiright (C) 1992               і    і
       і   і       Borland International Inc.       і    і
       і   і       All Rights Reserved              і    і
       і   АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ    і
       і                                                 і
       і                    ЪДДДДДДДДДДДї                і
       і                    і±±±±OK±±±±±і                і
       і                    АДДДДДДДДДДДЩ                і
       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 3.4 Окно About Box для программы Steps.

                    Выполнение диалогового блока
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы выполнить  специализированный  диалоговый  блок,
используйте  тот  же  метод  ExecDialog,  который  вы   уже
использовали для других диалоговых блоков:

Application^.ExecDialog(New(PDialog,Init(@Self,'ABOUTBOX')
));

     Естественно, нужно   определить   команду  для  вывода
диалогового блока About  box;  Steps  использует  сообщение
cm_About,  генерируемое выбором меню OptrionsіAbout. Теперь
такой вид реакции на команду  должен  быть  вам  достаточно
знаком (см. файл STEP05.PAS):

     type
       TStepWindow = object(TWindow)
            .
            .
            .
         procedure CMAbout(var Msg: TMessage);
            virtual cm_First + cm_About;
     end;

     procedure TStepWindow.CMAbout(var Msg: TMessage);
     begin
        Application^.ExecDialog(New(PDialog, Init(@Self,
                                 'ABOUTBOX')));
     end;

     В шаге  6  мы создадим более сложное диалоговое окно с
несколькими управляющими элементами.


              Режимные и безрежимные диалоговые блоки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     После выполнения окна с помощью ExecDialog  диалоговый
блок  становится  режимным.  Это  означает,  что  программа
работает с этим блоком до его закрытия.  Пока  активно  это
окно, все получаемые программой сообщения поступают в него.
Такой диалоговый блок называется режимным окном приложения,
поскольку  оно  режимное только по отношению к выполняющему
его  приложению.  Существуют   также   системные   режимные
диалоговые   блоки,  которые  приостанавливают  всю  работу
приложения,  пока блок не будет закрыт.  Такие блоки и окна
используются  редко,  и  применять  их следует только в том
случае,  если при работе других приложений могут возникнуть
проблемы.

     Иногда желательно     получить     диалоговый    блок,
сохраняющийся при работе  других  частей  программы.  Такой
диалоговый  блок  работает  почти  как обычное окно,  но не
является режимным,  и потому носит название безрежимного. О
создании  безрежимных  диалоговых  блоков  рассказывается в
Главе 11 "Объекты диалоговых блоков".


                Глава 4. Работа с диалоговым блоком
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Теперь, когда вы оснастили программу  Steps  созданным
из    ресурса    диалоговым    блоком,    нужно   научиться
взаимодействовать с  этим  диалоговым  блоком.  Сначала  вы
создадите  объект,  инкапсулирующий все характеристики окна
пера,  затем используете диалоговый блок  для  установки  и
изменения этих характеристик.

     В данной главе описаны следующие шаги:

     * Определение объекта пера.

     * Создание сложного диалогового блока.

     * Добавление управляющих объектов.

     * Создание буфера передачи.

     * Выполнение диалогового блока.

     * Чтение результатов.


                  Шаг 6: Изменение атрибутов пера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                    ЪДДДДДДДДДДДДДДДДДДДДДДДї
                    і Step 1: Basic App     і
                    і Step 2: Text          і
                    і Step 3: Lines         і
                    і Step 4: Menu          і
                    і Step 5: About Box     і
                    іЫStepЫ6:ЫPensЫЫЫЫЫЫЫЫЫЫі
                    і Step 7: Painting      і
                    і Step 8: Streams       і
                    і Step 9: Printing      і
                    і Step 10: Palette      і
                    і Step 11: BWCC         і
                    і Step 12: Custom ctrls і
                    АДДДДДДДДДДДДДДДДДДДДДДДЩ

     Данный шаг    охватывает    ряд    тем,     касающихся
изобразительных средств Windows, особенно перьевых средств,
применяемых для изображения линий.  Перья Windows имеют три
отдельных атрибута: стиль, ширину и цвет.

     Первая часть  данного  шага  -  создание  объекта  для
представления пера не является  абсолютно  необходимой,  но
позволяет   вашему   окну   работать  с  пером  как  единой
сущностью,  а не отслеживать отдельно все атрибуты  перьев.
Инкапсулируя  перо,  вы можете также избежать необходимости
иметь   дело   с   некоторыми    повторяющимися    деталями
использования   инструментальных  средств  GDI,  аналогично
тому,  как объекты окон ObjectWindows предохраняют  вас  от
мелких деталей, связанных с созданием окна.

                       Создание объекта пера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Хотя Windows   ссылается   на   свои   изобразительные
средства как на "объекты" (отсюда и имена типа SelectObject
и DeleteObject),  они  не  являются  объектами  в  истинном
объектно-ориентированном  смысле,  так  как  не  используют
наследование и полиморфизм. Перо на самом деле представляет
собой  просто группу из трех характеристик отображения,  на
которые  Windows  ссылается  при  изображении  линии.   Эти
характеристики   являются   просто   свойствами   контекста
дисплея,  но полезно рассматривать  их,  как  встроенные  в
перо.

                       Характеристики пера

     Три характеристики  пера  -  это  его стиль,  размер и
цвет.  В шаге 3  вы  изменяли  размер  пера  и  отслеживали
текущий размер пера в поле объекта окна.  Вместо реализации
трех отдельных полей для отслеживания характеристик пера вы
можете  инкапсулировать  их в единый объект TPen.  Описание
TPen имеет следующий вид:

type
  PPen = ^TPen;
  TPen = object(TObject)
     Width, Style: Integer;
     Color: Longint;
     constructor Init(AStyle, AWidth: Integer;
                      AColor: Longint);
     constructor Load(var S: TStream);
     procedure ChangePen;
     procedure Delete;
     procedure Select(ADC: HDC);
     procedure SetAttributes(AStyle, AWidth: Integer;
                      AColor: Longint);
     procedure Store(var S: TStream);
private
   PenHandle, OldPen: HPen;
   TheDC: HDC;
   PenData: TPenData;
end;

      Примечание: Большую часть исходного  кода  из  данной
 главы  вы можете найти в файле PEN.PAS.  Для использования
 модуля  Pen  в  STEP06A.PAS  и  STEP06B.PAS  нужно  внести
 минимальные изменения.

      Примечание: Тип TPen определен в модуле Pen.

     Конструктор Init  создает новый объект пера с заданным
стилем,  размером и цветом. SetAttributes изменяет атрибуты
уже  созданного объекта пера.  ChangePen выводит диалоговое
окно, позволяющее пользователю задать атрибуты пера. Load и
Store позволяют сохранять объекты пера в потоке.

                 Выбор и удаление объектов пера

     Наиболее интересную  работу выполняют процедуры Select
и Delete.  Select создает изобразительное средство  Windows
на  основе  характеристик,  записанных  в  полях атрибутов.
Вместо того,  чтобы вызывать в  графической  программе  для
создания  пера,  получения  его  описателя,  выбора  пера в
контексте  дисплея,  использования  пера  и  его   удаления
функцию API Windows, вы строите объект пера, а затем можете
его использовать, выделять и удалять.

     Метод Delete  отменяет  описатель   пера,   освобождая
ресурс  для  Windows.  Select  проверяет,  имеется  ли  уже
выделенное  перо,  и  перед  созданием  и  выбором   нового
отменяет существующее перо.  Это полезно использовать, если
это же перо предполагается применять повторно,  так что вам
не  понадобиться  вызывать  Delete при каждом использовании
пера.  С другой стороны,  в шаге 7 вы  увидите,  как  можно
сохранять  нарисованные  линии,  и каждая линия будет иметь
свой собственный объект пера.  Если бы каждый  объект  пера
создавался  и  сохранялся  в  пере  Windows,  Windows скоро
исчерпала бы ресурсы.  Поэтому важно непосредственно  после
использования пера вызывать для его отмены метод Delete.

     Основное достоинство  TPen  в  том,  что  вам не нужно
больше беспокоиться  о  получении,  сохранении  и  удалении
объекта  пера.  TPen  имеет  два  частных поля,  в одном их
которых   записывается   описатель   пера.   Объект    пера
отслеживает  описатель  и взаимодействия с Windows,  а ваша
программа просто имеет  дело  с  объектом.  Другое  частное
поле,  PenData,  содержит  используемый  на этом шаге буфер
передачи.

     Файл STEP06A.PAS   содержит   код   программы   Steps,
модифицированный  для  использования  объекта TPen в модуле
Pen.  В основном изменения невелики (например,  поле ThePen
изменяет тип с HPen на PPen,  а метод SetPenSize заменяется
вызовом метода  SetPenAttributes  объекта  пера,  поскольку
объект  пера  может  управлять  цветом  и  стилем  наряду с
размером).



                Создание сложного диалогового блока
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     До сих   пор   вы   использовали   достаточно  простой
диалоговый блок (см.  блок About Box в  шаге  5).  Особенно
полезными  становятся  диалоговые  блоки,  когда  вы можете
устанавливать   и   считывать   значения   их   управляющих
элементов.

     В модуле   Pen   определяется   более  сложный  ресурс
диалогового блока  с  именем  'PenDlg',  который  дает  вам
возможность  изменения  атрибутов  только что определенного
объекта пера. Этот диалоговый блок показан на Рис. 4.1.

      ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
      і±=±ЫЫЫЫЫЫЫЫЫЫSet Pen AttributesЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі
      ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
      і   ЪДColorДДДДДДДДДДї ЪДStyleДДДДДДДДДДДї          і
      і   і (*) Black      і і (*) Solid       і          і
      і   і ( ) Purple     і і ( ) Dash        і          і
      і   і ( ) Blue       і і ( ) Dot         і          і
      і   і ( ) Cyan       і і ( ) DashDot     і          і
      і   і ( ) Green      і і ( ) DasDotDot   і          і
      і   і ( ) Yellow     і і ( ) Null        і          і
      і   і ( ) Red        і ГДДДДДДДДДДДДДДДДДґ          і
      і   і ( ) White      і і Width: ±1±      і          і
      і   АДДДДДДДДДДДДДДДДЩ АДДДДДДДДДДДДДДДДДЩ          і
      ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
      і                                                   і
      і                     ЪДДДДДДДДДДДДї ЪДДДДДДДДДДДДї і
      і                     і±±±±OK±±±±±±і і±±Cancel±±±±і і
      і                     АДДДДДДДДДДДДЩ АДДДДДДДДДДДДЩ і
      і                                                   і
      АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 4.1 Диалоговый блок с изменением атрибутов пера.

     Set Pen Attributes - установка атрибутов пера; Color -
цвет;  Black - черный; Purple - фиолетовый; Blue - голубой;
Cyan - бирюзовый;  Green - зеленый;  Yellow - желтый; Red -
красный;  White - белый; Style - стиль; Solid - непрерывная
линия; Dash - пунктир; Dot - точки; DashDot - точки и тире;
DasDotDot - тире и две точки; Null - пусто; Width - ширина;
OK - подтверждение; Cancel - отмена.

     Построение объекта  из  ресурса  'PenDlg'  выполняется
также,  как это делается для окна About Box (за исключением
порождающего окна). Поскольку диалоговый блок атрибута пера
выполняется из объекта TPen,  а не из оконного объекта,  вы
не  можете в качестве порождающего окна использовать @Self.
Вместо этого TPen присоединяет диалоговый блок к одному  из
окон,  о  присутствии  которых известно заранее - основному
окну приложения:

procedure TPent.ChangePen;
var PenDlg: PPenDialog;
begin
  .
  .
  .
  PenDlg := New(PPenDialog, Init(Application^.MainWindow,
                'PenDlg'));
     .
     .
     .
end;

     Другим важным отличием является то, что на этот раз вы
имеете новый производный объектный тип TPenDialog.  Так как
окно About box не использует ничего,  кроме назначенного по
умолчанию поведения диалогового окна,  инкапсулированного в
TDialog,   вам   не  требуется  создавать  для  него  новый
объектный тип.  Однако  диалог  атрибутов  пера  отличается
более сложным поведением и требует настройки объекта.

     Приведем определение TPenDialog из модуля Pen:

     type
       PPenDialog = ^TPenDialog;
       TPenDialog = object(TDialog);
          constructor Init(AParent: PWindowsObject; AName;
                           PChar);
     end;

     constructor TPenDialog.Init(AParent: PWindowsObject;
                           AName: PChar;
     var
       AControl: PRadioButton;
       i: Integer;
     begin
       inherited Init(AParent, AName);
       AControl := New(PRadioButton, InitResource(@Self,
                       1100 + i));
       for i := 0 to 5 do
       AControl := New(PRadioButton, InitResource(@Self,
                       1200 + i));
     end;

     Построенные в    TPenDialog    управляющие     объекты
поясняются в следующем разделе.

                        Управляющие объекты
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если вашей   программе    требуется    непосредственно
взаимодействовать  с  управляющими  объектами  в диалоговом
окне (например,  чтобы поместить элементы в блок списка или
определить  выбор кнопки с независимой фиксацией),  с этими
управляющими элементами полезно связать объекты.  Тогда  вы
сможете   управлять  этими  элементами  также,  как  любыми
другими объектами в программе.


                Использование интерфейсных объектов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     При "обычном" программировании в Windows (то есть  без
ObjectWindows),    ваша    прикладная    программа   должна
взаимодействовать с каждым элементом экрана  через  функции
API  Windows.  Как  вы уже видели,  ObjectWindows облегчает
создание и управление диалоговыми блоками,  изолируя вас от
Windows  путем  максимально  возможного  использования  для
представления элементов экрана объектов.  Эти  интерфейсные
объекты   также   значительно  облегчают  взаимодействие  с
управляющими элементами в диалоговых блоках.

           Примечание: Интерфейсные объекты  описываются  в
      Главе   9,   а  управляющие  объекты  описываются,  в
      частности, в Главе 12.

     Если вам не  требуются  управляющие  объекты,  вы  все
равно  сможете взаимодействовать с управляющими элементами,
но это приведет к необходимости частого вызова функций  API
Windows,   передачи   управляющим   элементам  сообщений  и
интерпретации   результатов.   ObjectWindows    значительно
облегчает   эту   задачу,  инкапсулируя  поведение  каждого
управляющего   элемента    в    объекте.    Передаются    и
обрабатываются те же сообщения,  но ObjectWindows заботится
обо всех деталях.

     Связь объекта  с  созданными  из  ресурса  управляющим
элементом  достаточно  проста:  внутри конструктора объекта
диалогового блока вы строите объекты для любых  управляющих
элементов,  которыми  хотите манипулировать.  Однако вместо
использования   для   построения    управляющих    объектов
конструктора Init применяется InitResource.

                      Конструктор InitResource
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда вы  на  этапе  выполнения  создаете  управляющий
объект  (в противоположность созданию его из ресурса),  вам
нужно задать расположение, размер и начальное значение (или
состояние)  управляющего элемента,  а также указать,  какой
объект является порождающим.  Все эти элементы передаются в
качестве параметров конструктору Init объекта.

     Связь объекта   с  управляющим  элементом  из  ресурса
намного проще,  так как такая информация как расположение и
размер,    определяется    ресурсом.   Требуется   передать
конструктору  InitResource  только  порождающий  объект   и
идентификатор  управляющего  элемента.  Так как управляющие
объекты обычно строятся внутри конструктора их  порождающих
диалоговых  блоков,  указатель  порождающего  объекта почти
всегда равен @Self.

     Как показано в приведенном выше примере,  диалог  пера
модуля  Pen  связывает объекты с их управляющими элементами
редактирования (для задания размера пера) и обоими наборами
кнопок с зависимой фиксацией (для задания цвета и стиля).

     Заметим, что   все   управляющие  объекты  строятся  и
присваиваются одной и той же локальной переменной AControl.
Вашей программе не придется взаимодействовать ни с одним из
этих управляющих элементов непосредственно,  так  как  пока
выполняется   режимный  диалоговый  блок,  остальная  часть
программы не активна.  InitResource к списку дочерних  окон
диалогового  блока,  чтобы обеспечить очистку и уничтожение
элементов экрана вместе с диалоговым окном.

     В общем случае нет необходимости присваивать  дочерним
окнам  в режимных диалоговых блоках поля объекта.  Однако в
шаге 11  вы  увидите,  как  можно  сохранять  указатели  на
управляющие   элементы   объектов  безрежимного  окна,  что
облегчает работу с ними.

                      Создание буфера передачи
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Теперь, когда  в  диалоговом  блоке у вас есть объект,
связанный  с  управляющими  элементами  диалогового   окна,
необходим  способ  для установки и чтения их значений.  Это
делается с помощью буфера передачи.  Буфер передачи  -  это
запись, которая содержит одно поле для каждого управляющего
элемента в диалоговом  окне,  в  который  или  из  которого
происходит передача.

     Например, диалоговый блок,  созданный в шаге 6,  имеет
поле  редактирования  и  четырнадцать  кнопок  с  зависимой
фиксацией.  В  управляющий элемент редактирования требуется
передавать строку,  а каждая кнопка с  зависимой  фиксацией
получает  значение Word,  указывающее на его выбор.  Модуль
Pen определяет тип записи,  передаваемый TPenDialogs  и  из
него:

     type
       TPenData = record
         XWidth: array[0..6] of Char;
         ColorArray: arra[0..7] of Word;
         StyleArray: array[0..5] of Word;
     end;

     Вы можете  также  управлять  кнопками  с   независимой
фиксацией,  используя 14 отдельных полей или один массив из
14 значений типа Word;  передаваемые данные будут теми  же.
Однако,   так   как   ваша   прикладная   программа   будет
интерпретировать  их  как  две  группы  из  8  и  6  кнопок
соответственно, удобно задать поле для каждой группы.

                       Присваивание буфера

     Каждый потомок      TWindowsObject      имеет     поле
TransferBuffer.  Когда  вы   хотите   передать   данные   в
диалоговое   окно,   нужно   задать  объект  TransferBuffer
диалогового блока, указывающий на запись передачи:

PenDlg := New(PPenDialog, Init(Application^.MainWindow,
                               'PenDlg'));
PenDlg^.TransferBuffer := @PenData;

     Если ваши программы создают объекты  диалогового  окна
динамически,  убедитесь, что они каждый раз назначают буфер
передачи.  TransferBuffer по умолчанию имеет значение  nil.
Это означает, что данные не переданы.

                        Заполнение буфера

     Перед фактической  передачей данных в диалоговое окно,
вам нужно установить  значение  полей  в  буфере  передачи.
Перед    выводом   диалогового   окна   пера   это   делает
TPen.ChangePen:

procedure TPen.ChangePen;
var
  PenDlg: PPenDialog;
  TempWidth, ErrorPos: Integer;
begin
  SetColorAttr(PenDate, Color);
  SetStyle(PenDate, Style);
  wvsprintf(PenDialog, Init(Application^.MainWindows,
            'PenDlg'));
  PenDlg^.TransferBuffer := @PenData;
  if Application^.ExecDialog(PenDlg) <> id_Cancel then
  begin
     Val(PenData.XWidth, TempWidth, ErrorPos);
     if ErrorPos = 0 then
         SetAttributes(SetStyle(PenData), TempWidth,
              GetColorAttr(PenData));
  end;
end;

     SetColorAttr и  SetStyle  используют  то преимущество,
что буфер передачи задает кнопки с  зависимой  фиксацией  в
виде массива значений Word.  SetStyle,  например,  выглядит
следующим образом:

procedure SetStyle(var ARec: TPenData; AStyle: Integer);
var i: Integer;
begin
  for i := 0 to 5 do
      if = AStyle then ARec.StyleArray[i] := bf_Checked
      else ARec.StyleArray[i] := bf_Unchecked;
end;

      Примечание: SetColorAttr выполняет то же  назначение,
      что  и  ColorArray.  bf_Checked  и bf_Unchecled - это
      константы ObjectWindows.

                          Передача данных
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     После того как вы создадите буфер передачи и заполняет
его значениями,  получение  этой  информации  в  диалоговом
блоке  не  представляет труда,  поскольку все за вас делает
ObjectWindows.  Когда  для  выполнения  диалогового   блока
вызывается   ExecDialog,   он   вызывает  TransferDatа  для
копирования значений из буфера передачи в отдельные объекты
управляющих элементов.

     Когда вы завершите диалоговое окно, щелкнув "мышью" на
командной  кнопке   OK,   ExecDialog   перед   уничтожением
диалогового  блока  и  его  управляющих  элементов передает
значения из управляющего элемента обратно в буфер передачи.
Отмена   диалогового  блока  или  его  закрытие  с  помощью
управляющего меню обходит механизм передачи данных  обратно
в буфер передачи.

     Таким образом,  буфер передачи указывает на постоянный
набор данных,  не зависящий от диалогового блока. Во многих
случаях   диалоговый  блок  создается  и  уничтожается  при
выполнении программы многократно, а присваивание каждый раз
его   поля  TransferData  одной  и  той  же  записи  данных
позволяет  выводить  управляющие  элементы  так,  как   они
выглядели при последнем закрытии диалогового блока.

                    Чтение возвращаемых значений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Считывание значений обратно в  буфер  передачи  -  это
обратный  процесс  по  отношению  к заполнению буфера перед
заполнением  диалогового  окна.  В  модуле  Pen  определены
некоторые   функции,  способствующие  интерпретации  выбора
кнопки с зависимой фиксацией в каждой группе.

function GetStyle(ARec: TPenDate): Longint;
var i: Integer;
begin
  for i := 0 to 5 do
     if ARec.StyleArray[i] = bf_Cheched then GetStyle := i;
end;

     Если пользователь  отменяет  диалоговый блок,  то вас,
конечно,  не должно  беспокоить  считывание  значений:  они
совпадают   с   переданными  значениями.  Обычно  когда  вы
выполняете диалоговый блок с помощью ExecDialog,  то  чтобы
определить,   возвратил   ли   диалоговый  блок  какие-либо
полезные данные,  проверяется возвращаемое значение (id_Ok,
если пользователь щелкнул "мышью" на командной кнопке OK, в
противном случае id_Cancel).

     if Application^.ExecDialog(PenDlg) <> id_Cancel then
     begin
       Val(PenDate.XWith, TempWith, ErrorPos);
       SetAttributes(GetStyle(PenData), TempWidth,
                     GetColorAttr(PenData));
     end;

                    Вызов диалогового блока пера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы вывести диалоговый блок пера, вызовите его метод
ChangePen.  Программа  STEP06B.PAS  делает  это  в ответ на
команду   cm_Pen,   генерируемую   выбором   пункта    меню
OptionsіPen и щелчком правой кнопкой "мыши".

procedure TStepWindow.CMPen(var Msg: TMessage);
begin
  CurrentPen^.ChangePen;         { CurrentPen - это объект
                                     блока пера }
end;

procedure TStepWindow.WMRButtonDown(var Msg: TMessage);
begin
  if not ButtonDown then CurrentPen^.ChangePen;
end;

      Примечание: Данные  методы  можно   найти   в   файле
 STEP06B.PAS.

               Глава 5. Повторное отображение графики
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В следующих трех шагах вы узнаете как

     * Отображать по запросу графический образ.

     * Сохранять образ файла и загружать его.

     * Печатать образa.

                   Шаг 7: Вывод на экран графики
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                    ЪДДДДДДДДДДДДДДДДДДДДДДДї
                    і Step 1: Basic App     і
                    і Step 2: Text          і
                    і Step 3: Lines         і
                    і Step 4: Menu          і
                    і Step 5: About Box     і
                    і Step 6: Pens          і
                    іЫStepЫ7:ЫPaintingЫЫЫЫЫЫі
                    і Step 8: Streams       і
                    і Step 9: Printing      і
                    і Step 10: Palette      і
                    і Step 11: BWCC         і
                    і Step 12: Custom ctrls і
                    АДДДДДДДДДДДДДДДДДДДДДДДЩ

     Возможно, вы  удивитесь,  узнав,  что графика и текст,
которые вы рисуете в окне с помощью  функций  Windows  типа
TextOut или LineTo, исчезают при изменении размера окна или
повторного вывода его на экран. После того, как графические
данные  переданы  Windows,  через вызовы функций Windows вы
никогда не получаете их обратно для повторного отображения.

     Чтобы в окне повторно отображалась графика,  вы должны
сохранить  эту графику (или данные для регенерации графики)
в структуре некоторого типа,  такой как объект.  С  помощью
объектов  вы  можете  полиморфически  хранить  простую  или
сложную графику,  а также  хранить  объекты  и  поля  ваших
оконных объектов.


                      Изображение и рисование
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Существует два  способа  получения в окне графического
образа. С рисованием вы уже знакомы по предыдущим примерам.
При  рисовании  вы  создаете  графический  образ в реальном
времени в ответ на ввод данных пользователем.  Но  окно  не
может  требовать  от  пользователя  воссоздания графики при
обновлении экрана.

     Окна должны иметь возможность воссоздавать по  запросу
свои  графические  образы.  Windows  сообщает своим оконным
объектам, когда они требуют изображения или обновления. При
этом   окно  должно  каким-то  образом  генерировать  образ
экрана. В ответ на необходимость изображения. ObjectWindows
автоматически вызывает метод Paint вашего окна. Наследуемый
и TWindow метод Paint не выполняет никаких функций. В Paint
вы  должны  поместить  код  для  передачи содержимого окна.
Фактически Paint вызывается при первом выводе  окна.  Paint
отвечает  за  обновление  (при  необходимости)  изображения
текущим содержимым.

     Существует еще одно важное отличие между  отображением
графики  в методе Paint и другим ее отображением (например,
в ответ на действия "мышью").  Содержимое  экрана,  которое
должно   использоваться   для   отображения,  передается  в
параметре PaintDC,  так что вашей  программе  не  требуется
получать или освобождать его.  Однако вам потребуется вновь
выбрать для PaintDC изобразительные средства.

     Чтобы отобразить содержимое  окна,  вместо  повторения
тех действий, которые привели к первоначальному изображению
(DragDC),  вы используете PaintDC.  Визуальный эффект будет
тот  же,  что  и при первоначальном рисовании пользователем
(аналогично проигрыванию аудиозаписи  концерта).  Но  чтобы
"проигрывать"   ее   в  методе  Paint,  сначала  вам  нужно
сохранить графику в виде объектов.


                   Сохранение графики в объектах
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Созданные программой Steps изображения на  самом  деле
просто  представляют  наборы  различного  числа линий.  При
каждой буксировке "мыши"  вы  добавляете  другую  линию.  А
каждая  линия - это на самом деле определенный набор точек,
соединенных  линейными  сегментами.   Чтобы   сохранить   и
воспроизвести  такие  изображения,  вам  необходим гибкий и
расширяемый тип данных

     Для размещения  неизвестного  числа  линий  или  точек
прекрасно   подходит  определенный  в  модуле  Objects  тип
TCollection.  Это набор объектов, который может динамически
расширяться,  когда  вы  добавляете  другие элементы.  Этим
наборам не важно,  что  они  включают,  поэтому  вы  можете
использовать  один  и тот же механизм и для рисунка (набора
линий), и для линии (набора точек).

           Примечание: О наборах рассказывается в Главе  19
      "Наборы".

     Концептуально вам нужно просто сделать так, чтобы окно
знало о своем  содержимом,  так  что  оно  сможет  обновить
изображение.  Окно  содержит рисунок,  представляющий собой
набор линий. Таким образом, вам нужно:

     * Передать окну  объект  или  поле,  содержащее  набор
линий.

     * Определить объект линии, который может отображаться.

     * В  ответ на сообщения "мыши" добавлять к сохраненным
       линиям точки.


                      Добавление поля объекта
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы сохранить рисунок в виде набора линий,  добавьте
в TStepWindow поле с именем Drawing. В любой момент Drawing
содержит текущий рисунок  в  виде  набора  объектов  линий.
Когда   требуется   отобразить  окно,  оно  использует  для
изображения линии данные, записанные в Drawing.


                     Определение объекта линии
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Далее нужно ответить на вопрос,  что  такое  линия.  В
шаге 4 вы видели, что изображаемая линия представляет собой
просто набор точек,  передаваемых из  Windows  в  программу
через  сообщение  wm_MouseMove.  Для  представления линий и
точек вам необходимы объектные типы.  Поскольку эффективный
объект  изображения линии должен быть повторно используемой
частью,  создайте отдельный  модуль,  определяющий  объекты
линий и точек.

     TLine содержит   всю   информацию,   необходимую   для
изображения данной линии: перо и набор точек.

     type
       PLine = ^TLine;
       TLine = object(TObject)
           Points: PCollection;
           LinePen: PPen;
           constructor Init(APen: PPen);
           constructor Load(var S: TStream);
           destructor Done; virtual;
           procedure AddPoint(AX, AY: Word);
           procedure Draw(ADC: HDC);
           procedure Store(var S: TStream);
     end;

     LinePen просто указывает на объект TPen, а Point - это
набор объектов точек.  TLine и TLinePoint  содержат  методы
Load и Store, преимущества использования которых для записи
картинок на диск вы увидите в шаге  8.  В  отличие  от  них
объект TLine весьма прост: конструктор и деструктор создают
и уничтожают LinePen,  AddPoint  включает  объект  точки  в
Points, а Draw рисует линии между точками Points.

     Объект TLinePoint еще проще:

     type
       PLinePoint = ^TLinePoint;
       TLinePoint = object(TObject)
          X, Y: Integer;
          constructor Init(AX, AY: Integer);
          constructor Load(var S: TStream);
          procedure Store(var S: TStream);
     end;

     constructor TLinePoint.Init(AX, AY: Integer);
     begin
       X := AX;
       Y := AY;
     end;

     TLinePoint не определяет никакого нового  поведения  -
это  просто объект данных,  который должен использоваться в
TLine. Но позднее (в шаге 8) он понадобиться как объект для
записи  в  поток.  Не забудьте построить в TStepWindow.Init
Drawing и уничтожить его в TStepWindow.Done:

     constructor TStepWindow.Init(AParent: PWindowsObject;
                                  ATitle: PChar);
     begin
       inherites Init(AParent, ATitle);
       ButtonDown := False;
       HasChanged := False;
       CommonPen := New(PPen, Init(ps_Solid, 1, 0));
       Drawing := New(PCollection, Init(50, 50));
     end;

     destructor TStepWindow.Done;
     begin
       Dispose(CommonPen, Done);
       Dispose(Drawing, Done);
       inherited Done;
     end;

     Основное окно  программы  Steps содержит набор в своем
поле Drawing набор линий.  Когда пользователь рисует линии,
вы  должны  преобразовывать  их  в  объекты  и  добавлять в
Drawing.  Затем,  когда потребуется отобразить окно,  путем
итерации Drawing нужно отобразить каждую его точку.


                 Изменение методов работы с "мышью"
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы сохранять  линии  в  виде  объектов,  вы  должны
изменить  EMLButtonDown  и  WMMouseMove,  чтобы  не  только
рисовать  линии,  но  также сохранять точки в наборе линий.
Поскольку текущую линию придется обновлять не только одному
методу,  добавьте  в TStepWindow еще одно поле типа PLine с
именем CurrentLine:

     type
       TStepWindow = object(TWindow);
          CurrentLine: PLine;
            .
            .
            .
     end;

     Кроме добавления  изображения   линии   WMLButttonDown
создает  при  каждом  вызове новый объект линии и добавляет
его в набор в Drawing.  WMMouseMove просто добавляет  новую
точку  в  конец  объекта  текущей линии и изображает в окне
линейные сегменты. Сохраняя все точки всех линий, ваше окно
будет   записывать   информацию,  необходимую  для  точного
воспроизведения картинки.

procedure TStepWindow.WMLButtonDown(var Msg: TMessage);
begin
  if not ButtonDown then
  begin
    ButtonDown := True;
    SetCapture(HWindow);
    DragDC := GetDC(HWindow);
    CommonPen^.Select(DragDC);
    MoveTo(DragDC, Msg.lParamLo, Msg.lParamHi);
    CurrentLine := New(PLine, Init(CommonPen));
    Drawing^.Insert(CurrentLine);
  end;
end.

procedure TStepWindow.WMMouseMove(var Msg: TMessage);
begin
  if ButtonDown then
  begin
    LineTo(DragDC, Msg.lParamLo, Msg.lParamHi);
    CurrentLine^.AddPoint(Msg.LParamLo, Msg.LParamHi);
  end;
end;

      Примечание: Уничтожать   устаревшие   CurrentLine  не
 требуется,  поскольку они записаны в наборе  Drawing.  Все
 объекты линий уничтожаются при уничтожении Drawing.

     WMLButtonUp модификации   не  требует.  Вам  не  нужно
уничтожать все  объекты  линий  при  очистке  отображаемого
окна, поэтому добавьте в CMFileNew вызов метода FreeAll:

     procedure TStepWindow.CMFileNew(var Msg: TMessage);
     begin
       Drawing^.FreeAll;
       InvalidateRect(HWindow, nil, True);
     end;

                     Вывод сохраненной графики
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Теперь, когда  TStepWindow  сохраняет   свою   текущую
строку,  вы  должны  научить  его по команде (этой командой
является  Paint)   рисовать   ее.   Давайте   напишем   для
TStepWindow   метод   Paint,   который  повторяет  действия
WMLButtonDown, WMMouseMove и WMLButtonUp. Путем итерации по
набору линий Paint воссоздает картинку аналогично тому, как
это делаете вы.  Метод Paint имеет следующий вид (см.  файл
STEP07.PAS):

procedure TStepWindow.Paint(PaintDC: HDC; var PaintInfo:
                            TPintStruct);

procedure DrawLine(P: PLine); far;
begin
  P^.Draw(PaintDC);
end;

begin
  Drawing^.ForEach(@DrawLine);
end;

      Примечание: Итерация  методов  описывается в Главе 19
 "Наборы".

     Метод Draw объекта линии для изображения каждой  линии
между точками также использует итератор ForEach:

     procedure TLine.Draw(ADC: HDC);
     var First: Boolean;

       procedure DrawLine(P: PLinePoint); far;
       begin
         if First then MoveTo(ADC, P^.X, P^.Y)
         else LineTo(ADC, P^.X, P^.Y);
         First := False;
       end;

     begin
       First := True;
       LinePen^.Select(ADC);
       Points^.ForEach(@DrawLine);
       LinePen^.Delete;
     end;



                 Шаг 8: Сохранение рисунка в файле
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                    ЪДДДДДДДДДДДДДДДДДДДДДДДї
                    і Step 1: Basic App     і
                    і Step 2: Text          і
                    і Step 3: Lines         і
                    і Step 4: Menu          і
                    і Step 5: About Box     і
                    і Step 6: Pens          і
                    і Step 7: Painting      і
                    іЫStep 8:ЫStreamsЫЫЫЫЫЫЫі
                    і Step 9: Printing      і
                    і Step 10: Palette      і
                    і Step 11: BWCC         і
                    і Step 12: Custom ctrls і
                    АДДДДДДДДДДДДДДДДДДДДДДДЩ

     Теперь, когда вы сохранили представление данных в виде
рисунка  как  часть оконного объекта,  можно легко записать
эти данные в файл (фактически,  в буферизованный поток DOS)
и считать его обратно.

     Данный шаг  посвящен  добавлению  полей  объектов  для
записи  состояния   сохраняемой   информации,   модификации
сохраняемой   в   файле   информации  и  методам  открытия.
Используя   предусмотренные   в   ObjectWindows   потоковые
объекты,   вы   убедитесь  в  удобстве  их  применения  для
сохранения данных в файле.

                       Отслеживание состояния
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Требуется отслеживать   две   характеристики  рисунка.
Изменение файла мы уже отслеживали (в шаге 1 было добавлено
поле HasChanged), но теперь нужно знать, загружен ли файл в
данный момент.  Как и HasChanged,  IsNewFile - это  атрибут
TStepWindow типа Boolean, поэтому его также следует сделать
полем:

     TStepWindow = object(TWindow)
         ButtonDown, HasChanged, IsNewFile: Boolean;
          .
          .
          .
     end.

     Поле HasChanged принимает значение True,  если текущий
рисунок модифицирован.  Модификация означает,  что  рисунок
был   изменен   с  момента  последнего  сохранения  или  не
сохранялся вовсе.  Вы уже устанавливаете поле HasChanged  в
True,  когда  пользователь  начинает  рисовать,  и в False,
когда окно очищается.  Когда пользователь  открывает  новый
файл   или   сохраняет   существующий,  HasChanged  следует
установить в False.

     IsNewFile указывает,  что рисунок не  взят  из  файла,
поэтому сохранение рисунка потребует от пользователя задать
имя  файла.  IsNeFile  имеет  значение  True   только   при
первоначальном    запуске   приложения   и   после   выбора
пользователем команды меню FileіNew (ФайліНовый).  Это поле
устанавливается   в   False,  когда  файл  открывается  или
сохраняется.  Фактически,  FileSave  использует  IsNewFile,
чтобы  увидеть,  можно  ли  сохранить файл немедленно,  или
пользователю требуется выбрать файл из файлового диалога.

     Приведем методы сохранения и загрузки файла. На данный
момент  они  выполняют только сохранение и загрузку файлов.
Сохранение файла сконцентрировано  в  одном  новом  методе,
который  называется  WriteFile,  а открытие файла выполняет
метод ReadFile.

procedure TStepWindow.CMFileNew(var Msg: TMessage);
begin
  if CanClose then
  begin
    Drawing^.FreeAll;
    InvalidateRect(HWindow, nil, True);
    HasChanged := False;
    IsNewFile := True;
  end;
end;

procedure TStepWindow.CMFileOpen(var Msg: TMessage);
begin
  if CanClose then
     f Application^.ExecDialog(New(PFileDialog, Init(@Self,
        PChar(sd_FileOpen), StrCopy(FileName, '*.PTS')))) =
         id_Ok then ReadFile;
end;

procedure TStepWindow.CMFileSave(var Msg: TMessage);
begin
  if IsNewFile then CMFileSaveAs(Msg) else WriteFile;
end;

procedure TStepWindow.CMFileSaceAs(var Msg: TMessage);
begin
  if IsNewFile then StrCopy(FileName, '');
  if Application^.ExecDialog(New(PFileDialog,
       Init(@Self, PChar(sd_FileSave), FileName))) =
       id_Ok then WriteFile;
end;

procedure TStepWindow.ReadFile;
begin
  MessageBox(HWindow, @FileName, 'Загрузить файл:',
             mb_Ok);
  HasChanged := False;
  IsNewFile := False;
end;

procedure TStepWindow.WriteFile;
begin
  MessageBox(HWindow, @FileName, 'Сохранить файл:',
             mb_Ok);
  HasChanged := False;
  IsNewFile := False;
end;

      Примечание: Данный  текст  программы  можно  найти  в
 файле STEP08A.PAS.

               Сохранение и загрузка файлов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Теперь, когда вы создали основную схему для построения
и  загрузки  файлов,  осталось только выполнить фактическую
загрузку и сохранение в  файле  наборов  точек.  Для  этого
можно   использовать   потоковый  механизм  автоматического
сохранения  объекта.  Сначала  вы  научитесь  сохранять   и
загружать  сами  объекты точек и линий (как это сделать для
наборов вы уже знаете).  Затем методы WriteFile и  FileOpen
будут модифицированы для использования потоков.

           Примечание: Подробнее об использовании потоков с
      объектами рассказывается в Главе 20 "Потоки".

     Ниже приведен исходный код, показывающий как сохранять
и загружать сами объекты TLine и TLinePoint:

     const
        RLinePoint: TStreamRec = (
           ObjType: 200;
           VmtLink: Ofs(TypeOf(TLinePoint)^);
           Load: @TLinePoint.Load;
           Store: @TLinePoint.Store);

        RLine: TStreamRec = (
           ObjType: 201;
           VmtLink: Ofs(TypeOf(TLine)^);
           Load: @TLine.Load;
           Store: @TLine.Store);

     constructor TLinePoint.Load(var S: TStream);
     begin
       S.Read(X, SizeOf(X));
       S.Read(Y, SizeOf(Y));
     end;

     procedure TLinePoint.Store(var S: TStream);
     begin
       S.Write(X, SizeOf(X));
       S.Write(Y, SizeOf(Y));
     end;

     constructor TLine.Load(var S: TStream);
     begin
       Points := PCollection(S.Get);
       LinePen := PPen(S.Get);
     end;

     procedure TLine.Store(var S: TStream);
     begin
       S.Put(Points);
       S.Put(LinePen);
     end;

     procedure StreamRegistration;
     begin
       RegisterType(RCollection);
     end;

     Для регистрации  TCollection  при  запуске  прикладной
программы вы должны  вызывать  StreamRegistration  (который
находится  в Steps).  Вы можете поместить это вызов в метод
TStepWindow.Init. Модуль DrawLine регистрирует в своем коде
инициализации  TLinePoint  и  TLine,  поэтому линии и точки
регистрируются простым включением DrawLine в оператор uses.

     Заключительным шагом  изменения  методов  WriteFile  и
ReadFile  будет фактическая запись в потоки и чтение из них
(см. STEP08B.PAS):

     procedure TStepWindow.ReadFile;
     var
       TempColl: PCollection;
       TheFile: TDosStream;
     begin
       TheFile.Init(FileName, stOpen);
       TempColl: := PCollection(TheFile.Get);
       TheFile.Done;
       if TempColl <> nil then
       begin
         Dispose(Drawing, Done);
         Drawing := TempColl;
         InvalidateRect(HWindow, nil, True);
       end;
       HasChanged := False;
       IsNewFile := False;
     end;

     procedure TStepWindow.WriteFile;
     var
       TheFile: TDosStream;
     begin
       TheFile.Init(FileName, stCreate);
       TheFile.Put(Drawng);
       TheFile.Done;
       IsNewFile := False;
       HasChanged := False;
     end;



                 Шаг 9: Печать графического образа
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                    ЪДДДДДДДДДДДДДДДДДДДДДДДї
                    і Step 1: Basic App     і
                    і Step 2: Text          і
                    і Step 3: Lines         і
                    і Step 4: Menu          і
                    і Step 5: About Box     і
                    і Step 6: Pens          і
                    і Step 7: Painting      і
                    і Step 8: Streams       і
                    іЫStepЫ9:ЫPrintingЫЫЫЫЫЫі
                    і Step 10: Palette      і
                    і Step 11: BWCC         і
                    і Step 12: Custom ctrls і
                    АДДДДДДДДДДДДДДДДДДДДДДДЩ

     Печать из  Windows  может  представлять  собой сложную
задачу,  но ObjectWindows  предоставляет  простой  механизм
добавления средств печати в вашу прикладную программу.

     Добавление этих  средств предусматривает следующие три
шага:

     * Построение объекта принтера.

     * Создание объекта распечатки.

     * Печать объекта распечатки.

                    Построение объекта принтера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Любая программа  ObjectWindows может получить доступ к
принтеру с помощью объекта типа  TPrinter.  В  этом  случае
основное  окно  вашего  приложения  должно построить объект
принтера и сохранить его в объектном поле с именем Printer:

     constructor TStepWindow.Init(AParent: PWindowsObject;
                                  ATitle: PChar);
     begin
       inherited Init(AParent, ATitle);
          .
          .
          .
       Printer := New(PPrinter, Init);
     end;

           Примечание: Тип  TPrinter  определен  в   модуле
      OPrinter,  поэтому  не  забудьте  добавить OPrinter в
      свой оператор uses.

     Это все,   что   обычно    приходится    делать    для
инициализации   объекта  принтера.  По  умолчанию  TPrinter
использует назначенный по  умолчанию  принтер,  заданный  в
файле WIN.INI.  TPrinter предусматривает также механизм для
выбора альтернативных принтеров.

                    Создание объекта распечатки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows управляет  выводимыми  на печать данными
точно также,  как выводом на экран.  То есть вместо  записи
непосредственно    на    устройство    вывода   (или   даже
непосредственно в Windows) вы  направляете  свой  вывод  на
объект,  который  знает,  как  представлять  информацию  на
устройстве  вывода.  Для  вывода  на   печать   используйте
объекты, полученные из абстрактного типа TPrintout и метода
с именем PrintPage.

     Существует два основных случая,  с которыми вы  будете
иметь  дело  при генерации из приложения Windows данных для
печати: печать документов и печать содержимого окна. Печать
содержимого окна проще,  поскольку окна уже "знают" о своем
представлении.  Как оказывается на самом деле,  это  просто
особый случай печати документа.

 Примечание: О печати документов рассказывается в Главе 15.

                    Запись в контекст устройства
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     До настоящего момента вы  всегда  записывали  текст  и
графику   в   контекст   дисплея   (что  является  способом
представления в  Windows  пользовательской  области  окон).
Контекст  дисплея  -  это  просто специализированная версия
контекста устройства - механизма,  через который приложения
Windows  работают  с  различными  устройствами,  такими как
экраны, принтеры или коммуникационные устройства.

     Запись в контекст одного устройства мало отличается от
записи в контекст другого,  поэтому,  например,  достаточно
просто сообщить, например, оконному объекту, что для записи
на принтер нужно использовать механизм Paint.

                      Создание распечатки окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TWindowPrint -  это  специальный  потомок   TPrintout,
используемый    для   печати   содержимого   окна.   Печать
содержимого  окна  не  представляет   сложности   по   двум
причинам: вы имеете дело только с одной страницей, и объект
окна уже знает, как отображать свой образ.

     Обычно при печати документа вашей прикладной программе
нужно   выполнять   итерации  процесса  печати  для  каждой
страницы документа.  Так как окно имеет только один  образ,
при печати окна это не является необходимым.

     Таким образом,  печать  также  проста,  как ориентация
метода Paint объекта окна на вывод вместо окна  в  контекст
устройства, подходящий для принтера:

procedure TWindowPrint.PrintPage(DC: HDC; Page: Word;
              Size: TPoint; var Rect: TRect; Flags: Word);
var PS: TPaintStruct;
begin
  Window^.Paint(DC, PS);
end;

     Поскольку переданный   PrintPage   параметр   DC   уже
указывает на подходящий для принтера контекст устройства, в
простейшем случае PrintPage должен только сообщить  объекту
окна  на  вывод его содержимого в этот контекст устройства.
Теперь  ваш  объект  распечатки   также   знает   о   своем
представлении.

                          Вывод распечатки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Наличие объекта распечатки,  которому известно о своем
представлении,  это все,  что нужно для передачи распечатки
на принтер.  Программа Steps делает это в ответ на  команду
cm_FilePrint, генерируемую командой Print меню File:

     procedure TStepWindow.CMFilePrint(var Msg: TMessage);
     var P: PPrintout;
     begin
       if IsNewFile then StrCopy(FileName, 'Untitled');
       P := New(PWindowPrint, Init(FileName, @Self));
       Printer^.Print(@Self, P);
       Dispose(P, Done);
     end;

     CMFilePrint очень  просто  строит  объект  распечатки,
озаглавленный   заданным   именем   (имя  файла  точек  или
'Untitled') и заполняет его своим содержимым (так  как  это
единственное окно в приложении).

     При наличии  объекта  распечатки  CMFilePrint сообщает
объекту  принтера,  что  его  нужно   напечатать,   добавив
какие-либо сообщения об ошибках или диалоговые окна (отсюда
параметр  @Self).  Когда  печать  закончится,   CMFilePrint
уничтожает объект распечатки.


                       Выбор другого принтера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Одним из   средств   TPrinter   является   возможность
изменения установки  принтера.  TPrinter  определяет  метод
Setup,  который выводит диалоговое окно установки принтера,
позволяющее   пользователю   выбрать   принтер   из   числа
установленных в Windows и обеспечивает доступ к диалоговому
окну конфигурации устройства.

     Чтобы вывести диалоговое окно установки принтера, ваша
прикладная программа вызывает метод Setup объекта принтера.
Steps делает это  в  ответ  на  команду  cm_FileSetup  (см.
STEP09.PAS):

     procedure TStepWindow.CMFileSetup(var Msg: TMessage);
     begin
       Printer^.Setup(@Self);
     end;

     Диалоговое окно    установки     принтера     является
экземпляром типа TPrinterSetupDlg (см. Рис. 5.1).

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫSelect PrinterЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і                                                        і
і      Принтер и порт                                    і
і      ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДї  і
і      іPostScript Printer on LPT1:±±±±±±±±±±±±±±±±±іvі  і
і      АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДЩ  і
і    ЪДДДДДДДДДДДї        ЪДДДДДДДДДДДї     ЪДДДДДДДДДДДїі
і    і±±±±OK±±±±±і        і±±Setup±±±±і     і±±Cancel±±±іі
і    АДДДДДДДДДДДЩ        АДДДДДДДДДДДЩ     АДДДДДДДДДДДЩі
і                                                        і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 5.1 Диалоговое окно установки принтера.

     В комбинированном  блоке  диалогового  окна  выводятся
принтеры,  заданные  в  WIN.INI.  Это   дает   пользователю
возможность доступа ко всем установленным принтерам.










                  Глава 6. Вывод всплывающего окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Итак, вы создали два типа окон - основное окно (объект
TStepWindow) и режимные дочерние окна,  которые создаются и
уничтожаются каждый раз,  когда они  необходимы  (например,
блоки сообщений).  Однако,  в полноценной программе Windows
дочерние окна часто требуется сохранять активными в течении
неопределенного  периода  времени (в качестве примера можно
привести окно оперативной полосы SpeedBar в работающей  под
Windows интегрированной среде IDE).

     До сих   пор   все   дочерние   окна   в  Steps  имели
фиксированный размер и создавались из шаблонов ресурсов.  В
шагах 10 - 12 вы будете делать следующее:

     * Создавать     окна    с    динамическим    размером,
       сохраняющиеся на все время работы программы.

     * Добавлять  в  окно  специализированные   управляющие
элементы.

     * Создавать собственное интерактивное окно.

     Наконец, мы    дадим    предложения   по   дальнейшему
расширению программы Steps.

                Шаг 10: Добавление всплывающего окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                    ЪДДДДДДДДДДДДДДДДДДДДДДДї
                    і Step 1: Basic App     і
                    і Step 2: Text          і
                    і Step 3: Lines         і
                    і Step 4: Menu          і
                    і Step 5: About Box     і
                    і Step 6: Pens          і
                    і Step 7: Painting      і
                    і Step 8: Streams       і
                    і Step 9: Printing      і
                    іЫStepЫ10:ЫPaletteЫЫЫЫЫЫі
                    і Step 11: BWCC         і
                    і Step 12: Custom ctrls і
                    АДДДДДДДДДДДДДДДДДДДДДДДЩ

     Создание и  уничтожение  окон  и   диалоговых   блоков
прекрасно подходит,  когда они используются не часто.  Но в
некоторых случаях желательно иметь дочернее окно, доступное
большую   часть  времени.  Примером  такого  окна  является
инструментальная палитра.

     В этом шаге вы будете делать следующее:

     * Добавите к основному окну поле.

     * Построите плавающую палитру пера.

     * Выведете и скроете палитру пера.

     Палитра пера,    которая    выводится    при    выборе
пользователем команды PaletteіShow (ПалитраіВывод) показана
на Рис. 6.1.

            ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
            і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫPenPaletteЫЫЫЫЫЫЫЫЫЫЫЫЫі
            ГДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДґ
            і   ІІ      Add    і           Delete   і
            і ІІІІІІ    Pen    і ІІІІІІ    Pen      і
            і   ІІ             і                    і
            ГДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДґ
            і                                       і
            і     ДДДДДДДДДДДДДДДДДДДДДДДДДДДДД     і
            і                                       і
            ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
            і                                       і
            і     ЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯ     і
            і                                       і
            ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
            і                                       і
            і     ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫ     і
            і                                       і
            АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 6.1 Палитра пера программы Steps с тремя перьями.

     Поскольку это первое "новое" окно, которое вы создаете
и   которое   будет   создаваться   автоматически,  неплохо
рассмотреть,  как создаются и выводятся на экран объекты  и
элементы окна.

                  Добавление к окну дочернего окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Режимными дочерними окнами,  которые  вы  до  сих  пор
использовали,   управлять  легко.  Вы  можете  их  создать,
использовать и отменить.  Но здесь  нам  нужно  работать  с
диалоговым окном,  которое не является режимным.  Например,
оно должно  закрываться,  если  закрывается  приложение,  и
становиться скрытым, если основное окно минимизируется.

     В основном   поведение   диалоговых  окон  (такое  как
закрытие  или  когда  окно  временно  становится   скрытым)
автоматическое. Единственный случай, когда вам нужно делать
что-то особенное - это когда  вы  хотите  сделать  дочернее
окно независимым от его порождающего окна.  Например,  окно
палитры, которое вы собираетесь выводить, сможет скрываться
и  выводиться,  пока основное окно остается видимым.  Окна,
которые могут перемещаться  или  выводиться  независимо  от
своих  порождающих окон,  называются независимыми дочерними
окнами.  На следующем шаге вы  будете  создавать  зависимые
окна, присоединенные к независимому окну палитры.

     Так как  основное  окно  должно  посылать команды окну
палитры,  потребуется  указатель  на  это   окно,   поэтому
добавьте   в  TStepWindow  его  палитры  пера.  TStepWindow
содержит теперь следующие поля:

     TStepWindow = object(TWindow)
        DragDC: DHC;
        ButtonDown: Boolean;
        FileName: array[0..fsPathName] of Char;
        HasChanged, IsNewFile: Boolean;
        Drawing: PCollection;
        Printer: PPrinter;
        PenPalette: PPenPalette;      { окно палитры }
          .
          .
     end;

     Осталось только  построить  объект  дочернего  окна  и
присвоить его PenPalette. Этому посвящен следующий раздел.


                      Построение окна палитры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Объекты дочернего окна строятся обычно в конструкторах
своих порождающих окон. Аналогично тому, как это происходит
при инициализации  любого  другого  поля,  вы  присваиваете
значения любому указателю дочернего окна. В данном случае:

constructor TStepWindows.Init(AParent: PWindowsObject;
                              ATitle: PChar);
begin
  inherited Init(AParent, ATitle);
    .
    .
    .
  nPalette := New(PPenPalette, Init(@Self, 'Pan Palette');
end;

               Назначение порождающего окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Порождающие окна   автоматически   управляют    своими
дочерними  окнами,  поэтому при создании дочернего окна ему
передается указатель на объект порождающего окна. Поскольку
порождающее   окно   обычно   строит  свои  дочерние  окна,
указателем порождающего окна обычно является @Self.

     Важным исключением является основное окно  приложения.
Так  как  оно  не  имеет  порождающего  окна,  конструктору
основного окна передается nil.

     Каждый оконный  объект  имеет  список  своих  дочерних
окон,  обеспечивающий создание,  вывод, сокрытие и закрытие
окон в нужные моменты.  Построение и  уничтожение  дочерних
окон   автоматически   обновляет   список   дочерних  окон:
построение дочернего окна добавляет  его  в  список  своего
порождающего окна; уничтожение окна удаляет его из списка.


                     Создание элементов экрана
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     При построении  объекта дочернего окна,  ObjectWindows
берет на себя функции по работе с соответствующими  объекту
элементами экрана. Это обратно тому, что вы делали в шаге 6
с помощью InitResource. Тогда вы имели созданный из ресурса
элемент  экрана  и  связывали с ним объект,  благодаря чему
могли манипулировать элементом экрана.  Теперь  вы  создали
собственный   объект,   и  вам  нужно  сообщить  Windows  о
необходимости создания соответствующего экранного элемента.

     Когда вы в шаге 3 делали это для диалогового окна,  то
вызывали  ExecDialog.  Метод  TApplication  создает элемент
экрана    и    выполняет    режимное    диалоговое    окно.
Соответствующим  методом  для  нережимных (или безрежимных)
диалоговых окон является TApplication.MakeWindow.  Основным
отличием   является   то,   что   MakeWindow   не   выводит
автоматически создаваемый элемент экрана и не  переходит  в
режимное состояние.

           Примечание: MakeWindow   и   создание  элементов
      экрана подробно описываются в Главе  9  "Интерфейсные
      объекты".

     Тогда процесс  построения  и  вывода  окна  состоит из
следующих трех этапов:

     * Построение оконного объекта с помощью Init.

     * Создание элемента экрана с помощью MakeWindow.

     * Вывод окна с помощью Show.

     К счастью,  второй и третий шаги  для  основного  окна
приложения выполняются автоматически. Кроме того, вызов для
порождающего окна  MakeWindow  автоматически  вызывает  для
любого окна в его списке дочерних окон MakeWindow,  так что
дочерние окна  основного  окна  (такие  как  палитра  пера)
автоматически получают элементы экрана.

     В следующем разделе мы выведем дочернее окно.

                      Вывод и сокрытие палитры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Дочерние окна, отличные от тех, которые были созданы и
выведены  по умолчанию их порождающими окнами (этот процесс
управляется с помощью EnableAutoCreate и DisableAutoCreate)
в  каждом  интерфейсном  объекте.  Но  вы можете скрыть или
вывести дочернее окно по команде.  Обе функции метода  Show
наследуются из TWindowsObject.

     В зависимости  от  передаваемых  параметров метод Show
выводит либо скрывает окно. Параметр - это одна из констант
sw_,  определенная  в  Windows.  В  ответ  на  команды меню
PaletteіShow     (ПалитраіВывод)      или      PaletteіHide
(ПалитраіСокрытие),   которые  генерируют,  соответственно,
команды cm_PalShow и cm_PalHide, TStepWindow вызывает метод
Show палитры пера (это дополняет STEP10.PAS):

     procedure TStepWindow.CMPalShow(var Msg: TMessage);
     begin
       PenPalette^.Show(sw_ShowNA);
     end;

     procedure TStepWindow.CMPalHide(var Msg: TMessage);
     begin
       PenPalette^.Show(sw_Hide);
     end;

     Если у вас есть поле порождающего окна, указывающее на
дочернее окно,  с которым  необходимо  работать,  вы  легко
можете задать дочернее окно.

    Шаг 11:   добавление   специализированных   управляющих
элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                    ЪДДДДДДДДДДДДДДДДДДДДДДДї
                    і Step 1: Basic App     і
                    і Step 2: Text          і
                    і Step 3: Lines         і
                    і Step 4: Menu          і
                    і Step 5: About Box     і
                    і Step 6: Pens          і
                    і Step 7: Painting      і
                    і Step 8: Streams       і
                    і Step 9: Printing      і
                    і Step 10: Palette      і
                    іЫStepЫ11:ЫBWCCЫЫЫЫЫЫЫЫЫі
                    і Step 12: Custom ctrls і
                    АДДДДДДДДДДДДДДДДДДДДДДДЩ

     В шаге 10 вы добавили  к  основному  окну  независимое
дочернее окно.  Теперь вы добавите зависимые дочерние окна,
которые  называются  управляющими  элементами.  Порождающим
окном  этих  управляющих  элементов  является  окно палитры
пера.  Нужно помнить о том,  что окно палитры пера является
независимым дочерним окном,  для которого порождающим окном
является  основное  окно.  Таким  образом,   палитра   пера
является  одновременно  дочерним  окном  основного  окна  и
порождающим окном для управляющих элементов.

     В шаге 6 вы уже имели дело с управляющими элементами и
объектами   управляющих   элементов,  но  тогда  вы  просто
связывали объекты с управляющими элементами,  определенными
в   ресурсе.  Построение  управляющего  элемента  на  этапе
выполнения несколько сложнее,  так как наряду с  типом  как
вам   требуется   задать   позицию   и  размер  управляющих
элементов.

     Палитра пера,  показанная на Рис.  6.1, использует две
специализированные   кнопки   кисти   и  последовательность
графических изображений,  каждое  из  которых  представляет
перо,   которое   можно  использовать  для  рисования.  Эти
перьевые  "кнопки"  фактически  не  являются   управляющими
элементами,   а   скорее   представляют   собой   образы  в
единственным    дочернем    окне,    которое    может    их
идентифицировать при щелчке "мышью".

   В данном шаге вы добавите графические кнопки с помощью:

* добавления простых управляющих кнопок;

* реализации  в  программе  специализированных  управляющих
  элементов;

* определения графических изображений для кнопок.

     Для всех управляющих  элементов,  в  целом,  поведение
задается типом ObjectWindows TControl и его типом-потомком,
позволяющим работать с каждым типом управляющего  элемента.
Например, TListBox определяет объекты блока списка, а TEdit
определяет каждый  управляющий  объект  редактирования.  Вы
должны также понимать, что TControl - это потомок TWindow.


               Добавление к палитре командных кнопок
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Хотя они  ведут  себя  идентично,  между  управляющими
кнопками диалоговых блоков (таких как  файловое  диалоговое
окно)  и  управляющими  элементами  окон  (таких  как  окно
палитры)   имеется   существенное   различие.   Управляющие
элементы  диалогового  блока  вы  можете  задать  в ресурсе
диалогового блока.  Они не являются объектами, и диалоговый
блок,  которому  они  принадлежат,  полностью  отвечает  за
управление этими  элементами.  В  Главе  11  показано,  как
создать  из диалоговых ресурсов свои собственные диалоговые
блоки и работать с их управляющими элементами.

     Управляющие элементы   окон   задаются    определением
объекта.  Порождающее  окно  управляет  их поведением через
методы,  определенные   объектами   управляющих   элементов
ObjectWindows.  Например, чтобы получить следующий элемент,
который пользователь выбрал в блоке списка,  вызовите метод
GetSelString объекта блока. Аналогично оконному объекту или
объекту диалогового  блока,  объект  управляющего  элемента
имеет соответствующий визуальный элемент.

     Объект управляющего элемента и его управляющий элемент
связаны  через  поле  идентификатора  объекта  управляющего
элемента.   Каждый  управляющий  элемент  имеет  уникальный
идентификатор,  который используется его порождающим  окном
для  идентификации  управляющего элемента при маршрутизации
управляющих событий (таких как щелчок на элементе "мышью").
Для   ясности   для   каждого  идентификатора  управляющего
элемента следует определить следующие константы:

     const
       id_Add = 101;
       id_Del = 102;
       MaxPens = 9;

     MaxPens задает   максимальное  число  перьев,  которые
будет содержать палитра.  Значение 9  хорошо  подходит  для
стандартного экрана VGA.

               Объекты управляющих элементов как поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Как и в случае  других  дочерних  окон,  часто  удобно
хранить  указатель  объекта  управляющего  элемента  в виде
поля.  Это необходимо только для дочерних окон,  с которыми
вы позднее сможете работать непосредственно, вызывая методы
их объектов. TPenPalette записывает каждый из этих объектов
управляющих  элементов  в  отдельном  поле.  Приведем часть
описания объекта TPenPalette:

     TPenPalette = object(TWindow)
        AddBtn, DelBtn: PButton;
          .
          .
          .
     end;

     После создания   экземпляра   этих  дочерних  объектов
управляющих  элементов  вы  можете  манипулировать  ими   с
помощью   вызовов   методов.  Например,  в  соответствующие
моменты можно разрешать  или  запрещать  командные  кнопки,
вызывая   их  методы  Enable  и  Disable.  Используя  метод
ChildList  порождающего  окна,  можно  получить  доступ   к
объектам управляющих элементов дочерних окон, не записанных
в полях, но гораздо удобнее делать это с помощью полей.

                  Работа с управляющими элементами
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Любой тип  окна,  который  имеет  объекты  управляющих
элементов (или другое дочернее окно) должен определять  для
построения своих объектов управляющих элементов конструктор
Init.  Кроме того,  для задания управляющих элементов перед
выводом  вы можете переопределить SetupWindow.  Порождающее
окно (TPenPalette) автоматически создает и выводит все свои
дочерние окна.

     Приведем в  качестве  примера метод Init палитры пера.
Первое,  что  он  делает  -  это   установка   собственного
расположения  и атрибутов размера.  Так как метод Init окна
отвечает за задание его  атрибутов  создания,  и  поскольку
вместе с ним создаются управляющие элементы окна, вы должны
также в методе Init окна построить управляющие элементы.  В
каждом  вызове  конструктора  первый  параметр  - это @Self
(порождающее   окно).   За   ним   следует    идентификатор
управляющего элемента.

constructor TPenPalette.Init(AParent: PWindowsObject;
              ATitle: PChar);
begin
  inherited Init(AParent, ATitle);
  with Attr do
  begin
    Style := Style or ws_Tiled or ws_SysMenu or
               ws_Visible;
    W := 133;
    H := GetSystemMetrics(sm_CYCaction) + 42;
    AddBtn := New(PButton, Init(@Self, id_Add,
                  'Добавить перо', 0, 0, 65, 40, True);
    DelBtn := New(PButton, Init(@Self, id_Del,
                  'Удалить перо', 0, 0, 65, 40, False);
end;

     После создания окна, чтобы задать управляющие элементы
окна, вызывается виртуальный метод TPenPalette.SetupWindow.
Поскольку   здесь   вы  имеете  дело  только  с  командными
кнопками,     инициализация      не      требуется,      но
TPenPalette.SetupWindow  первоначально  запрещает  одну  из
командных  кнопок.   Если   бы   вы   использовали   другой
управляющий   элемент   (например,  блок  списка),  то  для
инициализации объекта управляющего  элемента  потребовалось
бы вызывать SetupWindow.

           Примечание: Когда   вы   переопределяете   метод
      SetupWindow  окна,  не  забудьте   сначала   вызывать
      наследуемый метод SetupWindow, так как он создает все
      дочерние управляющие элементы.

     Вызов методов Init и SetupWindow вполне достаточен для
правильного   вывода   в   окне  палитры  всех  управляющих
элементов.  Командные  кнопки  можно  будет  активизировать
("нажимать"),  но  без  каких-либо  действий.  В шаге 12 мы
определим реакцию на события управляющего элемента.


                      Сокрытие вместо закрытия
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если вы дважды щелкните  "мышью"  в  блоке  системного
меню палитры пера, оно исчезнет. Выбор команды PaletteіShow
не может больше выводить палитру,  так  как  объект  и  его
экранные  элементы уничтожены.  Выводить нечего.  Вы можете
переопределить  это,  добавив   метод   CanClose,   который
скрывает   окно,   а  затем  запрещает  его  закрытие  (см.
STEP11A.PAS):

     function TPenPalette.CanClose: Boolean;
     begin
       Show(sw_Hide);
       CanClose := False;
     end;

     Теперь двойной щелчок "мышью" в блоке системного  меню
скрывает  окно,  но  не  закрывает его,  так что позднее вы
можете вывести его снова.

     Обычно наличие   дочернего   окна,   которое    всегда
возвращает из CanClose False,  может предотвратить закрытие
всего  приложения.  Но  TStepWindow  перед   закрытием   не
проверяет  своих  дочерних  окон,  так  как  в  шаге  1  вы
переопределили его метод CanClose.

        Разрешение специализированных управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Как вы   уже  знаете,  объекты  управляющих  элементов
создают стандартные управляющие элементы Windows. Например,
только  что созданный вами объект TButton дает в результате
в палитре окна  стандартную  серую  кнопку.  Однако  IDE  и
диалоговые  блоки,  созданные вами из ресурсов,  используют
кнопки другого типа с расположенными  на  них  графическими
изображениями.   ObjectWindows  предоставляет  вам  простой
способ использования в программах командных  кнопок  такого
вида.

     Использовать специализированные  управляющие  элементы
Borland для Windows (BWCC) также просто,  как использование
модуля.  Для  этого  нужно  просто добавить BWCC в оператор
uses основной программы.  Это немедленно дает два  эффекта.
Первый состоит в том,  что все стандартные диалоговые блоки
(такое  как  файловое  диалоговое  окно,  которое  вы   уже
добавили  в  программу  Steps)  используют  для таких общих
элементов как кнопки  OK  или  Cancel,  а  также  кнопки  с
зависимой   и  независимой  фиксацией,  вместо  стандартных
управляющих элементов специализированные.

           Примечание: Об  использовании  и  проектировании
      специализированных   управляющих   элементов  Borland
      рассказывается в Главе 12.

     Фактически, после добавления в оператор uses программы
Steps BWCC вы можете перекомпилировать программу и получить
доступ к диалоговым блокам. Без каких-либо других усилий вы
существенно улучшите внешний вид программы и ее интерфейса.

     Но как насчет кнопок в палитре пера?  Они были созданы
из управляющих объектов с BWCC,  используемых в  программе,
но выглядят как обычные командные кнопки.  Ответ,  конечно,
состоит в  том,  что  вы  еще  не  определили  для  кнопок,
графические  изображения,  так  что по умолчанию они просто
используют  метки,  переданные  в  конструкторе   Init.   В
следующем    разделе    вы   увидите,   как   добавлять   к
специализированным   управляющим   элементам    графические
изображения.

       Создание для командных кнопок графических изображений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Хотя вы  можете  создавать   графические   изображения
(битовые массивы) для командных кнопок на этапе выполнения,
эту задачу следует решать  с  помощью  ресурсов.  Используя
пакет  разработчика ресурсов,  вам нужно создать для каждой
командной кнопки три различных битовых  массива:  один  для
позиционирования сверху,  один для позиционирования снизу и
один для позиционирования в фокусе ввода.

     С этими графическими изображениями  вы  можете  делать
что угодно.  Здесь ограничений нет. Вы можете изменять цвет
образа в зависимости от  состояния  кнопки  или  перемещать
образы  (что  обычно  используется)  при  нажатии,  а также
добавлять вокруг текста кнопки линию из  точек,  когда  она
находится  в  фокусе  (активна).  На Рис.  6.2 показано три
графических  изображения  для  командной  кнопки  Add   Pen
палитры пера.

ЪДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДї ЪДДДДДДДДДДДДДДДДДДї
і               і± і        .....   і і          .....   і±
і   ІІ   Add    і± і   ІІ  : Add :  і і   ІІ    : Add :  і±
і ІІІІІІ Pen    і± і ІІІІІІ: Pen :  і і ІІІІІІ  : Pen :  і±
і   ІІ          і± і   ІІ   .....   і і   ІІ     .....   і±
і               і± і                і і                  і±
АДДДДДДДДДДДДДДДЩ± АДДДДДДДДДДДДДДДДЩ АДДДДДДДДДДДДДДДДДДЩ±
  ±±±±±±±±±±±±±±±±                      ±±±±±±±±±±±±±±±±±±±

     Рис. 6.2       Графические       изображения       для
специализированной кнопки.

             Нумерация ресурсов графических изображений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Единственная сложная часть в  определении  графических
изображений   для   командных  кнопок  -  это  присваивание
идентификаторов ресурсов. Управляющие элементы BWCC знают о
том,    какое    графическое    изображение   использовать,
основываясь  на  идентификаторе  конкретного   управляющего
элемента.  Для  командных  кнопок  в  системах  с  VGA  для
ресурсов используется 1000 + идентификатор  для  "верхнего"
образа,  3000 + идентификатор для "нижнего" образа и 5000 +
идентификатор для образа в фокусе.

           Примечание: В  системах  с   EGA   используются,
      соответственно,  ресурсы 2000 + идентификатор, 4000 +
      идентификатор и 6000 + идентификатор.

     Так как командная кнопка Add Pen  имеет  идентификатор
101  (id_Add),  разрешение использования BWCC принимает вид
ресурсов 1101,  3101 и 5101.  В программе STEP11B.PAS,  для
доступа к специализированными графическим изображениям, для
командных кнопок Add Pen и Del Pen, используется директива:

     {$R PENTAL.RES}

Шаг 12:  Создание специализированного управляющего элемента
окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                    ЪДДДДДДДДДДДДДДДДДДДДДДДї
                    і Step 1: Basic App     і
                    і Step 2: Text          і
                    і Step 3: Lines         і
                    і Step 4: Menu          і
                    і Step 5: About Box     і
                    і Step 6: Pens          і
                    і Step 7: Painting      і
                    і Step 8: Streams       і
                    і Step 9: Printing      і
                    і Step 10: Palette      і
                    і Step 11: BWCC         і
                    іЫStepЫ12:ЫCustomЫctrlsЫі
                    АДДДДДДДДДДДДДДДДДДДДДДДЩ

     Наиболее интересная  часть создания палитры пера - это
создание  вашего  собственного   специализированного   окна
палитры.    Здесь    вы   можете,   наконец,   использовать
возможности, предусмотренные стандартными инструментальными
средствами окон, и что-то создать.

На этом шаге вы сделаете следующее:

* реализуете динамическое изменение размера окна палитры;

* зададите реакцию на уведомляющие сообщения от управляющих
  элементов;

* создадите объект палитры с несколькими областями.

         Динамическое изменение размеров палитры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Так как каждое перо,  которое вы сохраняете в палитре,
имеет один  и  тот  же  размер  (40  элементов  изображения
высотой  и  128  шириной),  вам  нужно убедиться,  что окно
палитры может увеличиваться  и  сжиматься  на  этот  размер
каждый  раз,  когда  вы  удаляете перо.  Объект TPenPalette
определяет два метода, которые позволяют это делать: Grow и
Shrink.

     procedure TPenPalette.Grow
     var WindowRect: TRect;
     begin
       GetWindowRect(HWindow, WindowRect);
       with WindowRect do
           MoveWindow(HWindow, left, top, right - left,
              bottom - top + 40, True);
     end;

     procedure TPenPalette.Shrink;
     var WindowRect: TRect;
     begin
       GetWindowRect(HWindow, WindowRect);
       with WindowRect do
           MoveWindow(HWindow, left, top, right - left,
             bottom - top - 40, True);
     end;

     Оба метода    находят    координаты    границ    окна,
модифицируют их и сообщают  окну,  что  нужно  использовать
новые   координаты   границ.   Функция   API  GetWindowRect
возвращает структуру  TRect,  содержащую  верхнюю,  нижнюю,
левую и правую координату.  Grow добавляет в нижнюю область
окна 40 элементов изображения,  а  Shink  вычитает  тот  же
объем.

     В следующем  разделе  вы узнаете,  как вызывать методы
Grow и Shrink в ответ на нажатие командных кнопок Add Pen и
Del Pen.

              Реакция на события управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Основное различие  между  окном  палитры  и  режимными
диалоговыми окнами,  которые вы использовали ранее, состоит
в  том,   что   режимное   диалоговое   окно   манипулирует
управляющими  элементами,  а  затем  считываете результаты,
если пользователь щелкает "мышью" на командной кнопке OK. В
данном  безрежимном окне палитры вы имеете дело с активной,
динамической частью программы и можете активно отвечать  на
каждый используемый управляющий элемент.

     Пока командные  кнопки  выводятся  в окне палитры,  но
щелчок кнопкой "мыши" не дает никакого  эффекта.  Щелчок  и
выбор "мышью" являются событиями управляющего элемента. Они
аналогичны событиям меню, на которые вы отвечали в шаге 4.

     Вы отвечали на события меню,  определяя методы реакции
на  команды.  Что-то аналогичное нужно делать с сообщениями
управляющих  элементов.   События   управляющих   элементов
создают  сообщения  (на  основе  дочернего идентификатора),
аналогичные командным сообщениям,  но вместо идентификатора
меню  содержащие  идентификатор управляющего элемента.  Для
идентификации  заголовка   метода   на   основе   дочернего
идентификатора     используйте     сумму    идентификаторов
управляющего элемента и констант id_First.

           Примечание: Подробнее о командных  сообщениях  и
      уведомляющих    сообщениях    управляющих   элементов
      рассказывается в Главе 16 "Сообщения окон".


 Имена методов реакции на сообщения управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Как и в случае методов  реакции  на  сообщения,  имена
которым присваиваются по сообщениям,  методы, основанные на
дочерних  идентификаторах,  также  должны  именоваться   по
идентификаторам сообщений. Так как две командные кнопки, на
которые вы хотите реагировать,  имеют идентификаторы id_Add
и id_Del, TPenPalette нужны методы с именами IDAdd и IDDel.

TPenPalette = object(TWindow)
  AddBtn, DelBtn: PBitButton;
  constructor Init(AParent: PWindowsObject; ATitle: PChar);
  procedure Grow;
  procedure SetupWindow; virtual;
  procedure Shrink;
  procedure IDAdd(var Msg: TMessage); virtual
                  id_First + id_Add;
  procedure IDDel(var Msg: TMessage); virtual
                  id_First + id_Del;
end;

     Теперь для выполнения соответствующих действий в ответ
на командные кнопки осталось только определить методы IDAdd
и  IDDel.  Пока что IDAdd должен просто вызывать увеличение
окна, а IDDel - его сжатие

     procedure TPenPalette.IDAdd(var Msg: TMessage);
     begin
       Grow;
     end;

     procedure TPenPalette.IDDel(var Msg: TMessage);
     begin
       Shrink;
     end;

           Примечание: Это   дополняет   содержимое   файла
       STEP12A.PAS.

                    Добавление "кнопок" палитры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Теперь, когда у вас есть окно палитры,  вам  необходим
просто  способ  вывода  на экран и выбора перьев в палитре.
Для  этого  вы  можете  использовать  относительно  простой
потомок TWindow и набор объектов пера.

     В данном разделе вы сделаете следующее:

     * определите объект палитры пера;

     * выберете перья по щелчку кнопкой "мыши".


                    Определение объекта палитры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Так как  окно палитры пера может изменять свой размер,
палитра в окне может фактически  оставаться  фиксированной.
Чтобы показать только часть палитры, в которой отображаются
перья,  вы  можете   использовать   возможности   отсечения
Windows.

     Самой палитре   необходимы   только   несколько  полей
данных:  набор перьев,  указание того,  какое перо в данный
момент    выбрано,   и   описатели   представляющих   перья
графических  образов.  Описатели  графических   изображений
представляют  собой частные поля не потому,  что они должны
быть секретными,  а для предотвращения их непреднамеренного
изменения другим кодом.

     Приведем описание объекта палитры:

     TPenPic = object(TWindow)
        PenSet: PCollection;
        CurrentPen: Integer;
        constructor Init(AParent: PWindowsObject);
        destructor Done: virtual;
        procedure Paint(PaintDC: HDC; var PaintInfo:
                        TPaintStruct); virtual;
        procedure AddPen(APen: PPen);
        procedure DeletePen;
        procedure SetupWindow; virtual;
        procedure WMLButtonDown(var Msg: TMessage);
                        virtual wm_First + wm_LButtonDown;
     private
       UpPic, DownPic: HBitMap;
     end;

     Объекту TPenPic  не требуется очень много методов.  Он
имеет простой конструктор  для  создания  набора  перьев  и
деструктор  для  их  уничтожения.  Метод SetupWindow просто
перемещает палитру внутри ее порождающего  окна.  AddPen  и
DeletePen включают перо в набор и удаляют перо из набора, а
WMLButtonDown  интерпретирует  щелчки  "мышью"  для  выбора
перьев   из   палитры.   Наконец,  Paint  рисует  "кнопки",
представляющие перья в наборе.

     Отметим также,  что TPenPic является потомком TWindow,
а  не  TControl.  Хотя  поведение  вашего нового объекта во
многом напоминает поведение управляющего элемента окна,  он
должен  быть  производным  от  TWindow,  так  как  TControl
работает только со  стандартными  управляющими  элементами,
такими   как   "нажимаемые"   командные   кнопки  и  полосы
прокрутки.  При создании собственных управляющих  элементов
нужно начинать с TWindow.



                   Создание и уничтожение палитры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Построение и уничтожение объекта  палитры  выполняется
достаточно просто.  Конструктор Init вызывает TWindow.Init,
затем изменяет стиль окна (чтобы оно стало видимым дочерним
окном).  PenSet  инициализируется  как набор фиксированного
размера,  достаточно большой,  чтобы содержать максимальное
число    заданных   константой   MaxPens   перьев,   и   не
возрастающий.  Для  текущего  выбранного  пера   CurrentPen
устанавливается  в  -1.  Это означает,  что выбранного пера
нет.

     Наконец, Init  загружает  в  UpPic   и   DownPic   два
графических  образа.  Они  используются в качестве фона для
каждого пера палитры.  DownPic рисуется за выбранным пером,
а UpPic - в качестве фона других перьев.

            ±±±±±±±±±±±±±±±±±±±
            ±ЪДДДДДДДДДДДДДДДДДДї    ЪДДДДДДДДДДДДДДДДДДї
            ±і                  і    і                  і±
            ±і                  і    і                  і±
            ±і                  і    і                  і±
             АДДДДДДДДДДДДДДДДДДЩ    АДДДДДДДДДДДДДДДДДДЩ±
                                       ±±±±±±±±±±±±±±±±±±±

     Рис. 6.3 Фоновые образы палитры пера.

     Деструктор Done перед вызовом наследуемого деструктора
Done отменяет графические образы.  Вызов  DeleteObject  для
уничтожения  графических  образов  имеет  важное  значение.
Подобно  контексту  дисплея,  графические  образы  являются
ресурсами  Windows,  поддерживаемыми  в ограниченной памяти
Windows. Если размещаете их в памяти Windows и не удаляете,
то  ваша  программа  (и другие работающие параллельно с ней
программы) потеряют доступ к этой памяти.

   Init и Done объекта палитры выглядят следующим образом:

     constructor TPenPic.Init(AParent: PWindowsObject);
     begin
       inherited Init(AParent, nil);
       AttrStyle := ws_Child or ws_Visible;
       PenSet := New(PCollection, Init(MaxPens, 0));
       CurrentPen := -1;
       UpPic := LoadBitMap(HInstance, 'PAL_UP');
       DownPic := LoadBitmap(HInstance, 'PAL_DOWN');
     end;

     destructor TPenPic.Done;
     begin
       DeleteObject(UpPic);
       DeleteObject(DownPic);
       Dispose(PenSet, Down);
       inherites Done;
     end;

                   Размещение в порождающем окне
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Как вы могли заметить,  TPenPic не задает свою позицию
в конструкторе так,  как это делают большинство управляющих
элементов. Причина здесь в том, что вы не можете полагаться
на координаты окна, пока оно не будет реально существовать.
TPenPalette  обходит  эту  проблему,  создавая свои объекты
кнопок путем вызова для определения высоты  заголовка  окна
функции  API  GetSystemMetrics.  Хотя  это  будет работать,
существует и другой подход.

     Вместо позиционирования  палитры  в  конкретное  место
порождающего  окна  вы  можете поместить его в определенную
позицию в порождающей области клиента.  Таким образом, если
вы добавляете меню или изменяете рамку, либо выполняете вне
окна какое-либо другое изменение,  ваш объект  палитры  все
равно будет правильно позиционирован.

     Изменение позиции окна выполняется в SetupWindow,  так
как окну палитры требуется  использовать  описатель  своего
порождающего  окна,  который  до вызова собственного метода
SetupWindow недоступен. При достижении SetupWindow дочернее
окно   может   рассчитывать   на   допустимость   описателя
порождающего окна.

     procedure TPenPic.SetupWindow;
     var ClientRect: TRect;
     begin
       inherited SetupWindow;
       GetClientRect(Parent^.HWindow, ClientRect);
       with ClientRect do
         MoveWindow(HWindow, 1, bottom - top + 1, 128,
                    40 * MaxPens, False;
     end;

     Для возврата координат области  клиента  окна  палитры
метод    TPicPen    использует    функцию    API    Windows
GwetClientRect.  Затем  он  перепозиционируется  с  помощью
MoveWindow  непосредственно  под  объекты  кнопок,  задавая
высоту,  достаточную для размещения всех перьев  в  наборе.
Заметим,  что  последний параметр MoveWindow - это значение
типа Boolean,  указывающее,  следует ли выполнять повторное
отображение  окна  после  перемещения.  Так  как палитра на
экран пока не выводилась,  то заново отображать ее не имеет
смысла,   поэтому   TPenPic.SetupWindow  передает  значение
False.





                    Добавление и удаление перьев
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В последнем  разделе  вы  отвечали на сообщения от Add
Pen (Добавить перо) и Del  Pen  (Удалить  перо)  изменением
размера  окна  палитры.  Теперь  настало время изменить эту
реакцию  и  фактически  добавлять  или  удалять  перья   из
палитры,  что  в  свою  очередь  указывает  окну палитры на
необходимость изменения размера.  Вместо вызова собственных
методов  Grow  и  Shrink  методы  объекта  палитры AddPen и
DeletePen должны вызывать соответственно,  методы  IDAdd  и
IDDel в TPenPalette.

     procedure TPenPalette.IDAdd(var Msg: TMessage);
     begin
       Pens^.AddPen(CommonPen);
     end;

     procedure TPenPalette.IDDel(var Msg: TMessage);
     begin
       Pens^.DeletePen;
     end;

     Метод AddPen воспринимает передаваемое перо,  копирует
его в набор и отмечает перо,  как текущее выбранное.  Затем
он разрешает кнопку Del Pen в окне палитры пера,  запрещает
кнопку Add Pen,  если набор полон,  и сообщает порождающему
окну  о  необходимости увеличения размера,  чтобы поместить
новое перо.

procedure TPenPic.AddPen(APen: PPen);
begin
  CurrentPen := PenSet^.Count;
  with APen^ do PenSet^.Insert(New(PPen, Init(Style, With,
                               Color)));
  with PPenPalette(Parent)^ do
  begin
    DelBtn^.Enable;
    if PenSet^.Count >= MaxPens tnen
       AddBtn^.Disable;
    Grow;
  end;
end;

      Примечание: Чтобы использовать преимущества  средств,
 специфических  для  TPenPAlette,  TPenPic  может выполнять
 приведение типа поля Parent.  Большинство оконных объектов
 не  связаны  так жестко с конкретным порождающим типом,  и
 поэтому   не   должны   делать    никаких    предположений
 относительно типа порождающих их окон.

     Метод DeletePen  по  существу изменяет действия AddPen
на обратные.  При наличии выбранного  в  палитре  пера  оно
удаляется  из  набора,  а  набор уплотняется таким образом,
чтобы перья размещались непрерывно. Затем он указывает, что
в  данный  момент выбранных перьев нет (поскольку выбранное
перо только что удалено) и запрещает командную  кнопку  Del
Pen,  так как Del Pen работает с выбранным пером.  Далее он
разрешает  кнопку  Add   Pen,   поскольку   удаление   пера
автоматически  освобождает  место  для  по крайней мере еще
одного пера.  Наконец,  он сообщает  порождающему  окну  на
необходимость  уменьшения  его размера (так выводить теперь
нужно меньше перьев).

     procedure TPenPic.DeletePen;
     begin
       if CurrentPen > -1 then
       begin
         PenSet^.AtFree(CurrentPen);
         PenSet^.Pack;
         CurrentPen := -1;
         with PPenPelette(Parent)^ do
         begin
           AddBtn^.Enable;
           DelBtn^.Disable;
           Shrink;
         end;
       end;
     end;

     Заметим, что    AddPen    и    DeletePen    используют
преимущества   того   факта,  что  окна  палитры  пера  для
упрощения  связи  с  методами  имеет  указатели   на   свои
командные кнопки.  Если бы TPenPalette не имел полей AddBtn
и DelBtn,  то объекту палитры  пришлось  бы  искать  их  по
идентификаторам и посылать им сообщения, либо нужно было бы
послать сообщение порождающему окну, которое в свою очередь
должно каким-то образом связываться с командными кнопками.



                  Отображение содержимого палитры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     За все,  что  мы  насоздавали   в   объекте   палитры,
приходится расплачиваться, когда приходит момент отображать
ее на  экране.  Поскольку  перья  хранятся  в  наборе,  для
отображения   каждого   пера   вы  легко  можете  выполнять
итерацию.  В самом деле,  метод  Paint  состоит  только  из
инициализации   локальной   переменной-счетчика,   а  затем
выполняет итерацию по набору с помощью ForEach:

procedure TPenPic.Paint(PaintDC: HDC;
                        var PaintInfo: TPaintStruct);
var PenCount: Integer;

   procedure ShowPen(P: PPen); far;
   var
     MemDC: HDC;
     TBitmap: HBitmap;
   begin
     MemDC := CreateCompatibleDC(PaintDC);
     Inc(PenCount);
     if PenCount = CurrentPen then
          TheBitmap = DownPic;
     else TheBitmap := UpPic;
     SelectObject(MemDC, TheBitmap);
     BitBlt(PaintDC, 0, PenCount * 40, 128, 40, MemDC, 0,
            0, SrcCopy);
     P^.Select(PaintDC);
     MoveTo(PaintDC, 15, PenCount * 40 + 20);
     LineTo(PaintDC, 115, PenCount * 40 + 20);
     P^.Delete;
     DeleteDC(MemDC);
   end;

begin
  PenCount := -1;
  PenSet^.ForEach(@ShowPen);
end;

     Наиболее интересная часть содержится не в Paint,  а во
вложенной процедуре ShowPen, которая вызывается для каждого
пера  в  палитре.  На  самом  деле  ShowPen состоит из двух
различных частей.  Первая  рисует  графическое  изображение
фона,  а  вторая  (которая  уже  должна быть вам достаточно
знакома) использует объект пера для  изображения  по  этому
фону образца линии.

     Изображение графических  образов  предусматривает  три
шага:  создание  контекста  устройства  памяти,   выбор   в
контексте  устройства  графического  образа  и  копирование
образа в контекст экрана.

     Как вы видели в шаге 8,  для различных видов устройств
существует  различные  контексты  устройства.  Для работы с
графическими   образами   (битовыми   массивами)    Windows
позволяет создавать контекст устройства памяти. Фактически,
вы можете  только  выбирать  битовые  массивы  в  контексте
устройства  памяти,  хотя  они  могут копироваться в другие
контексты устройства.

     Метод CreateMemoryDC    создает    пустой     контекст
устройства памяти,  совместимый с текущим PaintDC. Затем, в
зависимости от того,  является ли  данное  конкретное  перо
выбранным,   ShowPen   выбирает   в   контексте  устройства
графические  образы  UpPic  или  DownPic.  Заметим,  что  в
контексте     устройства     памяти    графический    образ
интерпретируется аналогично любому другому изобразительному
средству.  Наконец,  функция BitBlt копирует заданную часть
контекста  устройства  памяти  в  PaintDC.   Заметим,   что
контекст устройства памяти требуется уничтожать.

     После того как фон будет на месте,  ShowPen использует
ShowTo и LineTo  аналогично  тому,  как  это  делается  при
рисовании непосредственно в окне.

                   Выбор перьев с помощью "мыши"
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Наконец. TPenPic  обеспечивает  реакцию  на  щелчок  в
нарисованной  области  кнопкой  "мыши".  Заметим,  что хотя
размер объекта палитры никогда не изменяется,  он  получает
сообщение   от   щелчков   "мышью"  в  области,  фактически
показываемой на  экране.  Палитра  отсекается  рамкой  окна
палитры. Это означает, что вы можете щелкать кнопкой "мыши"
только непосредственно в палитре.

     Поскольку каждый элемент в палитре имеет один и тот же
размер, WMLButton для определения того, в каком графическом
образе была нажата кнопка "мыши",  может  просто  разделить
y-координату  щелчка  "мыши" (которая поступает в LParamHi)
на 40 (размер каждого графического изображения).  Затем  он
делает перо, на котором была нажата кнопка "мыши" текущим и
задает в качестве пера для рисования копию выбранного  пера
палитры. Поскольку теперь есть выбранное перо, он разрешает
кнопку Del Pen в окне палитры,  затем запрещает палитру для
обеспечения  ее  повторного  отображения  для  того,  чтобы
показать новый выбор.

     Код для  WMLButtonDown  имеет   следующий   вид   (это
дополняет текст STEP12B.PAS):

procedure TPenPic.WMLButtonDwon(var Msg: TMessage);
begin
  CurrentPen := Msg.LParamHi div 40;
  if CurrentPen <> nil then Dispose(CurrentPen, Done);
  with PPen(PenSet^.At(CurrentPen))^ do
      CurrentPen := New(PPen, Init(Style, With, Color));
  PPenPalette(Parent)^.DelBlt^.Enable;
  InvalidateRect(HWindow, nil, False);
end;

                       Что дальше?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Есть много дополнений и изменений,  которые вы  можете
внести в программу Steps,  чтобы сделать ее более полезной.
Версию  программы  Steps,  которая  включает  в  себя   эти
изменения, вы можете найти в файле GRAFFITI.PAS.

     Программа Graffiti содержит следующие изменения:

     * Многодокументальный интерфейс (MDI).

     * Сглаживание линий.

     * Отмена.

     * Улучшает поведение окна палитры.

     * Прокрутка.


                   Многодокументальный интерфейс
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TStepWindow может  очень  легко  работать  в  качестве
дочернего окна MDI.  Фактически  с  небольшими  изменениями
программа  Graffiti  использует  в  качестве своих дочерних
окон те же окна,  что Steps использует для основного  окна.
Так  как  владельцем  окна  палитры  пера  является  объект
TStepWindow,   каждый   отдельный   рисунок   имеет    свой
собственный  отличный  набор перьев.  О многодокументальном
интерфейсе рассказывается в Главе 14 "Объекты MDI").

                         Сглаживание линий
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для сложных   рисунков  со  многими  длинными  линиями
повторное  отображение  рисунка  может  потребовать   много
времени.    Graffiti   использует   одно   из   преимуществ
графический функций GDI - функцию PolyLine,  которая рисует
сегменты каждой линии сразу, а не по одному. Эффектом будет
более быстрое и плавное отображение окна.

                               Отмена
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Поскольку рисунок   состоит   из  наборов  линий,  для
стирания последней нарисованной  линии  легко  использовать
методы  наборов.  Graffiti связывает элемент меню EditіUndo
(РедактированиеіОтмена) с набором  линий  метода  AtDelete,
удаляя  последнюю  линию  в наборе,  которая является также
последней нарисованной линией.  Повторяя удаление последней
линии   в   наборе,   вы   можно  эффективно  отменять  все
изображение.

     Хотя программа Graffiti этого  не  делает,  вы  можете
добавить   также  функцию  Redo  (Возобновление),  сохраняя
удаленные линии в другом наборе,  и перемещая их по одной в
набор отображаемых линий, либо даже в другой рисунок.

                         Поведение палитры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вы можете также отметить, что при щелчке "мышью" между
палитрой и основным окном,  окно,  где вы нажимаете кнопку,
становится активным (получает  активную  рамку),  а  другие
окна  становятся  неактивными.  Если вы часто перемещаетесь
между двумя окнами (что может  иметь  место  при  работе  с
палитрой),  это может показаться весьма раздражающим. Чтобы
предотвратить это явление, вам нужно перехватывать передачу
в  окна  сообщений  sm_NCActivate,  и когда параметр WParam
сообщений равен 0 (попытка деактивизации рамки),  вы можете
изменить его на 1 (активизация рамки):

procedure TPenPalette.WVNCActivate(var Msg: TMessage);
begin
  if Msg.WParam = 0 then Msg.WParam := 1;
  DefWndProc(Msg);
end;

     Вызов DefWndProc     обеспечивает,    что    сообщение
обрабатывается  как  обычно,  но   теперь   рамка   палитры
деактивизироваться не будет. Аналогичный перехват вы можете
добавить в TStepWindow.

                             Прокрутка
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Наконец, так  как  каждое  дочернее  окно  MDI  обычно
невелико  по  размеру,   Graffiti   добавляет   возможность
автоматической   прокрутки  изображения  при  рисовании.  В
программе Steps,  когда перо выходит за границы окна, линия
продолжает рисоваться,  хотя видеть ее вы больше не можете.
Graffiti прокручивает изображение, так что вы будете видеть
другие части рисунка.


                Часть 2. Использование ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


                   Глава 7. Иерархия ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows представляет собой  исчерпывающий  набор
объектов,  облегчающий  разработку  программ  для Microsoft
Windows  на  Паскале.  В  данной  главе  вы  найдете  обзор
иерархии объектов ObjectWindows.  В остальных главах данной
части дается детальное описание различных частей иерархии.

     Кроме описания  иерархии  объектов,  в  данной   главе
описываются    основные   принципы   программирования   для
операционной среды Windows, включая вызов API Windows.

                         Соглашения Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Соглашения по    именам   ObjectWindows   обеспечивают
ясность и содержательность имен.


                           Имена объектов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Имена всех   объектный   типов,   предусмотренных    в
ObjectWindows,  начинаются  с  буквы T.  Например,  объекты
диалоговых окон имеют тип TDialog.  Для каждого определения
объектного  типа  имеется  соответствующий  ссылочный  тип,
начинающийся с P. Например, указатель на TDialogh имеет тип
PDialog.  В  примерах данного руководства будут создаваться
динамические  экземпляры  объектов,  например,  с   помощью
PDialog  позволяет разместить объекты TDialog в динамически
распределяемой области памяти.

                           Имена методов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Методы реакции   на  сообщения  называются  по  именам
сообщений,  на которые они отвечают,  но без подчеркиваний.
Например,  метод,  отвечающий на сообщение wm_KeyDown будет
называться WMKeyDown.


                           Обзор объектов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                          Иерархия объектов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows - это иерархия объектных типов,  которые
вы можете использовать для работы  с  большинством  обычных
задач    в   приложении   ObjectWindows.   Схема   объектов
пользовательского интерфейса библиотеки  показана  на  Рис.
7.1.   На   Рис.   7.2   представлены   объекты   иерархии,
используемые  для  управления   данными   и   проверки   их
допустимости.

     ЪДДДДДДДДДДДДДДДДї
     і    TObject     і
     АДДДДДДДВДДДДДДДДЩ
        ЪДДДДБДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДВДДДДДДДДДДДї
ЪДДДДДДДБДДДДДДДДї ЪДДДДДДДДБДДДДДДДї ЪДДДДДДДБДДДДДДДДї  і
і   TPrintout    і і    TPrinter    і і TWindowsObject і  і
АДДДДДДДВДДДДДДДДЩ АДДДДДДДДДДДДДДДДЩ АДДДДДДДВДДДДДДДДЩ  і
        ГДДДДДДДДДДДДДДДДДДДї                 і           і
ЪДДДДДДДБДДДДДДДДї ЪДДДДДДДДБДДДДДДДї  ЪДДДДДДЩ           і
і TEditPrintout  і і TWindowPrintoutі  і        ЪДДДДДДДДДґ
АДДДДДДДДДДДДДДДДЩ АДДДДДДДДДДДДДДДДЩ  і        і         і
                                       іЪДДДДДДДБДДДДДї   і
       ЪДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДЩіTApplication і   і
       і                    і          АДДДДДДДДДДДДДДЩ   і
ЪДДДДДДБДДДДДДДДДї ЪДДДДДДДДБДДДДДДДї        ЪДДДДДДДДДДДДЩ
і    TDialog     і і   TWindow      і        і
АДДДДДДВДДДДДДДДДЩ АДДДДДДДДВДДДДДДДЩЪДДДДДДДБДДДДДДДДї
       і                    і        і   TScroller    і
       і                    і        АДДДДДДДДДДДДДДДДЩ
       і                    АДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
       ГДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДї                 і
ЪДДДДДДБДДДДДДДДДї ЪДДДДДДДБДДДДДДДДї  і                 і
і  TFileDialog   і і TInputDialog   і  і                 і
АДДДДДДДДДДДДДДДДЩ АДДДДДДДДДДДДДДДДЩ  і                 і
       ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДЩ                 і
ЪДДДДДДБДДДДДДДДДДДДї         і                          і
іTPrinterAbortDialogі         ГДДДДДДДДДДДДї             і
АДДДДДДДДДДДДДДДДДДДЩ         і            і             і
                              і   ЪДДДДДДДДБДДДДДДДї     і
        ЪДДДДДДДДДДДДДДДДДДДДДґ   і  TPrintDialog  і     і
ЪДДДДДДДБДДДДДДДДї            і   АДДДДДДДДДДДДДДДДЩ     і
іTPrinterSetupDlgі            АДДДДДДДДДДДДї             і
АДДДДДДДДДДДДДДДДЩ                         і             і
                                  ЪДДДДДДДДБДДДДДДДї     і
                                  і   TDlgWindow   і     і
                                  АДДДДДДДДДДДДДДДДЩ     і
                                                         і
                                                         і
        ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДВДДДДДДДДДДґ
ЪДДДДДДДБДДДДДДДДї ЪДДДДДДДБДДДДДДДДї ЪДДДДДДДБДДДДДДДДї і
і    TControl    і і   TMDIClient   і і   TMDIWindow   і і
АДДДДДДДВДДДДДДДДЩ АДДДДДДДДДДДДДДДДЩ АДДДДДДДДДДДДДДДДЩ і
        ГДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДї          ЪДДДДДДЩ
ЪДДДДДДДБДДДДДДДДї ЪДДДДДДДБДДДДДДДДї  і  ЪДДДДДДДБДДДДДДї
і    TButton     і і   TScrollBar   і  і  і  TEditWindow і
АДДДДДДДВДДДДДДДДЩ АДДДДДДДДДДДДДДДДЩ  і  АДДДДДДДВДДДДДДЩ
ЪДДДДДДДБДДДДДДДДї                     і  ЪДДДДДДДБДДДДД-ї
і   TCheckBox    і         ЪДДДДДДДДДДДґ  і  TFileWindow і
АДДДДДДДВДДДДДДДДЩ         і           і  АДДДДДДДДДДДДДДЩ
ЪДДДДДДДБДДДДДДДДї ЪДДДДДДДБДДДДДДДДї  ГДДДДДДДДДДї
і  TRadioButton  і і    TStatic     і  і          і
АДДДДДДДДДДДДДДДДЩ АДДДДДДДВДДДДДДДДЩ  і          і
                           і           і  ЪДДДДДДДБДДДДДДї
                   ЪДДДДДДДБДДДДДДДДї  і  і    TListBox  і
                   і     TEdit      і  і  АДДДДДДДВДДДДДДЩ
                   АДДДДДДДДДДДДДДДДЩ  і          і
                                       і  ЪДДДДДДДБДДДДДДї
                           ЪДДДДДДДДДДДЩ  і   TComboBox  і
                           і              АДДДДДДДДДДДДДДЩ
                   ЪДДДДДДДБДДДДДДДДї
                   і    TGroupBox   і
                   АДДДДДДДДДДДДДДДДЩ

Модуль OPRINTER: Модуль OWINDOWS: Модуль OSTDDLGS:

TPrinout            TWindow             TInputDialog
TPtinter            TAppication         TInputDialog
TEditPrintout       TScroller
TWindowPrintout
TPrinterAbortDlg
TPrintDialog
TPrinterSetup

Модуль ODUIALOGS:   Модуль OSTDWNDS:

TDialog             TEditWindow
TDlgWindow          TFileWindow
TButton
TScrollBar
TCheckBox
TRadioButton
TControl
TStatic
TEdit
TListBox
TComboBox
TGroupBox

     Рис. 7.1. Иерархия объектных типов ObjectWindows.


     ЪДДДДДДДДДДДДДДДДї
     і    TObject     і
     АДДДДДДДВДДДДДДДДЩ
        ЪДДДДБДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДї
ЪДДДДДДДБДДДДДДДДї  ЪДДДДДДДБДДДДДДДДї   ЪДДДДДДДБДДДДДДї
і   TValidator   і  і   TCollection  і   і    TStream   і
АДДДДДДДВДДДДДДДДЩ  АДДДДДДДДДДДДДДДДЩ   АДДДДДДДДДВДДДДЩ
        ГДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДї АДДДДДДї
ЪДДДДДДДБДДДДДДДДДДДї ЪДДДДДДДБДДДДДДДДї ЪДДДДДДДБДДДДДДї і
іTPXPictureValidatorі іTFilterValidatorііTLookupValidatorіі
АДДДДДДДДДДДДДДДДДДДЩ АДДДДДДДВДДДДДДДДЩ АДДДДДДДВДДДДДДЩ і
                      ЪДДДДДДДБДДДДДДДДДї        і        і
                      і TRangeValidator і     ЪДДЩ        і
                      АДДДДДДДДДДДДДДДДДЩ     і           і
                                   ЪДДДДДДДДДДБДДДДДДДДДї і
                                 іTStringLookupValidatorі і
                                   АДДДДДДДДДДДДДДДДДДДДЩ і
        ЪДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДВДДДДДДДДДЩ
ЪДДДДДДДБДДДДДДДДї  ЪДДДДДДДБДДДДДДДДї  ЪДДДДДДДБДДДДДДДї
і TMemoryStream  і  і   TDosStream   і  і   TEmsStream  і
АДДДДДДДДДДДДДДДДЩ  АДДДДДДДВДДДДДДДДЩ  АДДДДДДДДДДДДДДДЩ
                    ЪДДДДДДДБДДДДДДДДї
                    і   TBufStream   і
                    АДДДДДДДДДДДДДДДДЩ

     Рис. 7.2   Иерархия   наборов,   потоков   и  проверки
допустимости.

Модуль OBJECTS:        Модуль VALIDATE:

TObject                TValidator
TCollection            TPXPictureValidator
TSortedCollection      TFilterValidator
TStrCollection         TRangeValidator
TStringCollection      TLookupValidator
TStream                TStrongLookupValidator
TMemoryStream
TEmsStream
TDosStream
TBufStream

                    Базовый объект

     TObject - это базовый объектный тип, общий предок всех
объектов   ObjectWindows.   Он   определяет   рудиментарный
конструктор  и  деструктор.  Потоки  ObjectWindows требует,
чтобы записанные объекты были потомками TObject.

                          TApplication

     Этот тип определяет поведение,  необходимое  для  всех
приложений ObjectWindows.  Каждое приложение ObjectWindows,
которое  вы  пишете,   будет   определять   объектный   тип
приложения, производный от TApplication. Объекты приложения
подробно описываются в Главе 8 "Объекты приложения".

                      Интерфейсные объекты

     Остальные объекты     в     иерархии     ObjectWindows
классифицируются  в  общем случае как интерфейсные объекты.
Они являются интерфейсными в том смысле,  что  представляют
элементы  и  пользовательском  интерфейсе  Windows и служат
интерфейсом  между  кодом  вашей  прикладной  программы   и
операционной    средой    Windows.   Интерфейсные   объекты
описываются в Главе 9.

                         Объекты Windows

     Объекты Windows  представляются  не  только  знакомыми
окнами   среды   Windows,   но  и  большинством  визуальных
инструментов операционной  среды,  такими  как  управляющие
элементы.

                    Объекты диалоговых блоков

     Объекты диалоговых    блоков    (окон)    обеспечивают
временные окна для обслуживания специальных функций ввода и
вывода.   В  общем  случае  они  включат  в  себя  текст  и
управляющие элемента,  такие как  командные  кнопки,  блоки
списка  и  полосы прокрутки.  Об объектах диалоговых блоков
подробно рассказывается в Главе 11.

                  Объекты управляющих элементов

     В диалоговых  блоках  и  некоторых  окнах  управляющие
элементы  позволяют пользователям вводить данные и выбирать
параметры.  Объекты  управляющих   элементов   обеспечивают
согласованные и простые средства для работы со всеми типами
управляющих  элементов,  определенных  в  Windows.  Объекты
управляющих элементов подробно описываются в Главе 12.

                           Объекты MDI

     Windows реализует  стандарт  для  работы с несколькими
документами  в  рамках  одного  окна,  которое   называется
множественным     документальным     интерфейсом     (MDI).
ObjectWindows обеспечивает средства для установки окон  MDI
и  работы с ними.  Объекты MDI подробно описываются в Главе
14.
                  Объекты проверки допустимости

     ObjectWindows содержит полный набор объектов  проверки
допустимости    данных,    которые    позволяют   проверять
допустимость данных,  введенных пользователем,  при  выходе
пользователя  из  поля  или  когда  пользователь  завершает
работу с окном.  Проверка допустимости данных описывается в
Главе 13.

                        Объекты принтера

     Для работы с печатью документов или печати содержимого
окна ObjectWindows предусматривает соответствующие объекты.
О том, как использовать эти объекты, рассказывается в Главе
15.

                    Объекты наборов и потоков

     Модуль Object включает в себя многочисленные  объекты,
реализующие  гибкие структуры данных и потоки,  позволяющие
считывать и записывать объекты.  Наборы описываются в Главе
19, а потоки - в Главе 20.


                        Файлы ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Перечисленные выше  типы  ObjectWindows  реализует   в
скомпилированных   модулях.   В   данном   разделе   кратко
описывается  содержимое  поставляемых  модулей.  В   каждом
приложении ObjectWindows требуется только модуль OWindows.

     В данной версии ObjectWindows различные части иерархии
объектов разбивают различные  части  иерархии  объектов  по
отдельным     моделям.    Чтобы    перекомпилировать    код
ObjectWindows более ранних версий,  в  общем  случае  нужно
изменить  все  ссылки  на  модуль  WObjects  на  OWindows и
добавить к программам  и  модулям,  использующим  наборы  и
потоки  или  диалоговые  блоки,  соответственно  Objects  и
ODialogs.

     В данную версию ObjectWindows  добавлены  также  новые
модули  для  печати,  проверки  данных,  специализированных
управляющих элементов Borland и поддержки Windows 3.1.

     В Таблице   7.1   перечислены   модули,   составляющие
интерфейс   ObjectWindows   и  AOPI  Windows  3.0.  Модули,
поддерживающие  расширения  Windows  3.1,  представлены   в
Таблице 7.2.

Модули для ObjectWindows и API Windows   Таблицы 7.1
ЪДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іМодуль  і             Содержимое                       і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іObjects і Базовый объект TObject, наборы, потоки.      і
іOWindowsі Приложения, окна, полосы прокрутки, окна MDI.і
іODialogsі Диалоговые блоки, диалоговые окна,  управляю-і
і        і щие элементы.                                і
іOPrinterі Печать, специальные распечатки.              і
іValidateі Проверка допустимости данных.                і
іBWCC    і Специализированные управляющие элементы фирмыі
і        і Borland.                                     і
іOStdDlgsі Диалоговые блоки  имен  файлов,  однострочныйі
і        і ввод.                                        і
іOStdWndsі Окна  текстового  редактора,  окна  редактораі
і        і файлов.                                      і
іWinTypesі Все  типы,  используемые  подпрограммами  APIі
і        і Windows 3.0, включая записи, стили, сообщенийі
і        і и флаги.                                     і
іWinProcsі Описания  процедур  и функций для API Windowsі
і        і 3.0.                                         і
АДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ



                   Файлы ресурсов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Модули OStdDlgs, OStdWnds и OPrinter имеют связанные с
ними файлы ресурсов.  Ресурс модуля  находится  в  файле  с
именем,  эквивалентным  имени  модуля,  и расширением .RES.
Ресурсы   автоматически   включаются   при    использовании
соответствующих   модулей,   так   что  программа,  которая
использует  модуль  OstdDlgs,  будет  автоматически   иметь
доступ к ресурсам в OSTDDLGS.RES.

                         Файлы Windows 3.1
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Кроме стандартных модулей API Windows 3.0,  вы  можете
писать   программы,   использующие   преимущества  средств,
добавленных в версию 3.1 Windows.  Каждая из 11 DLL Windows
3.1 имеет соответствующий модуль:

Модули для доступа к средствам Windows 3.1  Таблица 7.2
ЪДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іМодуль  і                     Средство                 і
ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іComDlg  і Общие диалоговые блоки.                      і
іDDTML   і Сообщения динамического обмена данными.      і
іDlgs    і Константы диалогового блока.                 і
іLZExpandі Расширения файла LZ.                         і
іMMSystemі Расширения мультимедиа.                      і
іOLE     і Компоновка и встраивание объектов (OLE).     і
іShellAPIі Оболочка API Windows.                        і
іStress  і Строгая проверка типов.                      і
іToolHelpі Отладка и другие инструментальные средства.  і
іVer     і Версии.                                      і
іWin31   і Расширения Windows 3.1.                      і
АДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

              Взаимодействие с Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows избавляет  вас  от многих утомительных и
запутанных   частей   Windows,    но    иногда    возникает
необходимость  в  непосредственном взаимодействии с Windows
(например,  когда  вы   хотите   переопределить   некоторое
заданное  в Windows поведение или выйти за рамки того,  что
инкапсулировано в ObjectWindows).

     Существует два способа,  с помощью которых  вы  можете
взаимодействовать  с ObjectWindows:  вызов ее функций API и
получение сообщений.  В данном разделе описываются  функции
API.  Об  обработке  сообщений  рассказывается  в  Главе 16
"Сообщения Windows".

                        Функции API Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Функциональные возможности   Windows  заключены  в  ее
около   600   функций.   Каждая    функция    имеет    имя.
Взаимодействовать    с    операционной    средой   Windows,
модифицировать ее отображение или действие в ответ на  ввод
пользователя  можно с помощью вызова функций API.  Однако с
помощью ObjectWindows вы можете  создавать  окна,  выводить
диалоговые  блоки и манипулировать управляющими элементами,
не вызывая функций Windows. Как все это работает?

                 Вызов в ObjectWindows функций API
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Методы ObjectWindows    вызывают   функции   API.   Но
ObjectWindows   -   это   не   дублируемые   функциональные
возможности;    она    предоставляет    в    новом   пакете
объектно-ориентированной  библиотеки  функции  Windows,  ее
прикладной   программный   интерфейс   (API).  Кроме  того,
ObjectWindows  значительно  упрощает  задачи   спецификации
многочисленных  параметров,  требуемых  в функциях Windows.
Часто ObjectWin- dows автоматически подставляет  параметры,
такие  как  описатели  окон и идентификаторы дочерних окон,
которые хранятся в интерфейсных объектах в виде полей.

     Например, многие функции Windows для задания  окна,  с
которым они должны работать,  используют описатели окна,  и
эти функции вызываются обычно из методов оконного  объекта.
Объекты  содержат в поле HWindow описатель соответствующего
окна  и   может   передавать   его,   освобождая   вас   от
необходимости каждый раз задавать описатель. Таким образом,
объектные         типы         ObjectWindows         служат
объектно-ориентированным  слоем,  реализованным  с  помощью
вызовов необъектно-ориентированных функций API.

                       Доступ к функциям API
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы из     приложения    ObjectWindows    обратиться
непосредственно к  функциям  API,  вы  должны  использовать
модуль  WinProcs.  WinProcs  определяет  для каждой функции
Windows  заголовок  процедуры  или  функции  Паскаля,   что
позволяет   вам   вызывать   функции   Windows   как  любую
подпрограмму на Паскале.  Перечень заголовков этих  функций
вы  можете  найти  в  файле  WINPROCS.PAS или в оперативном
справочнике Help.

                         Константы Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Функции Windows  требуют  от  вас  передачи в качестве
аргументов разнообразных констант типа  Word  или  Longint.
Эти  константы  представляют стили окна,  диалогового блока
или управляющего элемента,  а также возвращаемые значение и
др.  Если  в  программе используются данные константы,  она
становится более  читаемой,  обслуживаемой  и  будет  более
независимой от изменений в последующих версиях Windows, чем
программы,  использующие  числа.  Определенные   в   модуле
WinTypes  константы  описываются  в Главе 21 "Справочник по
ObjectWindows".

                       Записи данных Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Некоторые функции   Windows   требуют   более  сложных
структур данных,  например, шрифтов (TLongFont) или классов
окон (TWndClass).  Windows и ObjectWindows определяют эти и
другие структуры данных.  Перечень  доступных  структур  вы
можете   найти   в  оперативном  справочнике  или  в  файле
WINTYPES.PAS.  Структуры,  непосредственно  используемые  в
ObjectWindows,  вы  можете  найти в Главе 21 "Справочник по
ObjectWindows".

     При использовании ObjectWindows  все  функции  Windows
доступны  также  непосредственно и могут вызываться в вашей
программе (если в  ее  операторе  uses  указывается  модуль
WinProcs).  Например,  следующий  код  для  получения  окна
сообщений вызывает функцию Windows MessageBox:

     Reply := MessageBox(HWindow, 'Хотите сохранить?',
              'Файл изменен', mb_YesNo or mb_IconQuestion);

     MessageBox возвращает      целочисленное     значение,
указывающее,  какое  действие   выбрал   пользователь   для
закрытия окна сообщения.  Если пользователь щелкнул "мышью"
на  командной  кнопке  Yes   (Да),   то   результат   равен
определенной в Windows целочисленной константе id_Yes. Если
пользователь щелкнул "мышью" на командной кнопке No  (Нет),
то результат равен id_No.

                   Комбинирование констант стилей
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Функции Windows,  позволяющие  получить   интерфейсные
элементы, требуют обычно некоторого параметра типа Word или
Longint.  Идентификаторы   констант   стилей   состоят   из
двухбуквенного мнемонического префикса,  за которым следует
подчеркивание и описательное имя.  Например, ws_Popup - это
константа  стиля  окна  (ws_  означает  стиль окна - window
style").

           Примечание: В Windows определены сотни  констант
      стилей, которые перечислены в Главе 21 "Справочник по
      ObjectWindows".

     Часто эти стили комбинируются  для  получения  другого
стиля.  Например,  в  случае  функции  MessageBox вы можете
передать  в   качестве   параметра   стиля   mb_YesNo   или
mb_IconQuestion.  Этот  стиль  дает  окно сообщений с двумя
командными кнопками Yes и No и пикторгаммой вопросительного
знака.  Поразрядная  операция or фактически комбинирует две
константы бит  за  битом.  Полученный  в  результате  стиль
представляет собой комбинацию обоих стилей.

     Имейте в виду, что некоторые стили взаимноисключающие.
Их   комбинирование   может   дать    непредвиденные    или
нежелательные результаты.

                        Типы функций Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже перечислены  виды  функций  Windows,  которые  вы
можете использовать в своих программах ObjectWindows.

          Функции интерфейса с администратором Windows

     Эти функции     выполняют     обработку     сообщений,
манипулируют  окнами  и  диалоговыми  блоками   и   создают
системный  вывод.  Данная категория включает в себя функции
для меню, курсоров и буфера вырезанного изображения.

                       Функции интерфейса
                с графическими устройствами (GDI)

     Эти функции   выводят   на   разнообразные  устройства
(включая экран и принтер) текст, графику и битовые массивы.
Они  не  привязаны  к  конкретному  устройству  и  являются
независимыми от устройства.

       Функции интерфейса со служебными функциями системы

     Эти функции работают с  широким  диапазоном  системных
устройств,  включая  управление  памятью,  взаимодействие с
операционной   системой,   администрирование   ресурсов   и
коммуникации.

                     Функции системного вызова
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Windows содержит ряд функций,  которые  позволяют  вам
проходить  в  цикле  (или  перечислять)  определенные  типы
элементов в системе Windows.  Например,  перечислить шрифты
системы  и  напечатать образец текста,  используя каждый из
них.  Чтобы использовать такую функцию,  вы должны передать
указатель  на нее (указатель системной функции),  и Windows
будет использовать  его  в  процессе  перечисления.  Данная
функция  при  итерации по списку характеристик окна,  окон,
дочерних окон,  шрифтов и т.д.  вызывается  непосредственно
Windows.

     Функции Windows,  требующие  функций системного вызова
(или повторного вызова), включают в себя: EnimChildWindows,
EnumClipboardFormats, EnumFonts, EnumMetaFile, EnumObjects,
EnumPops, EnumTaskWindows и EnumWindows.

     Функция системного   вызова   должна   быть    обычной
функцией,  а  не методов объекта.  Указатель на эту функцию
передается в качестве  первого  параметра  (типа  TFarProc)
данных  методов.  Например,  если  вы  определили в Паскале
функцию системного вызова ActOnWindow следующим образом:

function ActOnWindow(TheHandle: HWnd; The Value: Longint):
           Integer; far; export;

то можете  передать ее в качестве функции системного вызова
при вызове функции Windows EnumWindows:

ReturnValue:=EnumWindows(TFarProc(ActOnWindow), ALongint);

     Функция системного вызова  должна  иметь  тот  же  тип
возвращаемого   значения,   что  и  вызывающая  ее  функция
Windows.  Функция ActOnWindows  будет  выполнять  некоторое
действие с окном,  заданным переданным указателем. Параметр
TheValue - это любое значение,  выбранное  для  передачи  в
вызывающей программе.

     Директива компилятора  {$K+}  позволяет  автоматически
управлять функциями системного вызова. Если вы не выбираете
{$K+},  то для возврата адреса, по которому будет выполнять
вызов Windows,  должны передавать свои  функции  системного
вызова через функцию API MakeProcInstance.


                    Глава 8. Объекты приложения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     При разработке  приложения  ObjectWindows  вам   нужно
сначала  определить объект приложения,  производный от типа
ObjectWindows  TApplication.  Этот   объект   инкапсулирует
следующее поведение приложения ObjectWindows:

     * Создание и вывод основного окна приложения.

     * Инициализацию   первого  экземпляра  приложения  для
       задач,  выполняемых всеми  экземплярами  приложения,
       таких  как  создание файлов,  совместно используемых
       всеми экземплярами.

     * Инициализацию   каждого    экземпляра    приложения,
       например, загрузку таблицы оперативных клавиш.

     * Обработку сообщений Windows.

     * Закрытие приложения.

     Кроме определения   объекта   приложения   вы   должны
добавить к нему возможность  построения  объекта  основного
окна.   Вы   имеете   также   возможность   переопределения
используемого  по  умолчанию  поведения  инициализированных
экземпляров,  закрытия  приложения  и  обработки  сообщений
Windows.

                       Минимальные требования
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы ваше   программа   ObjectWindows  стала  рабочим
приложением Windows,  она должна  в  своем  основном  блоке
begin..end делать следующее:

     - выполнять инициализацию;

     - обрабатывать сообщения;

     - по требованию завершать работу.

     Используемый по  умолчанию объект выполняет эти задачи
путем вызова трех его методов:  Init,  Run и Done. Основной
блок  любой программы ObjectWindows содержит обычно эти три
метода. Чтобы изменить поведение по умолчанию, методы нужно
переопределить.


                      Поиск объекта приложения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда программа       выполняется,       ObjectWindows
поддерживает глобальную переменную Application -  указатель
на    объект    приложения.    Этот   указатель   позволяет
подпрограммам вне объекта приложения обращаться к его полям
и методам. По умолчанию Application устанавливается в @Self
конструктором  объекта  приложения  и  в  nil  деструктором
объекта.

                       Минимальное приложение
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Приведем пример минимального приложения ObjectWindows:

     program MinApp;
     uses OWindows;
     var
       MyApp: TApplication;
     begin
       MyApp.Init('TtstApp');
       MyApp.Run;
       MyApp.Done;
     end;

     MinApp -    это    абсолютный    минимум    приложения
ObjectWindows.  Эта программа не требует определения других
объектов.  Обычно вы определяете новый объектные  типы  как
минимум для приложения и основного окна.

                      Методы Init, Run и Done
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Так как  в  основном  блоке  программы   ObjectWindows
каждый  раз используются одни и те же операторы,  вы должны
понимать, что делает каждый из них.

                          Конструктор Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Первый оператор   -   это   вызов   конструктора  Init
приложения. Этот вызов делает следующее:

     * Строит объект.

     * Инициализирует поля данных объекта.

     * Устанавливает глобальную переменную  Application  на
       объект (@Self).

     * Выполняет два вида инициализации:

       - Вызывает  InitApplication  при  отсутствии  других
         выполняемых экземпляров данного приложения.

       - Всегда вызывает InitInstance, устанавливая вызовом
         InitMainWindow основное окно.

     Когда Init  завершает  работу,  основное  окно  вашего
приложения находится на экране.  В большинстве случаев  вам
нужно только переопределить InitMainWindow.

                             Метод Run
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Второй оператор вызывает метод Run приложения, который
реализует    работу    приложения,   вызывая   MessageLoop.
MessageLoop обрабатывает сообщения от Windows  и  выполняет
инструкции,    которые    управляют   работой   приложения.
MessageLoop  -  это  цикл,  который  продолжает  работу  до
закрытия приложения.

     MessageLoop вызывает несколько методов, обрабатывающих
конкретные поступающие сообщения (см. далее).


                          Деструктор Done
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Done -  это  деструктор  объекта   приложения.   Перед
завершением работы приложения он освобождает память объекта
приложения.

 ЪДДДДДДДДДДДДДДДДї     ЪДДДДДДДДДДДДДДДДДї
 і     Init       ГДДВД>і InitApplication і
 АДДДДДДДДДДДДДДДДЩ  і  АДДДДДДДДДДДДДДДДДЩ
                     і
                     і ЪДДДДДДДДДДДДї ЪДДДДДДДДДДДДДДДї
                     А>іInitInstanceГ>іInitMainWindow і
                       АДДДДДДДДДДДДЩ АДДДДДДДДДДДДДДДЩ

 ЪДДДДДДДДДДДДДДДДї     ЪДДДДДДДДДДДДДДДДДї
 і     Run        ГДДДД>і   MessageLoop   і
 АДДДДДДДДДДДДДДДДЩ     АДДДДДДДДДДДДДДДДДЩ

 ЪДДДДДДДДДДДДДДДДї
 і     Done       і
 АДДДДДДДДДДДДДДДДЩ

     Рис. 8.1   Вызовы   методов,    управляющие    работой
приложения.

                      Инициализация приложения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Выполнение методов,      инициализирующих       объект
приложения,  позволяет  вам  настроить части процесса путем
переопределения  отдельных  методов.   Один   из   методов,
требующий   переопределения,   чтобы   приложения  получило
конкретный смысл  -  это  InitMainWindow.  Вы  моете  также
переопределить InitInstance и InitApplication.

                    Инициализация основного окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вы должны  определить  метод  InitMainWindow,  который
строит  и  инициализирует объект основного окна и сохраняет
его в поле  MainWindow  объекта  приложения.  Ниже  показан
пример описания объекта приложения и метода InitMainWindow.

     Данный метод  создает  новый  экземпляр  типа  TWindow
ObjectWindows (PWindow - это  указатель  на  тип  TWindow).
Обычно ваша программа будет определять для своего основного
окна   новый   оконный   тип,   а   InuitMainWindow   будет
использовать этот тип вместо TWindow.

           Примечание: Объекты  окон подробно описываются в
      Главе 10.

     Следующее простое приложение ObjectWindows  объединяет
в себе новый тип TMyApplication и старое приложение MinApp.
Оно отличается от MinApp  только  тем,  что  основное  окно
имеет заголовок:

program TestApp;
uses OWindows;

type
  TMyApplication = object(TApplication)
     procedure InitMainWindow; virtual;
  end;

procedure TMyApplication.InitMainWindow;
begin
  MainWindow := New(PWindow, Init(nil, 'Основное окно'));
end;


var
  MyApp: TApplication;
begin
  MyApp.Init('TestApp');
  MyApp.Run;
  MyApp.Done;
end;

     Программа TestApp  выводит окно с заголовком 'Основное
окно'.  Вы можете легко перемещать это окно и изменять  его
размер,    минимизировать    его,    восстанавливать    или
максимизировать.  Закрытие   окна   завершает   приложение.
Короче,   TestApp   -   это   полнофункциональный  "скелет"
приложения, оснащенный только простейшим основным окном.



                  Специальный вывод основного окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Начальный вывод  основного окна управляется переменной
CmdShow модуля System.  CmdShow содержит одну  из  констант
sw_  и  передается в качестве параметра функции API Windows
ShowWindow, когда приложение создает свое основное окно.

     С помощью CmdShow вы  легко  можете  вывести  основное
окно  в  нормальном  виде  (по  умолчанию),  распахнутым до
размеров полного экрана, минимизированным в пиктограмму или
скрытым.   Лучшим   местом  присваивания  значения  CmdShow
является   конструктор   объекта   основного   окна.    Это
обеспечивает  передачу  выбранного  значения  при  создании
элемента экрана.

                  Инициализация первого экземпляра
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если пользователь  запускает  приложение  в отсутствии
уже работающих  других  экземпляров  этого  приложения,  вы
можете   определить   для  такого  первоначального  запуска
некоторую    обработку.    Эта     обработка     называется
инициализацией   первого   экземпляра.   Если  пользователь
начинает и завершает ваше приложение,  затем запускает  его
снова  и  т.д.,  каждый  экземпляр будет первым экземпляром
(поскольку другие экземпляры в этот момент не выполняются).

     Если текущим экземпляром является первый экземпляр, то
конструктор  Init  вызывает  InitApplication.  TApplication
определяет заместитель метода InitApplication,  который  вы
можете  для  выполнения  специальной  инициализации первого
экземпляра переопределить.


     Например, вы   можете   модифицировать  TestApp  таким
образом,  чтобы о первом экземпляре сообщалось в  заголовке
основного   окна.  Для  этого  добавьте  в  тип  приложения
TMyApplication булевское  поле  с  именем  FirstApp,  затем
переопределите метод InitApplication, чтобы он устанавливал
FirstApp в True.  Наконец, модифицируйте InitMainWindow для
проверки  FirstApp  и  вывода  в  основном  окне приложения
соответствующего заголовка (см. Рис. 8.2).

±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
±ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї±±±±±±
±і±=±±±±±±±Первый экземпляр±±±±±±±±±±±±±±±±±±±і^іvі±±±±±±
±ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ±±±±±±
±і                                                і±±±±±±
±і  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї±±±
±і  і±=±±±±±±±Дополнительный экземпляр±±±±±±±±±±±і^іvі±±±
±і  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ±±±
±і  і                                                і±±±
±і  і                                                і±±±
±і  і  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
±і  і  і±=±ЫЫЫЫДополнительный экземплярЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
±і  і  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
±і  і  і                                                і
±і  і  і                                                і
±АДДі  і                                                і
±±±±і  і                                                і
±±±±АДДі                                                і
±±±±±±±і                                                і
±±±±±±±АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 8.2 Новая инициализация приложения.

     program TestApp;
     uses OWindows;

     type
       TMyApplication = object(TApplication)
           FirstApp: Boolean;
           procedure InitMainWindow; virtual;
           procedure InitApplication; virtual;
       end;

     procedure TMyApplication.InitMainWindow;
     begin
       if FirstApp then
           MainWindow := New(PWindow, Init(nil,
                             'Первый экземпляр'))
       else MainWindow := New(PWindow, Init(nil,
                             'Дополнительный экземпляр'));
     end;

     procedure TMyApplication.InitApplication;
     begin
       FirstApp := True;
     end;

     var MyApp; TMyApplication;
     begin
       MyApp.Init('TestApp');
       MyApp.Run;
       MyApp.Done;
     end.


                  Инициализация каждого экземпляра
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Пользователь может  одновременно  выполнять  несколько
экземпляров      ObjectWindows.      Метод     InitInstance
инициализирует  каждый  экземпляр  приложения.  Он   должен
инициализировать только само приложение,  а не его основное
окно. Основное окно инициализируйте в InitMaionWindow.

     InitInstance вызывает InitMainWindow,  а затем создает
и   выводит  основное  окно.  Для  модификации  стандартной
инициализации приложения (например,  для  загрузки  таблицы
оперативных   клавиш)   вам   нужно  только  переопределить
InitInstance. Если вы переопределяете для своего приложения
InitInstance,  убедитесь  сначала,  что  он  вызывает метод
InitInstance, наследуемый из TApplication.

     Приведем метод InitInstance, который перед выполнением
приложения загружает метод InitInstance.  'MeHotKeys' - это
идентификатор   ресурса   таблицы    оперативных    клавиш,
определенный в файле ресурса:

procedure TEditApplication.InitInstance;
begin
  inherited InitInstance;
  HAccTable := LoadAccelerators(HInstance, 'MyHotKeys');
end;

     Вы можете    также   использовать   InitInstance   для
регистрации  экземпляра  приложения  с  внешней  DLL  (типа
Paradox Engine).


                       Выполнение приложений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Метод Run    вашего    приложения    вызывает    метод
MessageLoop,  который  вызывает  цикл  обработки  сообщений
вашей  программы.  Во  время  выполнения  вашей программы в
цикле обработки  сообщений  обрабатываются  поступающие  от
Windows  сообщения.  Программы ObjectWindows наследуют цикл
MessageLoop,  который  работает  автоматически.  Дополняйте
цикл  обработки  сообщений  только  специальными диалогами,
оперативными клавишами или обработкой MDI.

     Метод MessageLoop  для  обработки  сообщений   Windows
вызывает три метода.  ProcessDlgMsg работает с безрежимными
диалоговыми   окнами,    ProcessAccels    -    обрабатывает
оперативные   клавиши,  а  ProcessMDIAccels  -  оперативные
клавиши для приложений MDI. Для приложений, не использующих
командные  клавиши  или  безрежимные диалоговые окна или не
являющихся приложениями  MDI  MessageLoop  можно  несколько
упростить. См. методы TApplication в Главе 21.


                        Закрытие приложений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вызов деструктора  Done  в  основной  программе вашего
приложения уничтожает объект приложения.  Однако, перед тем
как   это   происходит,   программа  должна  прервать  цикл
обработки   сообщения.   Это   может    произойти,    когда
пользователь пытается закрыть основное окно приложения.  Мы
говорим,  что это может произойти,  так  как  ObjectWindows
предусматривает механизм изменения поведения приложения при
закрытии: вы можете задавать условия закрытия.

                 Модификация поведения при закрытии
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Все оконные   объекты,   наследуют   булевский   метод
CanClose,  возвращающий по умолчанию True (что указывает на
подтверждение   закрытия,   то   есть  TestApp  закрывается
немедленно). Для изменения поведения при закрытии вы можете
переопределить  методы  CanClose  приложения  или основного
типа окна.  Если какие-либо объекты возвращают из  CanClose
значение False,  то приложение завершиться не может. Обычно
вы можете изменить поведение при закрытии  объектного  типа
основного   окна.   Например,   перед   завершением   можно
убедиться, что приложение сохранило файлы.

                        Механизм CanClose

     Механизм CanClose   дает   основному   окну,   объекту
приложения  и  другим  окнам  возможность  подготовиться  с
закрытию или предотвратить его.  В итоге объект  приложения
должен  разрешить  закрытие  приложения.  По  умолчанию  он
проверяет   основное   окно.   Обычная   последовательность
закрытия выглядит следующим образом:

     1. Windows    посылает   основному   окну   приложения
        сообщение wm_Close.

     2. Объект  основного  окна  вызывает  метод   CanClose
        объекта приложения.

     3. Объект приложения вызывает метод CanClose.

     4. Объект  основного  окна вызывает метод CanClose для
        каждого из дочерних окон и возвращает True только в
        том  случае,  если  методы  CanClose  дочерних окон
        возвращают True.

                      Модификация CanClose

     Методы CanClose  редко  возвращают   значение   False.
Вместо  этого  они  должны  выполнять  некоторые  действия,
позволяющие  им  возвращать  True.  Метод  CanClose  должен
возвращать  False  только  в  том случае,  если он не может
выполнить действий, необходимых для нормального завершения,
или   пользователь  показывает,  что  он  хочет  продолжать
выполнение программы.

     Например, метод   CanClose   окна   редактора    может
проверять изменение редактируемого текста, а затем выводить
диалоговое окно с запросом,  нужно ли сохранить текст перед
закрытием,  и  воспринимать  ответ  Yes (Да),  No (Нет) или
Cancel (Отмена).  Cancel будет указывать,  что пользователь
пока не хочет закрывать приложение, так что CanClose должен
возвращать False.  CanClose следует также возвращать  False
при  обнаружении  ошибки в сохранении текста,  предоставляя
пользователю другую  возможность  сохранения  данных  перед
закрытием.

     Если метод CanClose не переопределяется, тип основного
окна  наследует  его  от   TWindowsObject,   где   CanClose
возвращает  True  после  вызовов  методов CanClose дочерних
окон. Чтобы модифицировать поведение при закрытии основного
окна, переопределите метод CanClose. Например, для проверки
того,  что пользователь собирается закрыть окно,  он  может
проверять открытые файлы.


                   Глава 9. Интерфейсные объекты
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Объекты, представляющие  окна,   диалоговые   окна   и
управляющие элементы,  называются интерфейсным объектами. В
данной главе обсуждаются общие  требования  к  интерфейсным
объектам и их поведение, а также взаимодействие с реальными
окнами,  диалоговыми  блоками   и   выводимыми   на   экран
управляющими элементами.

     В этой   главе   поясняется  также  взаимосвязь  между
различными  интерфейсными  объектами  приложения,  а  также
механизм передачи сообщений Windows.

           Примечание: Приводимый  здесь материал относится
      к окнам, диалоговым блокам и управляющим элементам.

                Для чего нужны интерфейсные объекты?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для чего  нужны  интерфейсные объекты,  если в Windows
уже есть окна, диалоговые блоки и управляющие элементы?

     Одна из основных трудностей программирования в Windows
-  это  достаточно сложная работа с визуальными элементами.
Иногда вам нужно послать в окно сообщение,  в другой раз  -
вызвать  функцию  API  Windows.  Для разных типов элементов
экрана соглашения будут различными.

     ObjectWindows уменьшает большую часть этих сложностей,
предоставляя  объекты,  инкапсулирующие  элементы  экрана и
избавляющие вас от необходимости иметь дело непосредственно
с  Windows.  К  тому  же  они  обеспечивают  более  удобный
интерфейс.

                  Что делают интерфейсные объекты?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Интерфейсные объекты    предоставляют    методы    для
создания,   инициализации,   управления    и    уничтожения
соответствующих элементов экрана, и имеют содержащие данные
поля,  включая  описатель  интерфейсного  элемента  и   его
порождающего и дочернего окна. Методы объекта берут на себя
многие детали программирования в Windows.

     Взаимосвязь объект/элемент во многом аналогична  связи
файла  DOS  с  переменной  Паскаля.  Имея  файл,  вы можете
присвоить файловую  переменную,  представляющую  физическую
структуру  фактического файла на диске,  а затем работать с
этой файловой переменной. С помощью ObjectWindows вы можете
определить    объект,   представляющий   физическое   окно,
управляющий элемент или диалоговый блок, который фактически
обслуживается администратором окон Windows.  Вы работаете с
объектом,  а он  берет  на  себя  функции  по  обслуживанию
элемента экрана.


                     Общий интерфейсный объект
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Все интерфейсные  объекты  ObjectWindows  наследуют из
единственного абстрактного объектного типа  TWindowsObject,
который  определяет  поведение,  общее для окна,  диалога и
объектов   управляющих    элементов,    видоизменяемых    и
специализируемых  в  производных  объектных  типах TDialog,
TWindow и TControl.

     В качестве общего предка  всех  интерфейсных  объектов
методы  TWindowsObject  обеспечивают  единообразный  способ
поддержки взаимосвязи между объектами и  элементами  экрана
(включая  создание  и  уничтожение  объектов),  обслуживают
соотношения    "родитель-потомок"    между    интерфейсными
объектами  и  регистрируют новый классы Windows (см.  Главу
10).

     Новые типы,     производные     от     TWindowsObject,
определяются     редко,     но     он     служит    основой
объектно-ориентированной   модели   окон.   Он   определяет
большинство     наследуемых     объектами    функциональных
возможностей, когда вы получаете из TWindow и TDialog новые
типы.


                   Создание интерфейсных объектов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Задание полного      интерфейсного      объекта      с
соответствующими  интерфейсными  элементами  требует   двух
шагов:

     * Построения объекта.

     * Создания элемента экрана.

     Первым шагом является вызов конструктора Init, который
строит интерфейсный объект и  устанавливает  его  атрибуты,
такие как стиль и меню.

     Второй шаг  заключается  в вызове метода создания окна
объекта приложения,  MakeWindow,  связывающего интерфейсный
объект  с новым элементом экрана.  Эта связь поддерживается
полем HWindow экрана (описателем окна).

   Примечание: Об описателях окон рассказывается в Главе 7
      "Иерархия ObjectWindows".

     MakeWindow вызывает   метод  Create  объекта,  который
всегда сообщает Windows о необходимости  создания  элемента
на экране.  Create создает также метод SetupWindow, который
инициализирует   интерфейсный   объект   путем    создания,
например, дочерних окон.

                    Допустимость описателя окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Обычно в Windows вновь созданный интерфейсный  элемент
получает  (от  Windows)  сообщение  wm_Create,  на  которое
требуется  ответить  инициализацией.  Интерфейсный   объект
ObjectWindows   не   будет  получать  сообщений  wm_Create,
поэтому не  забудьте  определить  для  инициализации  метод
SetupWindow.

     Если инициализация   интерфейсного   объекта   требует
описателя элемента экрана (например, для вызова функции API
Windows),  то  она не должна вызываться раньше SetupWindow.
То   есть,   перед   вызовом   SetupWindow   поле   HWindow
интерфейсного    объекта    не    является   допустимым   и
использоваться не должно.  Если вы хотите вызывать  функцию
API  или нечто требующее описателя окна,  не вызывайте их в
конструкторе  Init.  Поместите   такие   вызовы   в   метод
SetupWindow.

                               і<ДДДДHWindow допустимДДД>і
                               і                         і
  і<ДДДДДДДДДДДДДДинтерфейсный объект допустимДДДДДДДДДД>і
ДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБ>
  ^                  ^           ^        ^              ^
  і                  і           і        і              і
 Init вызывает       і           і        і              і
  наследуемый Init   і           і        і              і
                     і           і       Done            і
   SetupWindow вызывает наследуемыйі
    SetupWindow                    іDoneвызываетнаследуемый
                                   і   метод Done
                                   і
             Наследуемый SetupWindow вызывает Create

     Рис. 9.1 Когда окно имеет допустимый описатель.



                        Видимость на экране
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Создание интерфейсного   объекта   и  соответствующего
визуального элемента не обязательно означает, что вы что-то
видите  на экране.  Когда метод Create указывает Windows на
создание элемента экрана,  Windows проверяет,  включает  ли
стиль  окна  ws_Visible.  Если да,  то интерфейсный элемент
будет выводиться. В противном случае он будет скрытым.

     ws_Visible и другие стили окна обычно  устанавливаются
или  сбрасываются  конструктором  Init  в  поле  Attr.Style
объекта.

     В любой  момент  после  создания  элемента  экрана  вы
можете   вывести   или   скрыть   его,  вызвав  метод  Show
интерфейсного объекта.


                 Уничтожение интерфейсных объектов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Как и в  случае  создания  интерфейсный  объектов,  их
уничтожение предполагает выполнение двух шагов:

     * Уничтожение   визуального   интерфейсного   элемента
(Destroy).

     * Уничтожение интерфейсного объекта (Dispose).

     Уничтожением экранного   элемента   занимается   метод
Destroy интерфейсного объекта, который делает следующее: он
вызывает функцию Windows DestroyWindow, чтобы избавиться от
элемента экрана,  и устанавливает поле HWindow объекта в 0.
Таким образом,  проверив  указатель,  вы  можете  сообщить,
связан ли еще объект с элементом экрана.

     Уничтожить элемент  экрана  вы  можете без уничтожения
объекта (если хотите создавать и выводить его снова).

           Примечание: Уничтожение самого  окна  обычно  не
      требуется.  Это  делается  автоматически при закрытии
      окна.

     Когда пользователь   закрывает   на    экране    окно,
ObjectWindows   обнаруживает,  что  данный  элемент  экрана
уничтожен,  устанавливает  поле  HWindow   соответствующего
объекта в 0 и вызывает деструктор объекта Done.


              Связь порождающего и дочернего объектов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В приложении   Windows   совместная  работа  элементов
экрана (окон,  диалоговых блоков и  управляющих  элементов)
обеспечивается   с   помощью   связей   "родитель-потомок".
Порождающие  окна  управляют  своими  дочерними  окнами,  а
Windows  отслеживает эти связи.  ObjectWindows поддерживает
параллельный   набор    связей    между    соответствующими
интерфейсными объектами.

     Дочернее окно  -  это  элемент  экрана (оно не обязано
быть окном),  который управляется другим элементом  экрана.
Например,  блоки  списка обслуживаются окном или диалоговым
блоком,  в котором они выводятся.  Они выводятся  на  экран
только при выводе их порождающих окон.  Диалоговые блоки, в
свою  очередь,  являются  дочерними  окнами,   управляемыми
порождающими их окнами.

     Когда вы  перемещаете или закрываете порождающее окно,
дочерние окна  автоматически  закрываются,  и  в  некоторых
случаях перемещаются в нем.  Конечным предком всех дочерних
интерфейсных элементов  является  основное  окно,  хотя  вы
можете иметь окна и диалоги без порождающих окон.

     Порождающими окнами могут быть только диалоговые блоки
и окна,  но не порождающие элементы.  Дочерним окном  может
быть любой интерфейсный элемент.


                        Список дочерних окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда вы  строите  объект дочернего окна,  то можете в
качестве  параметра   конструктора   Init   можете   задать
порождающее  окно  (пример  вы  можете  найти  в Главе 10).
Объект дочернего окна  отслеживает  свое  порождающее  окно
через  указатель  на его поле Parent.  Он отслеживает также
объекты его дочерних окон,  сохраненные в  поле  ChildList.
Дочернее  окно,  на  которое  в  данный  момент  установлен
ChildList, является последним созданным дочерним окном.


                      Построение дочерних окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Как и в случае интерфейсных объектов, объекты дочерних
окон  создаются  в два этапа (построение объекта и создание
элемента экрана). Объекты порожденного окна следует строить
с  помощью  конструктора Init порождающего окна.  Например,
объект окна,  наследующий из TWindow и содержащий командную
кнопку должен иметь примерно следующий вид:

constructor TMyWindow.Init(AParent: PWindowsObject;
                           ATitle: PChar);
begin
  inherited Init(AParent, ATitle);
  TheButton := New(PButton, Init(@Self, id_TheButton,
                   'Текст кнопки', 20, 10, 100, 25, True));
end;

     Обратите внимание  на использование указателя Self для
связи   дочернего   объекта   (TheButton)   с   порождающим
(экземпляром TMyWindow).  Конструктор интерфейсного объекта
автоматически добавляет к своему списку дочерних окон новые
объекты.


                 Создание дочерних элементов экрана
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда построен список дочерних элементов интерфейсного
объекта,  создание  элементов  экрана  для  дочерних   окон
выполняется   автоматически.  Создание  родительского  окна
(через вызов  MakeWindow)  включает  в  себя  вызов  метода
SetupWindow   порождающего   окна.   Одним  из  наследуемых
действий SetupWindow является вызов для каждого из  окон  в
списке дочерних окон методов SetupWindow.

           Примечание: Автоматическое     создание    можно
      запретить.    См.     ниже     раздел     "Запрещение
      автоматического создания".

     При создании нового производного объектного типа нужно
помнить об инициализации объекта в SetupWindow после вызова
наследуемого метода SetupWindow, например:

procedure TMyCheckBox.SetupWindow;
begin
  inherited SetupWindow;           { сначала по умолчанию }
     .
     .
     .                  { выполнить инициализацию объекта }
end;


                Уничтожение дочерних окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вызов деструктора  порождающего окна приводит к вызову
деструкторов  всех  его  дочерних  окон,  так   что   вашей
программе  не  нужно  явно  вызывать  деструкторы дочернего
окна.  Это же  справедливо  для  метода  CanClose,  который
возвращает  True  только после вызова CanClose для всех его
дочерних окон.


                Запрещение автоматического создания
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы явно  исключить  дочернее  окно   из   механизма
автоматического  создания  и  вывода,  вызовите  после  его
создания метод DisableAutoCreate.  Чтобы  явно  добавить  в
механизм   создания  и  вывода  дочернее  окно  (такое  как
диалоговый  блок,  который  при  нормальном  выводе   будет
исключен),    вызовите    после    построения   его   метод
EnableAutoCreate.


                       Итерация дочерних окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Иногда желательно  написать  методы,  для   реализации
функции  выполняющие  итерации  по  каждому  дочернему окну
данного окна. Например, можно проверить в окне все кнопки с
независимой  фиксацией.  В  этом  случае  используйте метод
TWindowsObject.ForEach:

     procedure TMyWindow.CheckAllBoxes;

       procedure CheckTheBox(ABox: PWindowsObject); far;
       begin
         PCheckBox(ABox)^.Check;
       end;

     begin
       ForEach(@CheckTheBox);
     end;

     Использование метода  ForEach  (и  аналогичных методов
FirstThat  и  LastThat)  похоже  на  применение  методов  с
аналогичными  названиями в TCollection.  Хотя ObjectWindows
не использует наборы для обслуживания дочерних окон, методы
итерации работают аналогично.


                 Поиск определенного дочернего окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Иногда желательно  иметь методы,  выполняющие итерацию
по списку окон в поиске конкретного окна.  Например, в окне
с несколькими кнопками вам может потребоваться найти первую
установленную кнопку с независимой фиксацией. В этом случае
метод TWindowsObject.FirstThat можно записать так:

function TMyWindow.GetFirstChecked: PWindowsObject;

  function IsThisOneChecked(ABox: PWindowsObject): Boolean;
         far;
  begin
    IsThisOneChecked := (ABox^.GetCheck = bf_Checked);
  end;

begin
  GetFirstChecked := FirstThat(@IsThisOneChecked);
end;


                       Глава 10. Объекты окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Объекты окон (или оконные объекты) - это  интерфейсные
объекты,  предназначенные для облегчения работы с окнами. В
данной главе поясняется,  как создавать  и  заполнять  окна
приложения. Это предусматривает следующие задачи:

     * Инициализацию оконных объектов.

     * Установку атрибутов создания.

     * Создание экранных элементов окна.

     * Установку атрибутов регистрации.

     * Использование специализированных окон.

     * Прокрутку окон.


                      Что такое объекты окон?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Термин "объект  окна" относится к любому интерфейсному
объекту,  представляющему окно,  а в Windows это почти все,
что  выводится  на  экран.  В  качестве шаблона определения
большей части фундаментального поведения основного  окна  и
любого    всплывающего    окна   приложения   ObjectWindows
использует тип TWindow.


                  Окна, которые не являются окнами
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TWindow имеет три типа-потомка: TMDIWindow, TControl и
TEditWindow,  так  что  все  они  также  являются  оконными
объектами,  хотя на самом деле это не окна в полном  смысле
слова.  Типы  MDI используются в приложениях ObjectWindows,
которые   соответствуют   стандарту    многодокументального
интерфейса  Windows.  Об  MDI и этих типах рассказывается в
Главе 14.  TControl определяет управляющие элементы,  такие
как командные кнопки и блоки списков (см.  Главу 12).  Чаще
всего новые оконные типы являются производными от TWindow.

     Эта глава охватывает  типы  TWindow  и  TEditWindow  и
содержит примеры регистрации новых классов окон.


                       Где найти объекты окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Каждое приложение  Windows  имеет  основное окно.  Это
окно может выводиться в виде пиктограммы или не  выводиться
снова  (скрытое  окно),  но  существует всегда.  Приложения
ObjectWindows не являются  исключением:  они  должны  иметь
основное окно, представленное оконным объектом.

     Примером минимальной      программы      ObjectWindows
("скелета" программы) является TestApp в Главе 8.  Основное
окно  программы  ObjectWindows  является обычно экземпляром
TWindow или определяемого в  программе  наследующего  типа.
Многие   приложения   имеют  другие  окна,  которые  обычно
являются   дочерними    окнами    основного    окна.    Эти
дополнительные окна также являются экземплярами TWindow или
одного из его потомков.

     Например, графическая программа может  определять  для
своего   основного  окна  тип  TPaintWindow,  а  для  окна,
показывающего графический рисунок - тип TZoomWindow. В этом
случае  TPaintWindow  и  TZoomWindow  являются наследниками
TWindow.


                    Инициализация объектов окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Оконные объекты представляют элементы окна,  связанные
через    описатели,    сохраненные    в    наследуемом   из
TWindowsObject поле HWindow.  Так как объект окна имеет две
части,  его  создание  требует  двух  шагов:  инициализации
объекта и создания визуального элемента.

     Инициализация окна -  это  процесс  создания  оконного
объекта ObjectWindows путем вызова конструктора Init:

Window1:=New(PWindow,Init(nil, 'Заголовок окна 1'));
Window2:=New(PNewWindowType,Init(nil,'Заголовок окна 2'));

     Init создает новый оконный объект и устанавливает поле
Title в Attr в передаваемый аргумент PChar. Первый аргумент
вызова Init - это оконный объект  порождающего  окна.  Если
окно  является  основным  окном  (не  имеющим  порождающего
окна), то это nil.


                    Установка атрибутов создания
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Типичное приложение  Windows  имеет  много   различных
типов окон: перекрывающиеся или всплывающие, окна с рамкой,
прокручиваемые окна,  окна с заголовком и др.  Эти атрибуты
стилей,   а  также  заголовок  и  меню  окна  задаются  при
инициализации оконного объекта и используются при  создании
элементов окна.

     Атрибуты создания  оконного объекта,  такие как стиль,
заголовок и меню, записываются в поле Attr объекта - записи
типа TWindowAttr. TWindowAttr содержит следующие поля:

      Атрибуты создания окна          Таблица 10.1
ЪДДДДДВДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іПоле і Тип          і           Использование           і
ГДДДДДЕДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іTitleі PChar        і Строка заголовка.                 і
і     і              і                                   і
іStyleі Longint      і Комбинированная константа стиля.  і
і     і              і                                   і
іMenu і HMenu        і Описатель ресурса меню.           і
і     і              і                                   і
іX    і Integer      і Горизонтальная  координата  экранаі
і     і              і верхнего левого угла окна.        і
і     і              і                                   і
іY    і Integer      і Вертикальная   координата   экранаі
і     і              і верхнего левого угла окна.        і
і     і              і                                   і
іW    і Integer      і Начальная ширина окна в  координа-і
і     і              і тах экрана.                       і
і     і              і                                   і
іH    і Integer      і Начальная высота окна в  координа-і
і     і              і тах экрана.                       і
і     і              і                                   і
АДДДДДБДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


^±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
±(0,0)±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
±±±±±(X,Y)±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
±±±±±v±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
±±±±±ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДВДДїДД±±±±
±±±±±і ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫ  Title ЫЫЫЫЫЫЫЫЫЫЫЫЫЫі  і  і ^±±±±
±±±±±ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДБДДґ і±±±±
±±±±±і Menu                                        і і±±±±
±±±±±ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і±±±±
±±±±±і                                             і і±±±±
±±±±±і                                             і і±±±±
±±±±±і                                             і H±±±±
±±±±±і                                             і і±±±±
±±±±±і                                             і і±±±±
±±±±±і                                             і і±±±±
±±±±±і                                             і і±±±±
±±±±±і                                             і і±±±±
±±±±±і                                             і v±±±±
±±±±±АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩДД±±±±
±±±±±і<ДДДДДДДДДДДДДДДДДДWДДДДДДДДДДДДДДДДДДДДДДДД>і±±±±±±
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±

     Рис. 10.1 Атрибуты окна.


              Используемые по умолчанию атрибуты окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     По умолчанию  TWindow.Init  устанавливает Attr.Style в
ws_Visible.  Если окно является основным окном  приложения,
то Style равно ws_OverlappedWindow or ws_Visible.

     Menu по  умолчанию устанавливается в 0.  Это означает,
что меню не определено.

     X, Y,  W и H устанавливаются в cw_UseDefault, что дает
в   результате   перекрывающееся  окно  удовлетворительного
размера.  Когда создается  окно,  не  являющееся  основным,
значения X, Y, W и H вы обычно устанавливаете сами.


        Переопределение используемых по умолчанию атрибутов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     При создании   новых  оконных  типов,  производных  от
TWindow,  вы  обычно  определяете  новый  конструктор  Init
(особенно  если хотите получить атрибут создания,  отличных
от   используемого   по   умолчанию).   Если   вы    хотите
переопределить  Init,  то  можете  заново  задать  атрибуты
объекта,  непосредственно изменяя поле  Attr  после  вызова
Init.

     Если вы  переопределили Init,  убедитесь,  что первое,
что он делает - это вызов наследуемого метода TWindow.Init,
устанавливающего используемые по умолчанию атрибуты.  Затем
вы можете изменить по своему  выбору  любой  из  атрибутов.
Например,  типичное окно может определять конструктор Init,
который устанавливает атрибут Menu:

     constructor TWindowType.Init(AParent: PWindowsObject;
                                  ATitle: PChar);
     begin
        inherited Init(AParent, ATitle);
        Attr.Menu := LoadMenu(HInstance, 'TheMenu');
        AChildWindow := New(PChildWindowType, Init(@Self,
                            'Заголовок дочернего окна'));
        List1 := New(PListBox, Init(@Self, id_ListBox,
                     201, 20, 20, 180, 80));
            .
            .
            .
     end;


                     Атрибуты порожденного окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Конструктор TWindowType  отвечает  за  построение  его
дочерних  объектов,  таких  как  всплывающие  окна  и блоки
списка.  Тип  порожденного  окна,  в  свою  очередь,  может
устанавливать  атрибуты  в  своем  собственном конструкторе
Init:

constructor TChilwWindowType.Init(AParent: PWindowsObject;
                             ATitle: PChar);
begin
   inherited Init(AParent, ATitle);
   with Attr do
   begin
      Style := Style or ws_PopupWindow or ws_Caption;
      X := 100; Y := 100; W := 300; H := 300;
   end;
end;

     В качестве   альтернативы   вы  можете  не  определять
потомка типа окна, а сначала построить объект окна, а затем
переустановить  его  атрибуты  (все это в конструкторе Init
порождающего окна):

     constructor TWindowType.Init(AParent: PWindowsObject;
                                  ATitle: PChar);
     begin
        inherited Init(AParent, ATitle);
        Attr.Menu := LoadMenu(HInstance, 'TheMenu');
        AChildWindow := New(PChildWindowType, Init(@Self,
                            'Заголовок дочернего окна'));
        with Attr do
        begin
           Style := Style or ws_PopupWindow or ws_Caption;
           X := 100; Y := 100; W := 300; H := 300;
        end;
            .
            .
            .
     end;


                      Создание элементов окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     После построения  оконного  объекта вам нужно сообщить
Windows,  что  требуется  создать  связанные   с   объектом
элементы  экрана.  Это делается с помощью вызова MakeWindow
объекта приложения и  передачи  ему  в  качестве  параметра
указателя на объект окна.

     if Application^.MakeWindow(AWindow) <> nil then
                { успешное создание }
     else       { неуспешное создание }

     MakeWindow вызывает  два важных метода:  ValidWindow и
Create. ValidWindow проверяет успешность построение объекта
окна,  проверяя  поле  Status.  Если по каким-либо причинам
конструктор завершился неуспешно,  то MakeWindow возвращает
nil.   При   успешном  выполнении  конструктора  MakeWindow
переходит на метод Create оконного объекта.

     Create -  это  метод,  который   фактически   сообщает
Windows о создании элемента экрана. Если Create завершается
неудачно,  MakeWindow возвращает nil.  В  противном  случае
возвращается  указатель  на  оконный  объект.  Для работы с
элементом экрана Create также устанавливает поле HWindow.

     Хотя этот метод фактически создает элемент экрана,  вы
обычно  не  можете  вызывать  Create  явно.  Основное  окно
приложения автоматически создается  при  запуске  программы
методом TApplication.InitInstance.

     Все прочие  окна приложения являются дочерними окнами,
прямо или косвенно порождаемыми основным окном,  а дочерние
окна  создаются  обычно  в  методе  SetupWindow  или  в его
порождающих оконных объектах,  либо  с  помощью  MakeWindow
динамически на этапе выполнения.

           Примечание: Дочерние    окна    и    SetupWindow
      описываются в Главе 9 "Интерфейсный объекты".

     В общем случае порождающие окна  обычно  вызывают  для
своих  дочерних  окон  методы  Init и MakeWindow.  Атрибуты
оконного объекта обычно устанавливаются их методами объекта
порождающего  окна.  Поскольку  основное окно приложения не
имеет порождающего окна, объект приложения строит и создает
его при запуске приложения.


                   Задание атрибутов регистрации
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В ходе инициализации оконного объекта путем заполнения
поля объекта Attr вы можете установить несколько  атрибутов
окна,  такие  как  его  стиль,  расположение  и  меню.  Эти
атрибуты   используются   для   создания   соответствующего
оконного   элемента,   поэтому  они  называются  атрибутами
создания.

     Другие атрибуты,  включая  фоновый  цвет,  пиктограмму
представления  и  курсора  "мыши",  более  тесно  связаны с
данным типом оконного объекта и не могут изменяться в  ходе
работы  программы.  Эти  присущие  окну атрибуты называются
атрибутами регистрации,  так как  они  устанавливаются  при
регистрации класса окна в Windows.


                            Классы окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     С каждым   типом   оконного   объекта   связан  список
атрибутов регистрации,  которые  называются  классом  окна.
Список  атрибутов  регистрации  во многом напоминает список
атрибутов создания,  записанных в поле записи Attr  объекта
окна.  Однако,  атрибуты регистрации сохраняются в записи с
именем TWndClass,  который  определяется  и  поддерживается
Windows.

     Процесс связи  класса  окна  с  типом оконного объекта
называется   регистрацией   класса   окна.    ObjectWindows
автоматизирует процесс регистрации.  Таким образом, если вы
хотите изменить какую-либо  из  используемых  по  умолчанию
характеристик  объекта,  то можете не беспокоиться о классе
регистрации окна.

     Поля записи  TWndClass  и  их   типы   перечислены   в
следующей таблице:

   Атрибуты регистрации окна        Таблица 10.2
ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДї
іХарактеристика       і Поле              і Тип      і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДґ
істиль класса         і style             і Word     і
іпиктограмма          і hIcon             і HIcon    і
ікурсор               і hCursor           і HCursor  і
іфоновый цвет         і hbrBackground     і HBrush   і
іменю по умолчанию    і lpszMenuName      і PChar    і
АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДЩ

                    Поля стиля класса

     Это поле  стиля  отличается  от  атрибута  стиля  окна
(ws_), задаваемого при инициализации окна, поскольку задает
поведение,  присущее  операциям  окна  (в  отличие  от   их
визуального  представления).  Это  поле  может  заполняться
комбинацией констант стиля (cs_).

     Например, cs_HRedraw приводит к повторному отображению
окна при изменении его размера по горизонтали; cs_DoubleClk
позволяет окну получать сообщения о двойном нажатии  кнопки
"мыши"; cs_NoClose предотвращает выбор параметра Close меню
Control,  а  cs_ParentDC   дает   окну   контекст   дисплея
порождающего окна.

                        Поле пиктограммы

     Это поле   содержит   описатель  пиктограммы,  которое
используется для представления окна в его  минимизированном
состоянии.   Обычно   для   представления   основного  окна
программы выбирается ресурс пиктограммы.

                          Поле курсора

     Поле hCursor  содержит  описатель   курсора,   который
используется   для   представления   указателя  "мыши"  при
позиционировании его в окне.

                       Поле фонового цвета

     Это поле задает фоновый  цвет  окна.  Для  большинства
приложений    используется   стандартный   назначаемый   по
умолчанию  цвет   окна,   который   может   устанавливаться
пользователем в управляющей панели.  Однако вы можете путем
установки  этого  поля   в   описатель   физической   кисти
подставить конкретный цвет. Либо вы можете установить любое
из значений цветов Windows,  такие как color_ActiveCaption.
К любому значению цвета всегда добавляйте 1.

              Поле используемого по умолчанию меню

     Это поле указывает на имя ресурса меню, которое служит
используемым  по  умолчанию  меню   для   данного   класса.
Например, если вы определите тип EditWindow, который всегда
имеет стандартное меню  редактирования,  то  можете  задать
здесь  это меню.  Это устранит необходимость задания меню в
методе Init.  Если данный ресурс меню  имеет  идентификатор
'MyMenu', вы можете установить это поле следующим образом:

     AWndClass.IpszMenuName := 'MyMenu';


           Используемые по умолчанию атрибуты регистрации
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Тип TWindow  определяет  класс  окна  'TurboWindow'  с
пустой пиктограммой, курсором-стрелкой и стандартным цветом
окна.   Используемый   по   умолчанию  класс  ObjectWindows
(TurboWindow) имеет следующие атрибуты:

     * стиль:   cs_HRedraw   or    cs_VRedraw    (повторное
       отображение после каждого изменения размера);

     * пиктограмма: idi_Application (пустой прямоугольник);

     * курсор: idc_Arrow (стандартная стрелка Windows);

     * фоновый цвет: HBrush(color_Window + 1);

     * меню по умолчанию: nil.


                     Регистрация нового класса
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы изменить  атрибут регистрации,  такой как курсор
или  пиктограмму,  вам  нужно   написать   два   метода   -
GetClassName  и  GetWindowClass  - и определить новый класс
окна.  Каждый раз, когда вы изменяете атрибуты регистрации,
вам  нужно  изменить  имя класса.  Если класс регистрации с
данным именем уже зарегистрирован в Windows,  другие классы
с  тем  же  именем  класса  регистрироваться не будут - они
получат атрибуты уже зарегистрированного класса.


                       Изменение имени класса
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     GetClassName - это  функция,  которая  возвращает  имя
(PChar)   класса   окна.   TWindow.GetClassName  возвращает
'TurboWindow',  имя используемого по умолчанию класса окна.
TWindow.GetClassName   возвращает   'TurboWindow'   -   имя
используемого по умолчанию класса окна:

     function TWindow.GetClassName: PChar;
     begin
       GetClassName := 'TurboWindow';
     end;

     Чтобы определить    тип    объекта   окна   с   именем
IBeamWindow,  который использует вместо стандартной стрелки
I-образный   курсор,   переопределите   наследуемый   метод
следующим образом:

     function TBeamWindow.GetClassName: PChar;
     begin
       GetClassName := 'IBeamWindow';
     end;

           Примечание: Имя  класса  не  обязательно  должно
      соответствовать имени объектного типа.

     Имя класса должно быть уникальным.


              Определение новых атрибутов регистрации
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы отклониться  от  стандартных  характеристик,  вы
должны заполнить поля записи TWndClass с различными данными
в методе GetWindowClass.

     GetWindowClass воспринимает         в         качестве
аргумента-переменной  запись  TWndClass и заполняет ее поля
новыми атрибутами регистрации.  Когда вы определяете  новый
метод   GetWindowClass,  вам  следует  всегда  сначала  для
установки значений по умолчанию вызывать наследуемый  метод
TWindow.GetWindowClass, а затем устанавливать поля, которые
вы хотите изменить.

     Например, в поле hCursor  хранится  описатель  ресурса
курсора. Для IBeamWindow определяется метод GetWindowClass:

     procedure IBeamWindow.GetWindowClass(var AWndClass:
                                          TWndClass);
     begin
       inherited GetWindowClass(AWndClass);
       AWndClass.hCursor := LoadCursor(0, idc_IBeam);
     end;

           Примечание: idc_Beam    -     это     константа,
      представляющая один из курсоров Windows.

     Кроме окон,  диалоговым  окнам  (не диалоговым блокам)
необходимо  регистрировать  классы  окна  (см.  Главу  11).
Диалоговым  блокам  и  управляющим элементам классы окон не
требуются.


               Использование специализированных окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows предусматривает  два  потомка   TWindow,
являющихся  специализированными  окнами  для редактирования
текста.  Объектный  тип  TEditWindow  обеспечивает  простой
текстовый  редактор,  не обладающий возможностями чтения из
файла или записи в него.  Тип TFileWindow,  наследующий  из
TEditWindow,     обеспечивает    текстовый    редактор    с
возможностями чтения/записи файлов.

     Эти объекты  можно  использовать  непосредственно  как
стандартные  компоненты  ваших приложений.  Вы можете также
построить  производные  от  них   типы   и   создать   свои
собственные  специализированные  редакторы.  Программы  или
модули, использующие окна редактирования или файловые окна,
должны включать в свой оператор uses модуль OStdWnds.


                 Использование окон редактирования
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Окно редактирования - это окно с управляющим элементом
редактирования,   заполняющим    его    область    клиента.
TEditWindow.Init    инициализирует    поле    Editor   окна
редактирования,  чтобы оно указывало на управляющий элемент
объекта       редактирования.       TEditWindow.SetupWindow
устанавливает размеры управляющего элемента  редактирования
в  соответствии  с областью клиента окна и создает экранный
управляющий элемент редактирования.

     Метод WMSize    обеспечивает     изменение     размера
управляющего  элемента редактирования при изменении размера
его окна.  Метод WMSetFocus обеспечивает,  что  управляющий
элемент  редактирования  получает фокус ввода при получении
окном сообщения wm_SetFocus.


     Показанная ниже  программа EditWindowTester использует
окно редактирования,  чтобы пользователь мог  редактировать
текст для простой (нефункциональной) электронной почты.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫEdit Window TesterЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і Edit   Text                                            і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Кого это может касаться:                               і
і                                                        і
іЯхотелбызарегистрироватьжалобупоповоду попугая, которогоі
і я купил в вашем магазине полгода назад. Он умер.       і
і                 ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї  і
і Брюс            і±=±ІІІІІІПередано сообщениеІІІІІІІІі  і
і                 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ  і
і                 і                                   і  і
і                 і   6 строк послано                 і  і
і                 і          ЪДДДДДДДДДДДДї           і  і
і                 і          і±±±±OK±±±±±±і           і  і
і                 і          АДДДДДДДДДДДДЩ           і  і
і                 АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ  і
і                                                        і
АДДДДДДДДДДДДДДДД ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

Рис. 10.2 Окно редактирования.

program EditWindowTester;
{$R EWNDTEST.RES}
uses ODialogs, WinTypes, WinProcs, Strings, OStdWnds;
const cm_sendText = 399;
type
  TestApplication = object(TApplication)
     procedure InitMainWindow; virtual;
  end;

  PMyEditWindow = ^MyEditWindow;
  MyEditWindow = object(TEditWindow)
     constructor Init(AParent: PWindowsObject;
                      ATitle: PChar);
     procedure CMSendText(var Msg: TMessage); virtual
                      cm_First + cm_SendText;
  end;

constructor MyEditWindow.Init(AParent: PWindowsObject;
                      Atitle: PChar);
begin
  inherited Init(AParent, ATitle);
  Attr.Menu := LoadMenu(HInstance, MakeIntResource(102));
end

procedure MyEditWindows.CMSendText(var Msg: TMessage);
var
  Lines: Integer;
  TestString: string[3];
  Text: array[0..20] of Char;
begin
  Lines := Editor^.GetNumLines;
  Str(Lines, TextString);
  StrCat(Text, ' строк послано');
  MessageBox(HWindow, @Text, 'Передано сообщение', mb_Ok);
end;

procedure TestApplication.InitMainWindow;
begin
  MainWindow := New(PMyEditWindow, Init(nil,
'Окно редактирования -попробуйте набор и редактирование'));
 end;

 var TestApp: TestApplication;
 begin
   TestApp.Init('EditWindowTester');
   TestApp.Run;
   TestApp.Done;
 end.


                Использование файловых окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Файловое окно    -    это    окно   редактирования   с
дополнительными  возможностями,  позволяющими  считывать  и
записывать  данные в файл.  TFileWindow.Init воспринимает в
качестве аргумента  заголовок  окна  и  устанавливает  поле
FileDialog  таким образом,  чтобы оно указывало на файловый
диалоговый объект.


     Для работы  с файлами TFileWindow имеет четыре метода.
Методы  Open,  Save  и  SaveAs  для   вывода   пользователю
подсказки     с     именем     файла     используют    поле
TFileWindow.FileDialog  (см.  Главу  11).  Метод  New  дает
пользователю возможность отмены, если редактирование нового
файла приведет к потере изменений  текущего  текста.  Чтобы
дать  пользователю  возможность  доступа  к  этим  методам,
создайте свое меню со следующими идентификаторами меню:

Методы и идентификаторы меню файлового окна     Таблица 10.3
ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і    Метод            і    Идентификатор меню для вызоваі
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і    New              і    cm_FileNew                   і
і    Open             і    cm_FileOpen                  і
і    Save             і    cm_FileSave                  і
і    SaveAs           і    cm_FileSaveAs                і
АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Вы можете использовать файловые окна  без  модификации
как простые автономные текстовые редакторы.  Однако, иногда
желательно  создать  производные  от  TFileWindow  типы   и
обеспечить   дополнительные   функциональные   возможности.
Например, можно предусмотреть средство поиска. Помните, что
вы  все  равно  будете иметь доступ к управляющему элементу
редактирования TFileWindow.Editor.


                     Прокрутка содержимого окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В большинстве случаев для  прокрутки  текущей  области
просмотра  пользователи  используют  полосы прокрутки вдоль
края окна.  В отличие от стандартных управляющих  элементов
типа  полос прокрутки полосы прокрутки окна являются частью
самого окна.

     ObjectWindows управляет прокруткой окна,  предоставляя
каждому  оконному  объекту  поле  Scroller,  которое  может
указывать на объект TScroller.  Объект прокрутки  TScroller
обеспечивает  автоматизированный  способ  прокрутки в окнах
текста и графики.  Кроме того, TScroller может прокручивать
окна,  когда  пользователь  перемещает  "мышь"  за  область
клиента окна (это называется  автоматической  прокруткой  и
действует даже для окон, которые не имеют полос прокрутки).


                    Что такое объект прокрутки?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TScroller содержит значения,  определяющие,  насколько
должно прокручивается окно.  Эти  значения  записываются  в
полях XUnit,  YUnit,  XLine, YLine, XRange, YRange, XPage и
YPage объекта TScroller.  Поля,  начинающиеся  с  буквы  X,
представляют  горизонтальные  значения,  а  начинающиеся  с
буквы Y - вертикальные.

                        Единицы прокрутки

     Единица прокрутки  определяет   минимальную   величину
прокрутки.  Она  задается  в наименьших единицах устройства
(обычно в  элементах  изображения,  но  может  зависеть  от
текущего   режима   отображения),   на  которые  вы  можете
выполнять  прокрутку  в  горизонтальном  или   вертикальном
направлении.  Это  значение  обычно  основывается  на  виде
выводимой на экран информации.

     Например, если вы выводите текст с шириной  символа  8
элементов изображения и высотой 15,  то в качестве значений
XUnit и YUnit полезно задать, соответственно, 8 и 15.

                   Строки, страницы и диапазон

     Другие атрибуты  прокрутки  -   строка,   страница   и
диапазон  - выражаются в единицах прокрутки.  Значения Line
(строка) и Page (страница) - это число единиц,  на  которые
выполняется  прокрутка  в  ответ  на  запрос  пользователя.
Запрос может иметь форму щелчка кнопкой  "мыши"  на  концах
полосы  прокрутки (построчная прокрутка).  Щелчок "мышью" в
самой полосе прокрутки (но не на маркере полосы  прокрутки)
позволяет   выполнять   постраничную   прокрутку.  Атрибуты
диапазона (XRange, YRange) представляют общее число единиц,
на которое можно выполнять прокрутку.  Обычно этот диапазон
определяется на основе размера редактируемого документа.


                    Типичный объект прокрутки

     В качестве    примера    рассмотрим   текстовое   окно
редактирования.  Если вы хотите вывести на экран  текстовый
файл,  имеющий 400 строк текста с границей 80 символов и 50
строками на странице, то можно выбрать следующие значения:

 Типичные значения для окна редактирования   Таблица 10.4
ЪДДДДДДДДДДДДДВДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іПоле         і   Значениеі            Смысл              і
ГДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іXUnit        і    8      і  ширина символа               і
іYUnit        і   15      і  высота символа               і
іXLine, YLine і    1      і  1 единица на строку          і
іXPage        і   40      і  40 символов по горизонтали наі
і             і           і  страницу                     і
іYPage        і   50      і  50 символов по  вертикали  наі
і             і           і  страницу                     і
іXRange       і   80      і  максимальный   горизонтальныйі
і             і           і  диапазон                     і
іYRange       і  400      і  максимальный вертикальный ди-і
і             і           і  апазон                       і
АДДДДДДДДДДДДДБДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Объект TScroller   с   данными   значениями  позволяет
выполнять построчную или постраничную прокрутку.  С помощью
полос  прокрутки  или  автоматической прокрутки выполняется
просмотр всего файла.

                      Значения по умолчанию

     По умолчанию XLine и YLine имеют значение 1,  так  что
без  явной необходимости устанавливать их в другие значения
не нужно.  Для установки  значений  прокрутки  на  страницу
также существует используемая по умолчанию схема,  согласно
которой страница прокрутки  будет  соответствовать  текущей
высоте  или  ширине  области клиента окна (в зависимости от
направлений прокрутки).  Если вы не  хотите  переопределить
данный   механизм,   переустанавливать   эти   значения  не
требуется.



                 Задание для окна объекта прокрутки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы задать  для  окна объект прокрутки,  постройте в
конструкторе своего оконного  объекта  объект  TScroller  и
присвойте его полю Scroller. Вам нужно установить начальный
размер  единицы  и  диапазона,  но  позднее  вы  можете  их
изменить.

     При использовании объекта прокрутки для автоматической
прокрутки  полосы  прокрутки  не   требуются,   но   многие
прокручиваемые окна их имеют.  Чтобы добавить в окно полосы
прокрутки,   добавьте   в   поле   Attr.Style   ws_VScroll,
ws_HScroll (или то и другое).

     Приведем пример   конструктора   для  текстового  окна
редактирования:

constructor TTextWindow.Init(AParent: PWindowsObject;
                             ATitle: PChar);
begin
  inherited Init(AParent, ATitle);
  Attr.Style := Attr.Style or ws_VScroll or ws_YScroll;
  Scroller := New(PScroller, Init(@Self, 8, 15, 80, 400));
end;

     В качестве    аргументов    TScroller     воспринимает
прокручиваемое  окно  и начальные значения для полей XUnit,
YUnit,  XRange и YRange соответственно.  Атрибуты строки  и
страницы получают значения по умолчанию.

     После вывода  окна  на  экран  содержимое  его области
клиента можно  прокручивать  вертикально  и  горизонтально,
используя  для  этого  полосу  прокрутки или автоматическую
прокрутку.  Метод  Pant  окна  просто  рисует   на   экране
графическую   информацию,  необходимую  для  уведомления  о
прокрутке.  Как описывается в конце  этого  раздела,  метод
Paint можно оптимизировать для вывода только части рисунка.


                          Пример прокрутки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Scroll -  это полное приложение с графическим выводом,
допускающим прокрутку.  Показанная  ниже  программа  рисует
последовательность  прямоугольников,  затем  увеличивает их
размер, так что вся картинка не умещается в область клиента
окна,  отображенного на обычном экране VGA. С помощью полос
прокрутки вы можете просматривать различные  части  рисунка
или автоматически прокручивать картинку,  удерживая нажатой
левую кнопку "мыши" и перемещая ее из области клиента.

program Scroll;

uses Strings, WinTypes, WinProcs, OWindows;

type
  TScrollApp = object(TApplication)
      procedure InitMainWindow; virtual;
  end;

  PScrollWindow = ^TScrollWindow;
  TScrollWindow = object(TWindow)
    constructor Init(ATitle: PChar);
    procedure Paint(PaintDC: HDC;
                    var PaintInfo: TPaintStruct); virtual;
  end;

procedure TScrollApp.InitMainWindow;
begin
  MainWindow := New(PScrollWindow, Init('Boxes'));
end;

constructor TScrollWindow.Init(ATitle: PChar);
begin
  inherited Init(nil, ATitle);
  Attr.Style := Attr.Style or ws_VScroll or ws_HScroll;
  Scroller := New(PScroller, Init(@Self, 8, 15, 80, 60));
end;

procedure TScrollWindow.PAint(PaintDC: HDC;
                              var PaintInfo: TPaintStruct);
var X1, Y1, I: Integer;
begin
  for I := 0 to 49 do
  begin
    X1 := 10 + I*8;
    Y1 := 30 + I*5;
    Rectangle(PaintDC, X1, Y1, X1 + X1, X1 + Y1 * 2);
  end;
end;

var ScrollApp: TScrollApp;

begin
  ScrollApp.Init('ScrollApp');
  ScrollApp.Run;
  ScrollApp.Done:
end.



           Запрещение автоматической прокрутки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Объект TScroller    может   по   умолчанию   выполнять
автоматическую  прокрутку,  но  установка   поля   AutoMode
TScroller   в   значение   False  отключает  это  средство.
Окно-владелец  может  сделать  это  в  конструкторе   после
построения объекта TScroller:

Scroller := New(PScroller, Init(@Self, 8, 15, 80, 60));
Scroller^.AutoMode :=False;

     Если AutoMode  равно   False,   то   прокрутка   может
выполняться  только  с  помощью  полос прокрутки.  Полезная
особенность автоматической прокрутки состоит в том, что чем
дальше  вы  сдвинете  "мышь"  от области клиента окна,  тем
быстрее будет происходить прокрутка окна.  В зависимости от
удаления    мыши   приращение   прокрутки   будет   обратно
пропорционально   значению   параметра   строк   и    прямо
пропорционально значению параметра страницы.


                    Отслеживание полос прокрутки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В дополнение  к автоматической прокрутке,  приведенный
выше  пример  программы  будет   отслеживать   запросы   на
прокрутку,  сдвигая при нажатой кнопке "мыши" маркер полосы
прокрутки.  Другими словами  картинка  сдвигается  уже  при
нажатой   кнопке.   Эта   особенность  дает  действительную
обратную связь,  и пользователь может сдвигать нужную часть
изображения не отпуская кнопку "мыши".

     Однако, в  некоторых  случаях этот эффект нежелателен.
Например,  если вы просматриваете большой  текстовый  файл,
такое   отслеживание   может  замедлить  работу,  поскольку
возникает необходимость постоянно  считывать  информацию  с
диска  и  отображать  порцию  текста  для  каждого движения
"мыши". В такой ситуации лучше отменить этот эффект:

     Scroller^.TrackMode:=False;

     Теперь никакой  прокрутки  не  происходит  до  момента
отпускания  кнопки на мыши,  и в области клиента будет лишь
однократно показана нужная часть картинки.


              Модификация единиц прокрутки и диапазона
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В приведенных выше примерах  мы  предполагали,  что  к
моменту  построения  TScroller  известны  значения единиц и
диапазонов. Во многих случаях эта информация неизвестна или
может   меняться   при   изменении   размеров  отображаемой
информации.  В этом случае может  потребоваться  установить
или  изменить  значения  диапазона  (а может быть и единиц)
позднее.  Если значения заранее  неизвестны,  то  их  можно
задать как 0 в конструкторе TScroller.

                       Изменение диапазона

     Метод SetRange    воспринимает    два    целочисленных
аргумента - число  горизонтальных  и  вертикальных  единиц,
которые определяют общий диапазон прокрутки. Метод SetRange
должен  использоваться  при  изменении  размеров  картинки.
Например,  при  подготовке изображения картинки шириной 1 0
единиц и высотой 300,  данная  команда  установит  диапазон
прокрутки надлежащим образом:

     Scroller^.setRange(100, 300);

                   Изменение единиц прокрутки

     Если при   инициализации   объекта  TScroller  единицы
неизвестны,  то  их   значения   могут   быть   установлены
непосредственно перед прокруткой.  Например, они могут быть
установлены методом окна SetupWindow:

     procedure ScrollWindow.SetupWindow;
     begin
        TWindow.SetupWindow;
        Scroller^.XUnit:=10;
        Scroller^.YUnit:=20;
     end;


                    Изменение позиции прокрутки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Windows с  помощью  методов  ScrollTo и ScrollBy может
выполнять   принудительную   прокрутку.   Каждый   из   них
воспринимает   два   целочисленных   аргумента  в  терминах
горизонтальных и вертикальных единиц  прокрутки.  Например,
если  нужно  переместиться к левому верхнему углу картинки,
то используется ScrollTo:

     Scroller^.ScrollTo(0, 0);

     Приведем другой пример.  Если картинка имеет длину 400
единиц  в  вертикальном  направлении,  то позицию прокрутки
можно переместить к середине картинки следующим образом:

     Scroller^.ScrollTo(0, 200);

     Метод ScrollBy может перемещать позицию  просмотра  на
заданное  число  единиц  вверх,  вниз,  влево  или  вправо.
Отрицательные значения осуществляют сдвиг к левому верхнему
углу,  а  положительные  -  к  правому нижнему.  Если нужно
сместиться на 10 единиц вправо и на 20 единиц вниз,  то это
можно сделать командой:

     Scroller^.ScrollBy(10, 20);


                    Установка размеров страницы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     По умолчанию   размер   страницы   (XPage   и   YPage)
устанавливается в соответствии с размером  области  клиента
окна.   При  изменении  размеров  окна  механизм  прокрутки
учитывает эту информацию.  Метод окна WMSize вызывает метод
прокрутки  SetPageSize,  который устанавливает поля объекта
XPage и YPage на основании текущих размеров области клиента
окна и значений XUnit и YUnit. Для отмены этого механизма и
непосредственной  установки  размеров  страницы  вы  должны
переписать  унаследованный  метод  объекта окна WMSize и не
вызывать SetPageSize:

     procedure TTestWindow.WMSize(var Msg: TMessage);
     begin
       DefWndProc(Msg);
     end;

     Затем вы  можете  непосредственно  установить  XPage и
YPage в конструкторе окна (или в  производном  конструкторе
TScroller):

constructor ScrollWindow.Init(AParent:PWindowsObject;
                              ATitle: PChar);
begin
  inherited Init(AParent, ATitle);
  Attr.Style:=Attr.Style or ws_VScroll or ws_HScroll;
  Scroller:=New(PScroller, Init(@Self, 8, 15, 80, 400));
  Scroller^.XPage:=40;
  Scroller^.YPage:=100;
end;


         Оптимизация методов Paint для прокрутки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В приведенном     выше     примере     рисуется     50
прямоугольников,  но не делается даже  попытки  определить,
все  ли  прямоугольники  видны в области клиента окна.  Это
может привести к излишним усилиям  на  дорисовку  невидимых
изображений. Для оптимизации рисования в окне методом Paint
можно использовать метод TScroller.IsVisibleRect.

     Приведенный ниже метод  ScrollWindow.Paint  использует
IsVisibleRect  для  определения,  нужно ли вызывать функцию
Windows  Rectange.  Rectange   воспринимает   аргументы   в
единицах устройства,  а VisibleRect в единицах прокрутки. С
этой  целью  вершина  прямоугольника   X1   Y1   и   ширина
прямоугольника  (X2-X1)  и  его  высота (Y2-Y1) должны быть
разделены  на  соответствующее  число  единиц   до   вызова
IsVisibleRect:

procedure TScrollWindow.Paint(PaintDC: HDC; var PaintInfo:
                              TPaintStruct);
var
  X1, Y1, X2, Y2, I: Integer;
begin
   for I:=0 to 49 do
   begin
      X1 := 10 + I * 8;
      Y1 := 30 + I * 5;
      X2 := X1 + X1;
      Y2 := X1 + Y1 * 2;
      if Scroller^.IsVisibleRect(X1 div 8,
                                 Y1 div 15, (X2-X1) div 8,
                                 (Y2-Y1) div 15) then
      Rectangle(PaintDC, X1, Y1, X2, Y2);
    end;
end;


                Глава 11. Объекты диалоговых блоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Блоки диалога,   или    просто    диалоги,    являются
интерфейсными    объектами,    инкапсулирующими   поведение
диалоговых  блоков.  Это  дочерние  окнам,  которые  обычно
выводятся  для  выполнения  специфических  задач (например,
конфигурирования принтера или  организации  ввода  текста).
Объект   TDialog  обеспечивает  инициализацию,  создание  и
исполнение всех типов  блоков  диалога.  Для  каждого  типа
диалога вашего приложения, как и в случае оконных объектов,
вы можете  определить  производные  от  TDialog  диалоговые
блоки.

     ObjectWindows всегда  предоставляет  два типа диалогов
наиболее общего типа,  ввод текста и  диалог  файла.  Кроме
того,  в  ObjectWindows  имеется  тип  TDlgWindow,  который
позволяет вам создавать диалоги,  поведение  которых  более
похоже на окно.

Данная глава охватывает следующие темы:

* Использование объектов диалоговых блоков.
* Работа с управляющими элементами в диалоговых блоках.
* Связь объектов с управляющими элементами.
* Связь окон с ресурсами.


         Использование объектов диалоговых блоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Использование объектов  диалоговых  блоков  аналогично
использованию объектов всплывающего окна.  Диалоги являются
дочерними окнами  своего  порождающего  окна.  Для  простых
диалоговых  блоков,  которые  появляются на короткое время,
вся обработка диалога может быть  выполнена  одним  методом
объекта    порождающего    окна.    Диалог    может    быть
сконструирован,  выполнен и удален в одном  методе,  и  нет
необходимости  хранить  диалог  в  поле объекта.  Для более
сложных диалогов может  потребоваться  записать  диалоговый
блок в поле оконного объекта вашего диалогового блока.

     Подобно всплывающим  окнам  и  управляющим  элементам,
диалоговые  блоки   являются   дочерними   окнами   и   при
конструировании  добавляются к списку ChildList порождающих
окон.

     Использование объекта        диалогового         блока
предусматривает следующие шаги:

     * Построение объекта.

     * Выполнение диалогового окна.

     * Закрытие диалогового окна.


                         Построение объекта
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Диалоговые блоки  конструируются  и  специфицируются с
помощью  описания  ресурса,  создаваемого  вне   программы.
Ресурс  диалогового окна описывает внешний вид и размещение
управляющих элементов,  таких как  кнопок,  блоков  списка,
областей  редактирования  и  текстовых строк.  Он описывает
только внешний вид диалогового  блока  и  не  касается  его
поведения - за это отвечает прикладная программа.

     Каждый ресурс  диалогового  блока имеет идентификатор,
который  может  быть  номером  идентификатора  (Word)   или
строкой   (PChar).  Этот  идентификатор  позволяет  объекту
диалогового блока задавать,  какой ресурс используется  для
определения его внешнего вида.


                         Вызов конструктора
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы построить  объект  диалогового  блока,  вызовите
конструктор  Init.  Init  воспринимает  в  качестве   своих
параметров  указатель  на  порождающее окно и параметр типа
PChar, представляющий имя ресурса диалога:

     ADlg:=New(PSampleDialog, Init(@Self, 'EMPLOYEEINFO'));

     Если идентификатор  задается  номером,  его  требуется
привести с помощью MakeIntResource к PChar:

     Dlg := New(PSampleDialog, Init(@Self, PChar(120)));

     Так как диалоговые блоки обычно строятся внутри метода
оконного объекта,  порождающее окно почти  всегда  задается
как   Self.   Объекты  диалоговых  блоков,  не  создаваемые
оконными объектами,  должны иметь в  качестве  порождающего
Applicartion^.MainWindow    (поскольку   это   единственный
оконный объект,  всегда присутствующий в  каждой  программе
ObjectWindows).


                    Выполнение диалоговых блоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Выполнение диалогов  аналогично созданию и отображению
окна.  Однако, поскольку диалоги обычно появляются на более
короткий   отрезок  времени,  некоторые  этапы  могут  быть
сокращены.  Это в значительной  степени  зависит  от  того,
будет  ли  диалоговый  блок  отображаться  как режимный или
безрежимный.


              Режимные и безрежимные диалоговые блоки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Режимные диалоговые  блоки  являются  наиболее  общими
блоками    диалога.    Аналогично   генерируемым   функцией
MessageBox блокам сообщений,  режимные диалоги отображаются
для специфических целей на короткий отрезок времени.  Слово
"режимный"  означает,   что   пока   отображается   диалог,
пользователь   не   может   выбрать  или  использовать  его
порождающее  окно.  Пользователь   должен   воспользоваться
диалогом  и  выбрать  командную  кнопку  OK  или Cancel для
прекращения диалога и возвращению к  работе  с  программой.
Режимный диалог как бы "замораживает" выполнение оставшейся
части программы.

     Безрежимный диалоговый   блок   не    приостанавливает
выполнения  программы.  Как  и  оконный  объект,  он  может
создаваться  и  выполняться  в   одном   шаге   с   помощью
MakeWindow:

     Application^.MakeWindow(ADlg);

     В любое момент вы можете считать данные из диалогового
окна (если объект диалогового блока еще  существует).  Чаще
всего  это выполняется в методе OK,  который вызывается при
активизации пользователем командной кнопки OK.


               Выполнения режимных диалоговых блоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В случае  режимных  диалоговых  блоков  лучше   всего,
вероятно,  строить,  выполнять  и  уничтожать все объекты в
одном методе (как показано в примерах данной главы).  Таким
образом,  при  каждом  выводе  диалогового  блока это будет
новый объект.

     Объекты приложения    имеют    режимный     эквивалент
MakeWindow,   который   называется  ExecDialog.  Аналогично
MakeWindows,     ExecDialog     проверяет      допустимость
передаваемого объекта диалогового блока (то есть успешность
выполнения  конструктора  объекта  и  отсутствие   ситуации
нехватки памяти),  а затем выполняет диалоговый блок, делая
его модальным.

     ExecDialog возвращает     целочисленное      значение,
указывающее,  что  пользователь  закрывает диалоговое окно.
Возвращаемое значение - это идентификатор  задействованного
пользователем  управляющего  элемента,  такой как id_Ok для
командной кнопки OK  или  id_Cancel  для  командной  кнопки
Cancel.   После   завершения  выполнения  диалогового  окна
ExecDialog уничтожает объект диалогового окна.

     Таким образом,  с   помощью   одного   вызова   метода
ExecDialog вы можете создать,  вывести на экран и завершить
диалоговый блок.

ADlg := New(PSampleDialog, Init(@Self, 'RESOURCEID'));
ReturnValue := Application^.ExecDialog(ADlg);
if ReturnValue = id_OK then
      { кодирование для выборки данных и обработки диалога}
else
if ReturnValue = id_Cancel then { нажата Cancel }


         Выполнение безрежимных диалоговых блоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Безрежимные диалоги   похожи  на  всплывающие  окна  и
управляющие элементы.  Основная причина,  по которой вы  не
можете  удалять  безрежимными  диалогами  сразу же после их
отработки (в отличие от режимных),  состоит в том,  что  вы
заранее не знаете, когда пользователь закроет блок диалога.
(Помните о том, что в режимных диалогах метод ExecDialog не
возвращает  значения  до  закрытия  диалога.) Следовательно
лучше   всего   конструировать   безрежимные   диалоги    в
конструкторе   его  порождающего  окна  и  хранить  в  поле
порождающего объекта.

     В отличие от окон и объектов управления,  используемых
в   качестве   дочерних   окон,  диалоги  автоматически  не
отображаются при выводе их порождающих окон.

constructor ParentWindow.Init(AParent: PWindowsObject;
                              ATitle: PChar);
begin
  TWindow.Init(AParent, ATitle);
  ADlg := New(PSampleDialog, Init(@Self, 'EMPLOYEEINFO'));
end;

     Затем, каждый раз,  когда вы хотите отобразить диалог,
создайте и выведите его:

     begin
       Application^.MakeWindow(ADlg)
     end;

     И, наконец,    отдельный    объект    диалога    будет
автоматически удаляться при закрытии его порождающего окна.


             Работа с безрежимными диалоговыми блоками
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Диалоговые блоки  отличаются  от других дочерних окон,
таких как всплывающие окна и управляющие элементы, тем, что
они   за   время  существования  своего  порождающего  окна
создаются и уничтожаются многократно и редко  выводятся  на
экран  и  уничтожаются  вместе с порождающим окном.  Обычно
программа создает диалоговый блок в ответ  на  выбор  меню,
щелчок кнопкой "мыши", ошибку или другое событие.

     Таким образом,  нужно  убедиться,  что  вы  не строите
объекты диалоговых блоков снова и снова,  не уничтожая  их.
Помните  о  том,  что  все  построенные  диалоговые объекты
автоматически  включаются  в  списки   дочерних   окон   их
порождающих окон.

           Примечание: К  режимным диалоговым блокам это не
      относится, так как они автоматически уничтожаются при
      закрытии.


                        Завершение диалогов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Каждый блок  диалога  должен иметь способ его закрытия
пользователем.  Чаще всего  это  кнопки  OK  и/или  Cancel.
Потомки  TDialog автоматически отреагируют на нажатие одной
из этих кнопок вызовом метода EndDlg,  который  заканчивает
диалог.  Вы  можете  разработать  новые средства завершения
диалога,  если только они приводят  к  вызову  EndDlg.  Для
изменения  поведения  при закрытии вы можете переопределить
методы OK и Cancel.

     Например, вы  можете  переопределить  метод  OK  таким
образом,  что  введенные данные будут копироваться в буфер,
который находится вне объекта блока диалога.  Если ввод был
осуществлен  некорректно,  вы можете вывести блок сообщения
или сгенерировать звуковой сигнал.  Если  ввод  был  сделан
верно,  вы  можете  вызвать  EdnDlg.  Переданное  в  EndDlg
значение становится возвращаемым значением ExecDialog.

     Как и  в  случае  оконных  объектов,  объект   диалога
вызывает CanClose до закрытия блока диалога,  как это имело
место для объектов окна.  Вы можете переписать CanClose для
учета  условий  закрытия,  как  для блока диалога,  который
проверяет ввод  пользователя.  При  переписывании  CanClose
нужно  быть уверенным в том,  что вызывается унаследованный
от него метод,  т.к.  он вызывает методы CanClose  дочерних
окон.


                  Работа с управляющими элементами
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Все блоки диалога,  кроме самых простейших, имеют (как
дочерние окна) несколько управляющих  элементов  (например,
управления   редактированием,   блоки  списка  и  командные
кнопки).  Обратите внимание  на  то,  что  эти  управляющие
элементы  являются  не  объектами управляющих элементов,  а
только управляющими интерфейсными элементами, без методов и
полей    объекта.   Эта   глава   кроме   того   показывает
альтернативные  методы,   позволяющие   связывать   объекты
управления  с  элементами  управления  диалоговых  блоков с
использованием InitResource.

           Примечание: Использование управляющих объектов в
      окне (но не блоков диалога) показано в Главе 12.

     Между объектом  диалога  и  его  элементами управления
имеется двухсторонняя связь (можно сказать диалог). С одной
стороны   диалогу  нужно  манипулировать  его  управляющими
элементами, например, для заполнения блока списка. С другой
стороны   ему   нужно   обрабатывать   и   реагировать   на
сгенерированные сообщения  управляющих  событий,  например,
когда пользователь выбирает элемент блока списка.


               Взаимодействие с управляющим элементом
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Windows определят    набор    сообщений    управляющих
элементов,  которые посылаются  от  приложения  к  Windows.
Например,   имеются   следующие   сообщения  блока  списка:
lb_GetText,   lb_GetCurSel   и   lb_AddString.    Сообщения
управляющих  элементов  задают  специфическое  управление и
несут с собой информацию  в  аргументах  wParam  и  lParam.
Каждый  управляющий  элемент  в ресурсе диалога имеет номер
идентификатора,  который   вы   используете   для   задания
управляющего элемента,  принимающего сообщение. Для посылки
сообщения управляющему элементу нужно вызвать метод  TDialg
SendDlgItemMsg. Например, данный метод заполнит блок списка
диалога   элементами   текста   путем   посылки   сообщения
lb_AddString:

procedure TestDialog.FillListBox(var Msg: TMessage);
var
  TextItem: PChar;
begin
 TextItem := 'Item 1';
 SendDlgItemMsg(id_LB1, lb_AddString, 0,Longint(TextItem));
end;

где id_LB1 есть константа, равная ID блока списка.

     Если вам  потребуется  описатель одного из управляющих
элементов   диалога,    его    можно    получить    методом
GetItemHandle:

     GetItemHandle(id_LB1);


             Реакция на сообщения управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда пользователь   выбирает   управляющий   элемент,
например,  "нажимает" командную кнопку или делает  выбор  в
блоке   списка,  диалоговым  блоком  управляющего  элемента
порождающего  окна   принимается   специальное   сообщение,
основанное   на  дочернем  окне  и  называемое  управляющим
сообщением  (сообщение  управляющего  элемента).  Определим
метод   реакции   на   сообщение,  основанное  на  дочернем
идентификаторе,  в порождающем  типе  диалога  для  каждого
дочернего управляющего элемента:

     TTestDialog = object(TDialog)
     procedure HandleBN1Msg(var Msg: TMessage); virtual
                              id_First + id_BN1;
     procedure HandleListBox(var Msg: TMessage); virtual
                              id_First + id_LB1;
     end;

     В данном примере id_BN1  -  это  идентификатор  кнопки
управляющего  элемента,  а id_LB1 - это идентификатор блока
списка.  Щелчок "мышью" на командной кнопке даст сообщение,
посылаемое  в  диалоговый  блок.  Объект  диалогового блока
реагирует через динамический метод с  индексом,  основанным
на идентификаторе кнопки IDBN1.

           Примечание: Уведомляющие    сообщения   подробно
      поясняются в Главе 16 "Сообщения Windows"

     Каждое управляющее информационное сообщение  поступает
с  кодом  уведомления  - целочисленной константой,  которая
идентифицирует    произведенное     действие.     Например,
результатом выбора элемента из блока списка будет сообщение
с кодом lbn_SelChange,  где lbn_ - уведомление блока списка
(List   Box   Notification).  Нажатие  кнопки  "мыши"  дает
сообщение   bn_Clicked.   Ввод   в   управляющем   элементе
редактированием  приводит  к  сообщению с кодом en_Changed.
Имеются коды уведомления  для  блоков  списка,  управляющих
элементов   редактированием,   комбинированных   блоков   и
командных кнопок. Код уведомления передается в Msg.lParamHi
сообщения.   Для   восприятия   управляющих  информационных
сообщений  напишем  метод   реакции   для   типа   диалога,
обрабатывающий важные коды уведомления:

procedure TestDialog.HandleLB1Msg(var Msg: TMesage);
begin
  case Msg.lParamHi of
         lbn_SelChange:    { изменение порядка выбора };
         lbn_DblClk:    { выбор с помощью двойного щелчка};
  end;
end;
     Управляющие элементы, имеющие соответствующие объекты,
могут отвечать на уведомления сами. См. Главу 16.



                            Пример связи
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     В файле  с  текстом  программы DIALTEST.PAS,  основное
окно имеет  режимный  диалог,  определенный  типом  диалога
TTestDialog. Эта программа обеспечивает двухстороннюю связь
между объектом диалога и его управляющими  элементами.  Два
метода  -  IDBN1  и  IDLB1  -  являются  методами  реакции,
основанными на дочерних идентификаторах,  и вызываются  при
выборе пользователем управляющих элементов (дочерних окон).
Например,  при  выборе  пользователем  кнопки  диалога  BN1
('Fill List Box') вызывается метод IDBN1. Аналогично, когда
пользователь делает выбор в блоке списка, вызывается IDLB1.
С  другой  стороны,  для заполнения блока списка элементами
текста код  метода  IDBN1  посылает  в  диалог  управляющее
сообщение,    lb_AddString,    используя    метод   диалога
SendDlgItemMsg,

     Эта программа  также  показывает  как  путем  создания
нового  типа  диалога и связывания его с ресурсом диалога в
вызове  конструктора   Init   метода   TestWindow.RunDialog
создаются  новые диалоги.  Полный текст программы вы можете
найти на дистрибутивных дисках.


           Ассоциирование объектов управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     До этого момента  мы  имели  дело  с  реакцией  блоков
диалога  на  управляющие информационные сообщения,  которая
использовала  методы  реакции,   основанные   на   дочерних
идентификаторах.   Однако,  иногда  более  предпочтительно,
чтобы управляющий  элемент  сам  реагировал  на  сообщение.
Например,   вам  может  потребоваться  управляющий  элемент
редактирования, который позволяет вводить только цифры, или
командная кнопка, которая меняет стиль при своем "нажатии".
Это  можно  реализовать  с  помощью  объектов   управляющих
элементов в окнах (см.  Главу 12).  Однако, чтобы это имело
место  для  управляющих  элементов  диалога,  созданного  с
файлом ресурса,  вам нужно использовать для конструирования
объекта другой конструктор.

     При организации связей вы создаете объект управляющего
элемента  для  представления  управляющего объекта диалога.
Этот объект управления  дает  вам  гибкость  в  реакции  на
управляющие    сообщения.    Он    дает   вам   возможность
использования набор методов объектов управляющих элементов,
описанных в Главе 12.

     Для связи  объекта  с управляющим элементом определите
сначала объект управляющего элемента. Он должен быть создан
в   конструкторе   диалога.   Однако,  вместо  того,  чтобы
использовать конструктор Init, как это показано в Главе 12,
следует использовать InitResource, который берет в качестве
параметров порождающее окно  и  идентификатор  управляющего
элемента  (из  ресурса  диалога).  Это  приводит  к  вызову
методов реакции на сообщения объектов управляющих элементов
вместо  обработки  элементов по умолчанию.  Для этого нужно
определить    новый    тип    объекта,    производный    от
предусмотренного типа управляющего элемента.

     Обратите внимание,  что  в отличие от задания оконного
объекта, которое предполагает два шага (Init и MakeWindow),
поскольку управляющий элемент уже существует, связь объекта
с  управляющим  элементов  выполняется  за  один  шаг:   он
загружается   из  диалогового  ресурса.  Вам  нужно  только
сообщить InitResource, какой управляющий элемент из ресурса
вы  хотите  связать  с  объектом,  используя  идентификатор
управляющего элемента.


                   Использование диалоговых окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Основная разница между диалоговыми  блоками  и  окнами
состоит  в  том,  что диалог имеет соответствующий ресурс и
задает тип и расположение своих управляющих  элементов.  Но
окно также может иметь управляющие элементы.

     Одним из  подходов  размещения управляющих элементов в
окне является использование объектов управляющих  элементов
(как  показано  в  Главе  12).  Другой подход - это слияние
возможностей диалоговых блоков и окон,  как это делается  в
объектном типе TDlgWindow, что позволяет получить гибридный
объект,  называемый   диалоговым   окном.   Второй   подход
предусматривает   более   удобный   способ   построения   и
управления многими управляющими элементами  в  окне.  Кроме
того,  он  предлагает  для  диалоговых  блоков более гибкие
средства окон.

     TDglWindow является потомком TDialog и  наследует  его
методы,  такие  как  Execute,  Create,  Ok и EndDlg.  Как и
диалоговые блоки,  диалоговые  окна  имеют  соответствующий
ресурс  диалогового  блока.  С другой стороны,  как и окна,
диалоговые   окна   имеют   соответствующий   класс   окон,
определяющий  среди  всего  прочего  пиктограмму,  курсор и
меню.  Из-за связи с оконным классом в  потомке  TDlgWindow
следует     переопределять     методы     GetClassName    и
GetWindowClass.  Этот класс  должен  быть  тем  же,  что  и
перечисленный в диалоговом ресурсе.

     В большинстве  случаев  вы будете выполнять диалоговые
окна как и другие окна или безрежимные  диалоговые  окна  с
помощью методов Create и Show, а не метода Execute.

     В тех  случаях,  когда  основное окно должно содержать
много сложных управляющих элементов, хорошим использованием
диалоговых   окон   является   основное   окно  приложения.
Например,  программа-калькулятор  может  иметь  в  качестве
основного  окна  диалоговое  окно,  где кнопки калькулятора
заданы как управляющие элементы  диалогового  ресурса.  Это
позволило   бы   вывести   в   основном  окне  также  меню,
пиктограмму и курсор.


           Использование предопределенных диалоговых окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Для выполнения  двух типов общих функций ObjectWindows
предусматривает стандартные диалоговые блоки.  Одно их них,
окно  диалогового блока,  выводит пользователю однострочную
подсказку.  Другое,  файловое  диалоговое  окно,  позволяет
пользователю  задать  имя  файла и каталог для открытия или
сохранения файла.


               Использование диалоговых блоков ввода
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Диалоговые блоки   ввода   -   это   простые   объекты
диалоговых блоков, определяемых типом TInputDialog, которые
выводят пользователю подсказку со строкой текста.

     Вы можете запускать диалоги  ввода  как  режимные  или
безрежимные диалоговые блоки, но обычно вы будете выполнять
их как режимные.  С объектом диалога  ввода  связан  ресурс
диалога   ввода.   Он   находится   в  файле  ObjectWindows
OSTDDLGS.RES.

          Примечание: Использование     модуля      StdDlgs
      автоматически включает ресурсы в OSTDDLGS.RES.

     Каждый раз   при   конструировании   диалога  ввода  с
использованием  метода  Init,  вы   задаете   для   диалога
заголовок,  подсказку  и текст по умолчанию.  Покажем вызов
конструктора Init объекта диалога ввода:

var SomeText: array[0..79] of Char;
begin
  AnInputDlg.Init(@Self, 'Caption', 'Prompt', SomeText,
        SizeOf(SomeText))
    .
    .
    .
end;

     В данном  примере  EditText  -  это  текстовый  буфер,
который   заполняется   вводом   пользователя,   когда   он
"нажимает" кнопку OK.  Когда пользователь "нажимает" кнопку
OK или клавишу Enter,  строка введенного  в  диалоге  ввода
текста автоматически передается в массив символов,  который
хранит текст по умолчанию.  В данном примере конструируется
и отображается блок диалога и считывается текст:

procedure TSampleWindow.Test(var Msg: TMessage);
var
  EditText: array[0..255] of Char;
begin
  EditText:='Frank Borland';
  if ExecDialog(New(PInputDialog, Init(@Self, 'Data Entry',
  'Введите имя:', EditText, SizeOf(EditText)))) =id_OK then
  MessageBox(HWindow, EditText, 'Имя =', mb_OK);
  else MessageBox(HWindow, EditText,
                  'Имя пока имеет значение:',mb_OK);
end;



                Файловые диалоговые блоки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Файловые диалоговые  блоки   являются   другим   типом
диалогов,  поставляемых с ObjectWindows в типе TFileDialog.
Файловый диалоговый блок следует использовать  каждый  раз,
когда  вы  желаете  побудить пользователя ввести имя файла,
например  в  функциях  File  Open  и  File  Save  во   всех
приложениях. См. Рис. 11.1.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫFile OpenЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і                                                     і
і               ЪДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДї    і
і    Имя файла: і *.pas            і  і±±±±OK±±±±і    і
і               АДДДДДДДДДДДДДДДДДДЩ  АДДДДДДДДДДЩ    і
і                                     ЪДДДДДДДДДДї    і
і    Каталог: a:\                     і±±Cancel±±і    і
і                                     АДДДДДДДДДДЩ    і
і    Файлы:             Каталоги:                     і
і    ЪДДДДДДДДДДДДДДВДї ЪДДДДДДДДДДДДДДВДї            і
і    іcollect3.pas  і^і і[-a-]         і^і            і
і    іcollect4.pas  ГДґ і[-c-]         ГДґ            і
і    іdiatest.pas   і±і і[-f-]         іЫі            і
і    іedittest.pas  іЫі і[-g-]         і±і            і
і    іewndtest.pas  і±і і[-h-]         і±і            і
і    іhelpwind.pas  і±і і[-i-]         і±і            і
і    іlboxtest.pas  і±і і[-j-]         і±і            і
і    іmditest.pas   ГДґ і[-k-]         ГДґ            і
і    іpaltest.pas   іvі і[-w-]         іvі            і
і    АДДДДДДДДДДДДДДБДЩ АДДДДДДДДДДДДДДБДЩ            і
і                                                     і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

Рис. 11.1 Файловый диалоговый блок.

     В большинстве  случаев   файловые   диалоговые   блоки
выполняются  как  режимные.  С  объектом  файлового диалога
связан ресурс  файлового  диалогового  блока,  имеющийся  в
ObjectWindows  в  файле OSTDDLGS.RES.  Использование модуля
OStdDlgs автоматически включает файл ресурса.


             Инициализация файлового диалогового блока
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TFileDialog определяет   конструктор   Init,   который
позволяет  задать  маску файла и буфер для считывания имени
файла.  Маска файла (такая как '*.TXT') ограничивает файлы,
перечисляемые в комбинированном блока (аналогично тому, как
это делается в команде DOS DIR *.TXT).  Имя файла  и  маска
передаются  в  записи  типа  TFileDlgRec.  Приведем  пример
вызова файлового диалогового блока Init:

     var
       FileRec: TFileDlgRec;
       IsOpen: Boolean;
     begin
       StrCopy(FileRec.Name, 'TEST1.TXT');
       StrCopy(FileRec.Mask, 'C:\*.TXT');
       IsOpen := True;
       AFileDlg.Init(@Self, FileRec, IsOpen);
        .
        .
        .
     end;

     Последний параметр указывает, будет ли диалог диалогом
открытия  или  сохранения  (как  описывается  в   следующем
разделе).


               Выполнение файловых диалоговых блоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Существует два   вида   файловых   диалоговых  блоков:
диалоговый блок открытия файла и диалоговый блок сохранения
файла. Они различаются текстом кнопки в правом верхнем углу
диалогового  окна.  В  зависимости  от  того,   запрашивает
пользователь  открытие  или сохранение файла,  на командной
кнопке будет написано Open  или  Save.  Когда  вы  вызовите
ExecDialog,  то получите тип диалогового блока,  заданных в
конструкторе IsOpen параметром типа Boolean.  Если файловый
диалоговый блок строится с IsOpen, установленным в True, то
диалоговый блок будет работать как диалоговый блок открытия
файла. Если он строится с IsOpen, установленным в False, то
файловый диалоговый блок будет блоком сохранения файла.


     Дополнительным средством  файлового  диалогового блока
ObjectWindows является  то,  что  он  выводит  пользователю
подсказку,  хочет  ли  пользователь сохранить файл с именем
уже существующего файла (см.  Рис.  11.2).  В другой раз вы
можете  запросить  пользователя,  хочет ли он открыть новый
файл или очистить текущий текст без  сохранения.  Поскольку
это  должно происходить перед выводом файлового диалогового
блока,  то не является  частью  поведения  этого  блока.  В
примере  программы Steps в первой части данного руководства
перед загрузкой рисунка из файла проверяется метод CanClose
его основного окна.

          ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
          і±=±ЫЫЫЫЫЫFile exists! Overwrite it?ЫЫЫЫЫЫЫЫі
          ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
          і                                           і
          і    C:\TEMP\NICELINE.PTS                   і
          і                                           і
          і   ЪДДДДДДДДДДї            ЪДДДДДДДДДДї    і
          і   і±±±Yes±±±±і            і±±±No±±±±±і    і
          і   АДДДДДДДДДДЩ            АДДДДДДДДДДЩ    і
          і                                           і
          АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 11.2  Предупреждение  пользователя  о  перезаписи
существующих файлов.

     File exists! Overwrite it? - файл существует, затереть
его?

     Приведем пример  типичного  использования  диалогового
окна:

procedure TMyWindow.OpenSelectedFile;
var FileRec: TFileDlgRec;
begin
  StrCopy(FileRec.Name, 'HEDGEHOG.PAS');
  StrCopy(FileRec.Mask, '*.PAS');
  if ExecDialog(New(PFileDialog,
                Init(@Self, FileRec, True))) = id_Ok then
  begin
    Assign(AFile, StrPas(FileRec.Name));
      .
      .
      .
  end;
end;


              Глава 12. Объекты управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Windows предусматривает ряд  стандартных  интерфейсных
элементов,  называемых управляющими элементами. Управляющие
элементы   -   это    специальные    окна    с    некоторым
предопределенным   поведением.  ObjectWindows  обеспечивает
интерфейсные объекты для стандартных управляющих  элементов
Windows,  так  что  вы можете использовать эти интерфейсные
элементы в  своих  приложениях.  Интерфейсные  объекты  для
управляющих   элементов  называются  объектами  управляющих
элементов или просто управляющими объектами.

           Примечание: Об       интерфейсных       объектах
      рассказывается в Главе 9.

     Данная глава охватывает следующие темы:

     * Задачи, общие для всех управляющих объектов:

       - построение   и  уничтожение  объектов  управляющих
элементов;

       - взаимодействие с другими управляющими объектами.

     * Установка и чтение значений управляющих элементов.

     * Использование     специализированных     управляющих
элементов.

     Кроме того,   в   данной  главе  подробно  описывается
использование каждого интерфейсного объекта для стандартных
управляющих элементов Windows.


 Где можно использовать объекты управляющих элементов?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Управляющие элементы  -  это  специализированные окна,
которые  позволяют  пользователю  предопределенным  образом
задавать   или  выбирать  данные.  Чаще  всего  управляющие
элементы содержатся в  диалоговом  блоке.  Диалоговый  блок
управляет  их  определением  с  помощью ресурса диалогового
блока,  так что вам не потребуется часто использовать в них
объекты. Режимные диалоговые блоки не располагают способами
взаимодействия с управляющим объектом, поэтому в диалоговых
блоках  объекты  управляющих  элементов используются обычно
для установки и считывания значений управляющих элементов с
помощью   передачи.   Передача   для  объектов  управляющих
элементов  в  диалоговых  блоках  и  в  окнах   выполняется
одинаково (как описывается ниже в этой главе).

           Примечание: Диалоговые  блоки  и  их управляющие
      элементы описываются в Главе 11  "Объекты  диалоговых
      блоков".

     Возможно вы захотите использовать управляющие элементы
в окнах,  поэтому в данной главе описывается  использование
управляющих  элементов  вне  диалоговых  блоков.  Следующая
таблица    описывает    управляющие    элементы    Windows,
поддерживаемые типами объектов ObjectWindows:

    Управляющие элементы Windows,
   поддерживаемые в ObjectWindows      Таблица 12.1
ЪДДДДДДДДДДДВДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іУправляющийі Тип объектаі          Использование
і   элемент і            і                                і
ГДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іблок спискаіTListBox    іПрокручиваемый список элементов,і
і           і            іиз которых можно сделать выбор. і
ГДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іполоса     іTScrollBar  іПолоса   прокрутки,  аналогичнаяі
іпрокрутки  і            ітем,которые выводятся в  прокру-і
і           і            ічиваемых окнах и блоках списка. і
ГДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і"нажимаемаяіTButton     іКнопка для "нажатия со связаннымі
ікнопка     і            іс ней текстом.                  і
ГДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ікнопка с   іTCheckBox   іСостоящаяиз блока кнопка,котораяі
інезависимойі            іможет выбираться или нет,со свя-і
іфиксацией  і            ізанным текстом.                 і
ГДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДД-ДДДДДДДДґ
ікнопка с   іTRadioButtonіКнопка, которая может выбиратьсяі
ізависимой  і            іили   нет. Обычно   используетсяі
іфиксацией  і            іво взаимоисключающих группах.   і
ГДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іблок группыіTGroupBox   іСтатический прямоугольник с тексі
і           і            ітом в левом верхнем углу.       і
ГДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іуправляющийіTEdit       іПоле для ввода текста пользоватеі
іэлемент    і            ілем.                            і
іредактированияі         і                             і
ГДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
істатический   іTStatic  іФрагмент отображаемого текстаі
іуправляющий   і         ікоторый не может быть изменені
іэлемент       і         іпользователем.               і
ГДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іКомбиниро-    іTComboBoxіКомбинация блокаспискаиуправля
іванный блок   і         іющего элемента редактирования.
АДДДДДДДДДДДДДДБДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


                   ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
 Командная строка: і                               і
                   АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                   ^
                   А редактируемый упрвляющий элемент

 ЪДДДДДДДДДДї      ЪДДДДДДДДДДї
 і±±±OK±±±±±і      і±±Cancel±±і   <Д командные кнопки
 АДДДДДДДДДДЩ      АДДДДДДДДДДЩ

     ЪДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДї
     і < і±±±±±±±±±±±±±±±±±±Ы±±±±±±±±±±±±±±±±±±±±±±і > і
     АДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДЩ
                 ^
     полоса прокрутки ДЩ


      ЪДДДДДДДДДДДДДДВДї
      іcollect3.pas  і^і  <Д блок списка
      іcollect4.pas  ГДґ
      іdiatest.pas   і±і
      іedittest.pas  іЫі            ЪДДДДДДДДДДДДДДДДї
      іewndtest.pas  і±і            і *.txt          і
      іhelpwind.pas  і±і            АДВДДДДДДДДДДДДДДЕДї
      іlboxtest.pas  і±і              іnetlect3.txt  і^і
      іmditest.pas   ГДґ              іnetlect4.txt  ГДґ
      іpaltest.pas   іvі              іdiatext.txt   і±і
      АДДДДДДДДДДДДДДБДЩ              іreadtxt.txt   іЫі
                                      іvwndtext.txt  і±і
             комбинированный блок Д>  іwhelpwnd.txt  і±і
                                      іwboxtext.txt  і±і
                                      іydrtest.txt   ГДґ
                                      іxaltesx.txt   іvі
                                      АДДДДДДДДДДДДДДБДЩ

     Рис. 12.1 Стандартные управляющие элементы Windows.



              Что такое объекты управляющих элементов?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для Windows   управляющие   элементы   -   это  просто
специализированные виды окон.  В ObjectWindows тип TControl
является   потомком   типа  TWindow,  так  что  большинство
объектов управляющих элементов можно использовать  как  все
другие  оконные  объекты.  Объекты управляющих элементов по
способу их создания и уничтожения и  способу  их  поведения
(как дочерние окна) аналогичны оконным объектам. Однако они
отличаются от других окон способом  реакции  на  сообщения.
Например,   методы  Paint  объектов  управляющих  элементов
запрещены.  Windows берет на себя  функции  по  отображению
своих стандартных управляющих элементов.

     Может оказаться,  что перечисленные в приведенной выше
таблице управляющие  элементы  отвечают  всем  потребностям
вашего  приложения.  Однако  могут возникать случаи,  когда
требуется   определить   наследующие    типы    управляющих
элементов.  Например,  вы можете создать специализированный
блок  списка   TFontListBox,   производный   от   TListBox,
содержащий имена всех доступных вашему приложению шрифтов и
автоматически выводящих их при создании  нового  экземпляра
объекта.

     Тип TControl,    как    и   TWindowsObject,   является
абстрактным объектным типом.  Вы можете создать  экземпляры
его  потомков  - TListBox,  TButton и другие - но не можете
создать экземпляр TControl.

     Заметим, что вам,  возможно,  никогда  не  потребуется
создавать новый объектный тип,  наследующий непосредственно
из TControl.  TControl инкапсулирует свойства и стандартные
управляющие элементы, о которых уже знает Windows. Создание
специализированных  управляющих  элементов  описывается   в
данной главе ниже.


 Построение и уничтожение объектов управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Обычно в  объекта  порождающего  окна  для  каждого из
дочерних окон определяется поле данных. Независимо от того,
какой  вид  объектов вы используете,  для каждого из них вы
можете выполнить несколько задач:

     * Построение объекта управляющего элемента.

     * Вывод управляющего элемента.

     * Уничтожение управляющего элемента.


              Построение объекта управляющего элемента
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Построение управляющих   элементов    отличается    от
построения  любых других дочерних окон.  Обычно конструктор
порождающего окна вызывает конструкторы всех  его  дочерних
окон.  Однако  в  случае  управляющих  элементов  не просто
создается связь "родитель -  потомок",  но  устанавливается
также связь "окно - управляющий элемент".  Это очень важно,
поскольку кроме обычных связей  между  предком  и  потомком
управляющие  элементы взаимодействуют с порождающими окнами
особыми способами (через уведомления).

           Примечание: Уведомления описываются в  Главе  16
                       "Сообщения Windows".
     Чтобы построить и инициализировать объект управляющего
элемента, нужно сделать следующее:

     * добавить   в   объект  порождающего  окна  поле  (не
     обязательно);   *    вызвать    конструктор    объекта
     управляющего    элемента;    *    изменить    атрибуты
     управляющего элемента;  * инициализировать управляющий
     элемент в SetupWindows.


         Вызов конструкторов объектов управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В то  время  как обычный конструктор объекта дочернего
окна имеет только два параметра (порождающее окно и  строку
заголовка),  конструктор  управляющего  объекта имеет их не
менее шести.  Объект блока списка имеет наиболее простой из
всех  управляющих  элементов  конструктор,  который требует
задания только шести параметров:

     - объекта порождающего окна;
     - идентификатора управляющего элемента;
     - координату x верхнего левого угла;
     - координату y верхнего левого угла;
     - ширину;
     - высоту.

     TListBox.Init описывается следующим образом:

     constructor TListBox.Init(AParent: PWindowsObject;
                    AnID: Integer; X, Y, W, H: Integer);

     Все объекты управляющих элементов ObjectWindows (кроме
TMDIClient)  требуют не менее 6 параметров.  Большинство из
них   воспринимают   также   параметр,    задающий    текст
управляющего элемента.


                     Присваивание полям объекта
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Часто при  построении  управляющего  элемента  в  окне
желательно  сохранять  указатель  на  управляющий элемент в
поле оконного объекта.  Например,  чтобы добавить  в  окно,
определенное  типом  TSampleWindow  блок списка,  вы можете
задать в поле TSampleWindow поле TheList  и  присвоить  ему
блок списка:

constructor SampleWindow.Init(AParent: PWindowsObject;
                              ATitle: PChar);
begin
   inherited Init(AParent, ATitle);
   TheList := New(PListBox,
                  Init(@Self, id_LB1, 20, 20, 100, 80));
end;

     Порождающие окна   автоматически  поддерживают  список
своих дочерних окон,  включая управляющие элементы.  Однако
удобнее   манипулировать   управляющими   объектами,  когда
имеются соответствующие поля объекта. Управляющие элементы,
с   которыми   часто   работать  не  требуется  (такие  как
статический текст  или  групповые  блоки)  могут  не  иметь
соответствующих полей.

     При наличии    поля    объекта    построение   объекта
управляющего  элемента  не  представляет  труда.  Например,
чтобы   добавить  в  TSampleWindow  групповой  блок,  нужно
сделать следующее:

constructor SampleWindow.Init(AParent: PWindowsObject;
                              ATitle: PChar);
begin
   inherited Init(AParent, ATitle);
   TempGroupBox := New(PListBox,
                      Init(@Self, id_LB1, 'Group name',
                      140, 20, 100, 80));
end;



    Изменение атрибутов объекта управляющего элемента
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Все управляющие объекты, кроме TMDIClient, получает от
вызова  TControl.Init  используемые  по   умолчанию   стили
ws_Child  и  ws_Visible.  Если  вы  хотите  изменить  стиль
управляющего элемента,  то можно изменить  поле  Attr.Style
(как  это  описывается  для  окон  в Главе 10).  Каждый тип
управляющего   элемента   имеет   также    другие    стили,
определяющие его конкретные характеристики.


                Инициализация управляющего элемента
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Экранный элемент  управляющего  объекта  автоматически
создается   методом   SetupWindow,   наследуемым   объектом
порождающего   окна.  Убедитесь,  что  при  создании  новых
производных  типов  окон  вы  вызываете  наследуемый  метод
SetupWindow перед любой другой инициализацией окна.

     При необходимости   методом  SetupWindow  порождающего
окна  также  устанавливаются  и   заполняются   управляющие
элементы. Приведем пример типичного метода SetupWindow:

procedure TSampleWindows.SetupWindow;
begin
  inherited SetupWindow;  { создает дочерние управляющие
                            элементы }
  { добавляет элементы в список }
  TheList^.AddString('Элемент 1');
  TheList^.AddString('Элемент 2');
end;

     Заметим, что  инициализация   управляющего   элемента,
такая   как   добавление   строк   в  блок  списка,  должна
выполняться в  SetupWindow,  а  не  в  конструкторе.  Вызов
такого  метода  как  TListBox.AddString приводит к передаче
сообщений экранному управляющему элементу. Так как экранный
элемент   до  вызова  наследуемого  метода  SetupWindow  не
создается,  попытки инициализации управляющих элементов  до
этого момента завершится неудачно.


                  Сохранение управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для вывода   на   экран   управляющих   элементов  нет
необходимости вызывать метод Show.  Как дочерние окна,  они
автоматически  выводятся  на  экран и повторно отображаются
вместе с порождающим окном.  Однако, вы можете использовать
Show  для  сокрытия  или  вывода  управляющих  элементов по
запросу.


                 Уничтожение управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Порождающее окно отвечает за  уничтожение  управляющих
элементов.   Экранный   управляющий  элемент  автоматически
уничтожается вместе с элементом  порожденного  окна,  когда
пользователь  закрывает  окно  или  приложение.  Деструктор
порождающего окна  автоматически  уничтожает  все  дочерние
объекты.


                  Связь с управляющими элементами
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Связь между   оконным   объектом  и  его  управляющими
объектами  в  некотором  смысле  аналогичны  взаимодействию
между   объектом   диалогового  блока  и  его  управляющими
элементами.  Как  и  диалоговому  блоку,   окну   требуется
механизм  для  работы  с  его управляющими элементами и для
ответа на управляющие события,  такие  как  выбор  в  блоке
списка.


               Работа с управляющими элементами окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Диалоговые окна  работают с их управляющими элементами
путем передачи им сообщений с помощью метода SendDlgItemMsg
с    константой    управляющего    сообщения   (такой   как
lb_AddString) в качестве параметра (см.  Главу 11). Объекты
управляющих  элементов  сильно  упрощают этот процесс путем
использования методов (таких  как  TListBox.AddString)  для
непосредственной   работы   с  управляющими  элементами  на
экране.

     Когда объекты   управляющих   элементов   окна   имеют
соответствующие поля объекта, то вызвать управляющие методы
достаточно просто:

     TheListBox^.AddString('Scotts Valley');


                  Реакция на управляющие элементы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Реакция на взаимодействие с  пользователем  с  помощью
управляющих  элементов  несколько более сложна,  чем просто
вызов методов объектов управляющих элементов. Чтобы узнать,
как отвечать на сообщения управляющих элементов, см. раздел
"Команды,   уведомления   и   идентификаторы    управляющих
элементов" в Главе 16.


              Действие, аналогичное диалоговому блоку
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Диалоговый блок  с  управляющими  элементами позволяет
пользователю с помощью клавиши Tab циклически  перемещаться
по   всем  элементам  диалогового  блока.  Он  может  также
использовать клавиши стрелок для выбора в  групповом  блоке
кнопок   с  зависимой  фиксацией.  Чтобы  эмулировать  этот
клавиатурный интерфейс для окон с управляющими  элементами,
вызовите  для  оконного  объекта  в  его конструкторе метод
EnableKBHandler объекта TWindowsObject.


           Использование конкретных управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Каждый вид управляющих  элементов  работает  в  чем-то
отлично  от  других.  В  данном  разделе  вы  можете  найти
конкретную информацию о том,  как использовать объекты  для
каждого из стандартных управляющих элементов Windows.


                     Использование блока списка
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Использование блока  списка  -  это  простейший способ
запросить пользователя программы Windows  выбрать  что-либо
из  списка.  Блоки  списка  инкапсулируются объектным типом
TListBox.  TListBox определяет методы для  создания  блоков
списка,  модификации  списка  элементов,  запроса состояния
списка  элементов   и   поиска   выбранного   пользователем
элемента.


                  Построение объектов блока списка
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Конструктор Init  в TListBox воспринимает только шесть
параметров,  которые необходимы всем  объектам  управляющих
элементов.  Этими  параметрами  являются  порождающее окно,
идентификатор и размеры управляющего элемента X, Y, W и H:

LB1 := New(PListBox, Init(@Self, id_LB1, 20, 20, 340,100));

     TListBox получает  используемый  по  умолчанию   стиль
управляющего   элемента   ws_Child   or  ws_Visible,  затем
прибавляется lbs_Standard.  lbs_Standard -  это  комбинация
lbs_Notify    (для   получения   уведомляющих   сообщений),
ws_VScroll (для получения  вертикально  полосы  прокрутки),
lbs_Sort  (для  сортировки  списка  элементов  в алфавитном
порядке) и ws_Border (для вывода  рамки).  Если  вы  хотите
получить    другой    стиль   блока   списка,   то   можете
модифицировать поле Attr.Style в  TListBox.  Например,  для
блока   списка,   не   сортирующего  свои  элементы,  можно
использовать следующее:

LB1 := New(PListBox, Init(@Self, id_LB1, 20, 20, 340,100));
     LB1^.Attr.Style := LB1^.Attr.Style and not lbs_Sort;


                     Модификация блоков списка
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     После создания  блока  списка  вам нужно заполнить его
элементами  списка,  который  должны   представлять   собой
строки.  Позднее  вы можете добавить,  вставить или удалить
элементы,  либо  полностью   очистить   список.   Указанные
действия вы можете выполнить с помощью методов, приведенный
в следующей таблице:

 Методы модификации блоков списка     Таблица 12.2
ЪДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іВыполняемое действие     і            Метод             і
ГДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іДобавление элемента      і AddString                    і
іВставка нового элемента  і InsertString                 і
іДобавление элемента      і InsertString                 і
іУдаление элемента        і DeleteString                 і
іУдаление каждого элементаі ClearList                    і
іВыбор элемента           і SetSellIndex или SetSelStringі
АДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


                    Запрос в блоках списка
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Существует пять методов, которые вы можете вызвать для
получения информации о списке, содержащейся в объекте блока
списка. Эти методы перечислены в следующей таблице:

 Методы запроса блока списка       Таблица 12.3
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДї
і    Получаемая информация        і  Вызываемый метод і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДґ
і    Число элементов в списке     і   GetCount        і
і    Элемент с конкретным индексомі   GetString       і
і    Длина конкретного элемента   і   GetStringLen    і
і    Выбранный элемент            і   GetSelString    і
і    Индекс выбранного элемента   і   SEgSelIndex     і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДЩ


                       Реакция на блок списка
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Методы модификации  и  запроса  блока списка позволяют
вам установить значения или определять в каждый  конкретный
момент  состояние блока списка.  Однако,  чтобы знать,  что
делает пользователь в данный момент с  блоком  списка,  вам
нужно  реагировать  на  уведомляющие сообщения управляющего
элемента.

     Пользователь может выполнять с  блоком  списка  только
следующие действия: прокрутку списка, щелчок кнопкой "мыши"
на  элементе  списка,  двойной  щелчок  кнопкой  "мыши"  на
элементе.  Когда выполняется одно из этих действий, Windows
посылает  порождающему  окну  блока   списка   уведомляющее
сообщение блока списка. Обычно метод реакции на уведомление
для обработки сообщений для каждого  управляющего  элемента
порождающего  объекта  определяется  в  порождающем оконном
объекте.

     Каждое уведомляющее сообщение блока списка содержит  в
поле  lParamHi  параметра  Msg  код  уведомления (константу
lbn_),  который специфицирует характер  действия.  Наиболее
общие коды lbn перечислены в следующей таблице:

 Информационные сообщения блока списка    Таблица 12.2
ЪДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іwParam і                   Действие                      і
ГДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іlbn_SelChangeіОтдельным  нажатием   кнопки "мыши"былвыбран
і             іэлемент.                                   і
ГДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іlbn_DblClkіЭлементбылвыбрандвойным щелчком кнопки "мыши".і
ГДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іlbn_SetFocusіПользовательпереместилфокус  на  блок спискаі
і       іпростым или двойным нажатием кнопки  "мыши", либоі
і       іклавишей Tab. Предшествует lbn_SelChange.        і
АДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Приведем пример  метода порождающего окна по обработке
сообщений блока списка:

procedure TLBoxWindow.HandleLB1Msg(var Msg: TMessage);
var
 Idx: Integer;
 ItemText: string[10]
begin
 if Msg.lParamHi=lbn_SelChange then
 begin
  Idx:=LB1^.GetSelIndex;
  if LB1^.GetStringLenIdx)<11 then
   begin
    LB1^.GetSelString(@ItemText, 10);
    MessageBox(HWindow, @ItemText, 'Вы выбрали:', mb_OK);
   end;
 end;
   else DefWndProc(Msg);
 end;

     Пользователь делает выбор, если Msg.lParamHi совпадает
с константой lbn_SelChange.  Если это так, то берется длина
выбранной строки,  проверяется, что она помещается в строку
из 10 символов,  и выбранная строка  показывается  в  блоке
сообщения.



                     Пример программы: LBoxTest
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Программа LBoxTest -  это  полная  программа,  которая
создает  окно  с  блоком  списка.  После запуска приложения
появляется   основное   окно   с   блоком   списка.   Когда
пользователь  выбирает  элемент  блока  списка,  появляется
диалог  с  выбранным  элементом.   Обратите   внимание   на
взаимоотношения   между  объектом  окна  и  объектом  блока
списка. Блок списка - это не просто дочернее окно основного
окна, основное окно владеет им как полем объекта. LB1 - это
одно из полей объекта основного окна, и оно содержит объект
блока  списка.  Полный  текст  программы содержится в файле
LBOXTEST.PAS на ваших дистрибутивный дискетах.


          Использование статических управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Статические управляющие   элементы   -   это    обычно
неизменяемые модули текста или простые изображения, которые
могут появляться  на  экране  в  окне  или  блоке  диалога.
Пользователь    не    взаимодействует    со    статическими
управляющими элементами, хотя программа и может изменять их
текст.  Рис.  12.2 показывает множество стилей статического
управления и соответствующих констант стиля Windows.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫStatic Control TesterЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і                                                        і
і Default Static        Sample Text                      і
і                                                        і
і ss_Simple             Sample Text                      і
і                                                        і
і ss_Left               Sample Text                      і
і                                                        і
і ss_Center                      Sample Text             і
і                                                        і
і ss_Right                                  Sample Text  і
і                       ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДї   і
і ss_BlackFrame         і                            і   і
і                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ   і
і                       ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДї   і
і ss_BlackRect          іЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі   і
і                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ   і
і                       ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДї   і
і ss_GrayFrame          і                            і   і
і                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ   і
і                       ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДї   і
і ss_GrayRect           і±±±±±±±±±±±±±±±±±±±±±±±±±±±±і   і
і                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ   і
і                                                        і
і ss_NoPrefix                            Sample & Text   і
і                                                        і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 12.2 Стили статических управляющих элементов.




            Построение статических управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Пользователь никогда        не         взаимодействует
непосредственно  со  статическими  управляющими элементами,
поэтому приложение будет очень редко,  если  вообще  будет,
принимать   уведомляющие  сообщения  управляющих  элементов
относительно    статического     управляющего     элемента.
Следовательно,    большинcтво    статических    управляющих
элементов можно сконструировать с  идентификатором  ресурса
-1 или некоторым другим неиспользуемым числом.

     Конструктор Init  в  TStatic конструирует новый объект
статического управления и описывается следующим образом:

constructor TStatic.Init(AParent: PWindowsObject;
                      AnID: Integer; ATitle: PChar;
                      X, Y, W, H: Integer; ATextLen: Word);

     Кроме обычных параметров  Init  управляющего  объекта,
TStatic.Init имеет два дополнительных параметра - текстовую
строку ATitle и максимальную длину текста  ATextLen.  Текст
должен    заканчиваться   нулевым   символом,   поэтому   в
действительности число  отображаемых  символов  на  единицу
меньше заданной в конструкторе длины текста. Типичный вызов
для построения  статического  управляющего  элемента  может
выглядеть так:

Stat1 := New(Static, Init(@Self, id_ST1, '&Text',20,50,
                               200, 24, 6));

     После его   создания   обращаться    к    статическому
управляющему объекту или манипулировать им требуется редко,
поэтому поле,  содержащее статический управляющий объект, в
общем случае присваивать не нужно.

     Используемым по    умолчанию    стилем    статического
управляющего элемента  является  назначенный  по  умолчанию
стиль управляющего элемента, то есть ws_Child or ws_Visible
(выравнивание влево).  Чтобы изменить стиль,  модифицируйте
поле   Attr.Style.   Например,   чтобы  центрировать  текст
управляющего элемента, сделайте следующее:

Stat1^.Attr.Style := Stat1^.Attr.Style and (not ss_Left) or
                          ss_Center;

     В статическом  управляющем  элементе  есть возможность
подчеркивания  одного  или  нескольких  символов  в  строке
текста.  Реализация  и  действие  этого  эффекта аналогичны
подчеркиванию первого символа в выборе  меню:  Insert  и  &
должны  непосредственно  предшествовать  символу  в строке,
который будет подчеркиваться. Например, для подчеркивания T
в  слове 'Text' нужно в вызове Init строку '&Text'.  Если в
строке вам нужно  использовать  &,  применяйте  статический
стиль Windows ss_NoPrefix (см.  Рис.  12.2).  Для уточнения
текущего текста, который хранится в статическом управляющем
элементе, используется метод GetText.

         Модификация статического управляющего элемента

     Для изменения    текста    статического   управляющего
элемента TStatic имеет два  метода.  SetText  устанавливает
статический  текст,  передаваемый  аргументом PChar.  Clear
удаляет статический текст.  Однако,  вы не  можете  сменить
текст  статического  управляющего  элемента,  созданный  со
стилем ss_Simple.

             Опрос статических управляющих элементов

     Чтобы считать  текст,   содержащийся   в   статическом
управляющем элементе, используйте метод GetText.


                     Пример программы StatTest
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Программа StatTest    создает   статическое   тестовое
приложение,  показанное на Рис.12.2.  Обратите внимание  на
то, что метки ('Default Static' и 'ss_Simple') представляют
собой статистические  управляющие  элементы,  также  как  и
'Sample Text',  черные и серые прямоугольники. Полный текст
программы  содержится  в  файле   STATTEST.PAS   на   ваших
дистрибутивных дискетах.


                   Использование командных кнопок
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Управляющие элементы  типа  командных  кнопок (которые
иногда называют "нажимаемыми" кнопками) выполняют некоторое
действие   при  "нажатии"  такой  кнопки.  Есть  два  стиля
командных кнопок,  и оба они имеют  тип  TButton.  Эти  два
стиля  -  bs_PushButton  и  DefPushButton.  Используемые по
умолчанию  командные  кнопки  аналогичны  командным  другим
кнопкам,  но  имеют  жирную рамку и обычно используются для
указания реакции пользователя по умолчанию.  На  Рис.  12.3
показан  пример  программы Windows,  в которой используются
обычные кнопки нажатия и командные кнопки по умолчанию.

              ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДї
              і±=±ЫЫЫЫЫЫЫЫЫHex CalculatorЫЫЫЫЫЫЫіvі
              ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДґ
              і        ЪДДДДДДДДДДДДДДДДДї        і
              і        і        0        і        і
              і        АДДДДДДДДДДДДДДДДДЩ        і
              і                                   і
              і ЪДДДї  ЪДДДї ЪДДДї  ЪДДДї  ЪДДДї  і
              і ііDіі  і E і і F і  і + і  і & і  і
              і АДДДЩ  АДДДЩ АДДДЩ  АДДДЩ  АДДДЩ  і
              і ЪДДДї  ЪДДДї ЪДДДї  ЪДДДї  ЪДДДї  і
              і і A і  і B і і C і  і - і  і і і  і
              і АДДДЩ  АДДДЩ АДДДЩ  АДДДЩ  АДДДЩ  і
              і ЪДДДї  ЪДДДї ЪДДДї  ЪДДДї  ЪДДДї  і
              і і 7 і  і 8 і і 9 і  і * і  і ^ і  і
              і АДДДЩ  АДДДЩ АДДДЩ  АДДДЩ  АДДДЩ  і
              і ЪДДДї  ЪДДДї ЪДДДї  ЪДДДї  ЪДДДї  і
              і і 4 і  і 5 і і 6 і  і / і  і < і  і
              і АДДДЩ  АДДДЩ АДДДЩ  АДДДЩ  АДДДЩ  і
              і ЪДДДї  ЪДДДї ЪДДДї  ЪДДДї  ЪДДДї  і
              і і 1 і  і 2 і і 3 і  і % і  і > і  і
              і АДДДЩ  АДДДЩ АДДДЩ  АДДДЩ  АДДДЩ  і
              і ЪДДДї  ЪДДДДДДДДДї  ЪДДДДДДДДДДї  і
              і і 0 і  і   Back  і  і  Equals  і  і
              і АДДДЩ  АДДДДДДДДДЩ  АДДДДДДДДДДЩ  і
              АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

Рис. 12.3 Программа Windows, использующая командные кнопки.




                    Построение командных кнопок
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Кроме обычных  6 параметров,  конструктор Init объекта
TButton воспринимает текстовую строку типа PChar,  AText  и
флаг типа Boolean IsDefaultButton,  указывающий,  должна ли
кнопка быть используемой по умолчанию или обычной командной
кнопкой.   Конструктор  Init  объекта  TButton  описывается
следующим образом:

constructor TButton.Init(AParent: PWindowsObject;
                   AnID: Integer; AText: PChar;
                  X, Y, W, H: Integer; IsDefault: Boolean);

Типичный конструктор для обычной кнопки выглядит так:

Push1 := New(PButton, Init(@Self, id_Push1, 'Test Button',
             38, 48, 316, 24, False));


               Реакция на командные кнопки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Когда пользователь   щелкает   на   командной   кнопке
"мышью",  порождающее окно  кнопки  принимает  уведомляющее
сообщение.  Если  объект  порождающего  окна  перехватывает
сообщение,  он может отреагировать на эти  события  выводом
блока  диалога,  записью  файла  или  другим контролируемым
программой действием.

     Для организации  реакции  на  сообщения  кнопок  нужно
определить основанный на дочернем идентификаторе метод  для
обработки каждой кнопки.  Например,  следующий метод IDBut1
обрабатывает реакцию  на  "нажатие"  пользователем  кнопки.
Единственный  код  уведомления,  определенный в Windows для
командных кнопок - это bn_Clicked,  поэтому код уведомления
не нужно проверять.

     type
       TTestWindow = object(TWindow)
              But1: PButton;
               procedure IDBut1(var Msg: TMessage);
                  virtual id_First + idBut1;
                .
                .
                .
        end;

     procedure TestWindow.IDBut1(var Msg: TMessage);
     begin
 MessageBox(HWindow, 'Clicked', 'The Button was:' mb_OK)
     end;

           Примечание: Пример    использования    командных
      кнопок   показывает  программа  BtnTest,  которую  вы
      можете найти на дистрибутивных дисках.


                    Использование блоков выбора
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

Тип TCheckBox наследует от TButton, а тип TRadioButton - от
TCheckBox.  Кнопки  с  зависимой и независимой фиксацией мы
будем иногда кратко называть блоками выбора.

     Кнопки с независимой фиксацией обычно используются для
предоставления пользователю выбора одного из двух возможных
вариантов.  Пользователь может установить или не установить
управляющий   элемент,   или   оставить  его  так,  как  он
установлен.  Если  имеется  группа  кнопок  с   независимой
фиксацией,  то  может  устанавливаться  не  одна кнопка,  а
несколько.  Например,  вы  можете  использовать  кнопку   с
независимой  фиксацией  для  выбора  трех  шрифтов  для  их
загрузки в приложение.

     Кнопки с зависимой фиксацией используются  для  выбора
одного из нескольких взаимоисключающих вариантов. Например,
кнопка  с  зависимой  фиксацией  может  использоваться  для
выбора  шрифта для конкретного символа.  Когда пользователь
щелкает  "мышью"  на  кнопке  с  зависимой  фиксацией,  это
событие  приводит  к  генерации сообщения Windows.  Как и в
случае  других  управляющих  элементов,  порождающее   окно
кнопки  с  независимой  фиксацией  обычно перехватывает эти
сообщения и выполняет по ним действия.

     Однако, вы  можете  для   выполнения   ими   некоторых
действий при нажатии создать типы, производные от TCheckBox
и TRadioButton.  Если ваш тип определяет метод для nf_First
+  bn_Clicked,  то он сначала должен вызывать метод реакции
BNClicked,  а  уже  затем  выполнять  любые  дополнительные
действия.


Построение кнопок с зависимой и независимой фиксацией
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Кроме обычных   6  параметров,  конструктор  Init  для
кнопок с зависимой  и  независимой  фиксацией  воспринимает
текстовую  строку  и  указатель  на объект группового блока
(см.  "Групповые блоки"),  который  логически  и  визуально
выделяет   кнопки.   AGroup   -  это  указатель  на  объект
группового блока.  Если AGroup имеет значение nil,  то блок
выбора  не  является  частью  какой-либо логической группы.
Конструкторы описываются следующим образом:

constructor Init(AParent: PWindowsObject; AnID: Integer;
                 ATitle: PChar; X, Y, W, H: Integer;
                 AGroup: PGroupBox);

     Для обоих видов  блоков  выбора  синтаксис  идентичен.
Конструкторы   различаются   только  присваиваемым  стилем,
используемым   по   умолчанию.    Типичное    использование
конструкторов блока выбора имеет вид:

GroupBox1 := New(PGroupBox, Init(@Self, id_GB1,
                 'A Group Box', 38, 102, 176, 108));
ChBox1 := New(PCheckBox, Init(@Self, id_Check1,
          'Check Box Text', 235, 12, 150, 26, GroupBox1));

     Кнопки с   независимой    фиксацией    по    умолчанию
инициализируются  со  стилем  bs_AutoCheckBox,  а  кнопки с
независимой фиксацией  имеют  стиль  bs_AutoRadioButton.  В
соответствии  с этими стилями в каждый момент времени может
выбираться только одна клавиша выбора в группе.  Если  одна
выбрана, то другие автоматически остаются невыбранными.

     Если вы   переопределяете   стили  объектов  кнопок  с
зависимой или независимой фиксацией как "неавтоматические",
то  тогда уже вы отвечаете за их выбор или не выбор в ответ
на произведенные пользователем нажатия.


                     Модификация блоков выбора
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Модификация (выбор или отмена  выбора)  блоков  выбора
выглядит задачей пользователя программы,  а не вашей.  Но в
некоторых  случаях  программе  требуется   явно   управлять
состоянием  блоков выбора.  Одним из таких случаев является
вывод на экран параметров, которые были выбраны и сохранены
ранее.  Для  модификации  состояния  кнопки  с  независимой
фиксацией TCheckBox определяет 4 метода:

Методымодификациикнопок снезависимой фиксацией Таблица12.5
ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Выполняемое действиеі       Вызов метода                і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іВыбор кнопки         і Check или SetCheck(bf_Chacked)    і
іОтмена выбора кнопки і Uncheck или SetCheck(bf_Unchecked)і
іПереключение кнопки  і Toggle                            і
АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Когда вы   используете  данные  методы  с  кнопками  с
зависимой фиксацией,  ObjectWindows  обеспечивает  выбор  в
группе только одной кнопки с зависимой фиксацией.


                        Опрос блоков выбора
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Опрос блока  выбора  -  это один из способов выяснения
его состояния и  организации  реакции  на  него.  Кнопки  с
зависимой  и  независимой  фиксацией  имеют  два состояния:
выбранные и  невыбранные.  Для  получения  состояния  блока
выбора используется метод GetCheck типа TheckBox:

     MyState:=Check1^.GetCheck;

     Для определения  состояния блока возвращаемое GetCheck
значение   можно   сравнить   с    заданными    константами
bf_Unchecked, bf_Checked и bf_Grayed.

           Примечание: Использование   кнопок  обоих  видов
      показано  в  примере  программы  BtnTest   на   ваших
      дистрибутивных дисках.


                   Использование групповых блоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В своей  простейшей  форме  блок  группы  представляет
собой статический прямоугольник с  меткой,  который  обычно
объединяет другие управляющие элементы.


                    Построение групповых блоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Конструктор Init  группового  блока  кроме  обычных  6
параметров воспринимает текстовую строку метки группы.

constructor TGroupBoxInit(AParent: PWindowsObject;
                 AnID: Integer;
                 AText: PChar; X, Y, W, H: Integer);

     Типичное использование конструктора  группового  блока
может быть следующим:

GroupBox1:=New(PGroupBox, Init(@Self, id_GB1,'A Group Box'
                 38, 102, 176, 108));


           Группирование управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Поскольку блок  группы  визуально   связывает   группу
других управляющих элементов,  он может логически связывать
группу блоков выбора  (кнопок  с  зависимой  и  независимой
фиксацией).  Логическая группа автоматически отменяет выбор
характеристик блоков выбора "автоматического" стиля.

     Для добавления в  группу,  нужно  при  конструировании
блока  выбора  указать указатель на блок группы.  Например,
чтобы  добавить  в  окно  группу   кнопок   с   независимой
фиксацией,   в  оконный  объект  и  его  конструктор  можно
включить следующее:

     type
       TSomeWindow = object(TWindow)
          Group: PGroupBox;
          FirstCheck, SecondCheck: PCheckBox:
          constructor Init(AParent: PWindowsObject,
                           ATitle: PChar);
     end;

constructor TSomeWindow.Init(AParent: PWindowsObject;
                             ATitle: PChar);
begin
  inherited Init(AParent, ATitle);
  Group := New(PCheckBox, Init(@Self, id_TheGroup,
               'Various boxes', 10, 01, 100, 50));
FirstCheck := New(PCheckBox, Init(@Self, id_FirstCheck,
                    'One', 15, 20, 90, 10, Group));
SecondCheck := New(PCheckBox, Init(@Self, id_SecondCheck,
                     'Two', 15, 20, 90, 10, Group));
end;

     Заметим, что передаваемый блоку выбора параметр группы
- это указатель на объект блока группы,  а не идентификатор
группового  управляющего  элемента  (как  в  API  Windows).
Использование указателя позволяет вам строить объекты перед
созданием методом SetupWindows порождающего  окна  экранных
элементов.


                     Реакция на групповые блоки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда происходит событие, которое может изменить выбор
блока группы (например,  "нажатие" пользователем кнопки или
вызов  программой  метода  Check),  порождающее  окно блока
группы  принимает   сообщение,   основанное   на   дочернем
идентификаторе.  Порождающий объект воспринимает сообщение,
используя сумму id_First и идентификатора группового блока.
Это  позволяет  вам  определить  методы  для  каждой группы
вместо их задания для каждого блока выбора в группе.

     Для определения управляющего  элемента  в  группе,  на
который  было  оказано  воздействие,  вы  можете  прочитать
текущее состояние каждого управляющего элемента.


                     Пример программы: BtnTest
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     BtnTest - это полная программа, которая создает окно с
командной  кнопкой,  кнопками  с  зависимой  и  независимой
фиксацией и  блоком  группы  управляющих  элементов.  После
запуска  приложения появляется основное окно с управляющими
элементами.  Когда пользователь "нажимает"  на  управляющий
элемент,  приложение реагирует на это различными способами.
См. Рис. 12.4.

           Примечание: Полный текст программы содержится  в
      файле BTNTEST.PAS на ваших дистрибутивных дискетах.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫButton TesterЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і                                                         і
і         ЪДДДї                                           і
і         і X і Текст кнопки с независимой фиксацией      і
і         АДДДЩ                                           і
і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї  і
і і±±±±±±±±±±±Состояние кнопки с независимой фиксацией±і  і
і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ  і
і                                                         і
і             ЪДГрупповой блокДДДДДДДДДДДДДДДДДДДДДДДДДї  і
і             і ( ) Кнопка с зависимой фиксацией 1     і  і
і             і (*) Кнопка с зависимой фиксацией 2     і  і
і             АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ  і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 12.4 Окно с различными видами кнопок.


                   Использование полос прокрутки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Полосы прокрутки   являются    важнейшим    механизмом
изменения   обзора  пользователем  окна  приложения,  блока
списка или комбинированного блока. Однако, может возникнуть
ситуация,   когда  нужна  отдельная  полоса  прокрутки  для
выполнения некоторой специализированной  задачи  (например,
управление температурой в программе термостата или цветом в
программе     рисования).     Когда     нужна     отдельная
специализированная  полоса прокрутки,  используются объекты
TScrollBar.  Рис.  12.5 показывает  типичное  использование
объекта TSсrollBar.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫThermostatЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і                                                     і
і                     68 градусов                     і
і                                                     і
і                                                     і
і                                                     і
і ЪДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДї  і
і і<Ыі±±±±±±±±±±±±±±±±±Ы±±±±±±±±±±±±±±±±±±±±±±±±іЫ>і  і
і АДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДЩ  і
і                                                     і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 12.5 Объект полосы прокрутки.


                     Построение полос прокрутки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Кроме обычных   6   параметров  управляющего  объекта,
конструктор Init полосы прокрутки  воспринимает  флаг  типа
Boolean,   указывающий,   является   ли   полоса  прокрутки
горизонтальной.  Приведем  описание   конструктора   полосы
прокрутки:

     constructor TScrollBarInit(AParent: PWindowsObject;
                   AnID: Integer; X, Y, W, H: Integer;
                              IsHScrollBar: Boolean);

     Если вы  зададите  нулевую  ширину вертикальной полосы
прокрутки,   Windows   присвоит   ей   стандартную   ширину
(аналогичную  полосе  прокрутки блока списка).  То же самое
касается  задания  нулевой  высоты  горизонтальной   полосы
прокрутки. Вызов:

ThermScroll := New(PScrollBar, Init(@Self, id_ThermScroll,
                        20, 170, 340, 0, True));

создает горизонтальную полосу прокрутки стандартной высоты,
как  это  показано на Рис.  12.5.  Init конструирует полосы
прокрутки со стилями ws_Child,  ws_Visible и  sbs_Horz  или
sbs_Vert   для   горизонтальной   или  вертикальной  полосы
прокрутки соответственно.  Разнообразные  полосы  прокрутки
показаны на Рис. 12.6.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫScroll Bar TesterЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і          ЪДДї                               ЪДї         і
і    ЪДДВДДі/\іДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДїі^і         і
і    і/Ыі±±ГДДґ±±±±±±±±±±±Ы±±±±±±±±±±±±±±±іЫ\іГДґ         і
і    і\Ыі±±і±±і±±±±±±±±±±±Ы±±±±±±±±±±±±±±±іЫ/іі±і         і
і    АДДБДДіЫЫіДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДЩіЫі         і
і          і±±і                               і±і         і
і          і±±і                               і±і         і
і          і±±і                               ГДґ         і
і          ГДДґ                               іvі         і
і          і\/і                               АДЩ         і
і          АДДЩ                                           і
і ЪДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДї  і
і і<Ыі±±±±±±±±±±±±±±±±±Ы±±±±±±±±±±±±±±±±±±±±±±±±±±±±іЫ>і  і
і АДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДЩ  і
і                                                         і
і                                                         і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 12.6 Окно с разнообразными полосами прокрутки.


               Управление диапазоном полосы прокрутки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Один из атрибутов полосы  прокрутки,  инициализируемый
при  ее  конструировании,  это  диапазон.  Диапазон  полосы
прокрутки -  это  набор  всевозможных  положений  указателя
(маркера  полосы прокрутки).  Маркер полосы прокрутки - это
подвижный   прямоугольник,   который   пользователь   может
перемещать  по  ней.  Каждой  позиции  соответствует  целое
число.  Порождающее окно  использует  эту  целую  величину,
позицию, для установки и запроса по полосе прокрутки. После
конструирования  объекта  полосы  прокрутки  его   диапазон
устанавливается от 1 до 100.

     Положению маркера  в  "самой верхней" позиции (вершина
вертикальной полосы прокрутки или крайнее  левое  положение
горизонтальной  полосы  прокрутки) соответствует позиция 1.
"Самой нижней" позиции маркера соответствует  позиция  100.
Для  установки  иного  диапазона  нужно  использовать метод
SetRange,   описанный   в   разделе   "Модификация   полосы
прокрутки".


              Управление параметрами полосы прокрутки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Два других атрибута объекта полосы прокрутки - это его
приращение по строкам и страницам.  Приращение по  строкам,
установленное в 1,  это расстояние в единицах диапазона, на
которое переместится указатель  при  нажатии  пользователем
стрелок  на  полосе  прокрутки.  Приращение  по  страницам,
установленное в 10, это расстояние в единицах диапазона, на
которое  переместится указатель при нажатии пользователем в
области   прокрутки.   Эти    значения    можно    изменить
непосредственной  модификацией  полей  объекта  TScrollBar,
LineSize и PageSize.


                       Опрос полосы прокрутки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TScrollBar определяет   два   метода   опроса   полосы
прокрутки:  GetRange и GetPosition.  Метод GetRange  -  это
процедура,   использующая   два   целочисленных  переменных
аргумента. Процедура заносит в эти целые значения верхнюю и
нижнюю  позиции  из диапазона полосы прокрутки.  Этот метод
очень удобен, когда нужно, чтобы ваша программа переместила
указатель в его верхнюю или нижнюю позицию.

     GetPosition -  это функция,  которая возвращает в виде
целой величины  позицию  указателя.  Ваша  программа  очень
часто будет запрашивать диапазон и позицию и сравнивать их.


                    Модификация полос прокрутки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Модификация полос  прокрутки  -  это скорее работа для
пользователя вашей программы,  и  часто  это  действительно
так.  Однако,  ваша  программа  также  может модифицировать
полосу прокрутки. Используемые для этого методы перечислены
в следующей таблице.

Методы модификации полос прокрутки    Таблица 12.6
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДї
і   Выполняемое действие    і    Вызываемый метод    і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
іЗадание диапазона прокруткиі   SetRange             і
іУстановка позиции маркера  і   SetPosition          і
іПеремещение позиции маркераі   DeltaPos             і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДЩ

     SetRange - это  процедура,  которая  воспринимает  два
целочисленных  аргумента,  наименьшую  и наибольшую позицию
диапазона.  По  умолчанию  новая  полоса  прокрутки   имеет
диапазон от 1 до 100.  Вы можете изменить этот диапазон для
наилучшего   расположения   управляющих   элементов   полос
прокрутки.  Например,  полоса  прокрутки  в  приложении для
термостата может иметь  диапазон  от  32  до  120  градусов
Фаренгейта:

     ThermScroll^.SetRange(32, 120);


     SetPosition - это процедура, которая воспринимает один
целочисленый   аргумент   -   позицию,   в   которую  нужно
переместить указатель  полосы  прокрутки.  В  рассмотренном
ранее  приложении  для  термостата,  ваша  программа  может
непосредственно установить температуру 78 градусов:

     ThermScroll^.SetPosition(78);

     Третий метод DeltaPos  передвигает  позицию  указателя
полосы  прокрутки  вверх  (налево)  или  вниз  (направо) на
величину,  заданную целым аргументом.  Положительная  целая
величина перемещает указатель вниз (направо). Отрицательная
целая величина перемещает его вверх (налево). Например, для
уменьшения    температуры    термостата   на   5   градусов
используется:

     ThermScroll^.DeltaPos(-5);



                    Реакция на полосы прокрутки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     При работе   пользователя   с   полосой  прокрутки  ее
порождающее окно получает  от  нее  уведомляющие  сообщения
Windows.   Если  нужно,  чтобы  ваше  окно  реагировало  на
сообщения прокрутки,  реакция на  информационные  сообщения
должна  быть  обычной,  путем  определения методов реакции,
основанных на дочерних идентификаторах.

     Однако, уведомляющие   сообщения   полосы    прокрутки
несколько   отличаются  от  других  уведомляющих  сообщений
элемента управления.  Они основаны  на  сообщениях  Windows
wm_HScroll  и  wm_VScroll,  а  не wm_Command.  Единственное
отличие,  на которое нужно обратить внимание состоит в том,
что   уведомляющие   коды   полосы   прокрутки  записаны  в
Msg.wParam, а не в Msg.lParamHi.

     Чаще всего встречаются  коды  sb_LineUp,  sb_LineDown,
sb_PageUp,  sb_PageDown,  sb_ThumbPosition и sb_ThumbTrack.
Наиболее часто вы  будете  реагировать  на  каждое  событие
проверкой  новой  позиции  полосы  прокрутки и организацией
соответствующего  действия.  В  данном  случае  вы   можете
игнорировать уведомляющий код. Например:

     procedure TestWindow.HandleThermScrollMsg(var Msg:
                                               TMessage);
     var
        NewPos: Integer;
     begin
        NewPos:=ThermScroll^.GetPosition;
        { обработка с помощью NewPos }
     end;

     Часто альтернатива состоит в том, чтобы не реагировать
на  перемещение указателя до тех пор,  пока пользователь не
выберет его нового  местоположения.  В  этом  случае  нужно
реагировать на сообщение с кодом sb_ThumbTrack.

     procedure TestWindow.HandleThermScrollMsg(var Msg:
                                               TMessage);
     var
       NewPos: Integer;
     begin
       if Msg.wParam <> sb_ThumbTrack
        then begin
              NewPos:=ThermScroll^.GetPosition;
              { некоторая обработка на основе NewPos. }
             end;
     end;

     Иногда может   потребоваться,   чтобы  объекты  полосы
прокрутки сами реагировали на уведомляющие сообщения полосы
прокрутки.  При  этом  конкретная  реакция поведения должна
быть   встроена   в   объект    полосы    прокрутки.    Для
программирования    объекта   полосы   прокрутки,   который
непосредственно  реагировал  бы   на   его   информационные
сообщения,  нужно  определить  для  его типа метод реакции,
основанный  на  информации.   В   качестве   идентификатора
заголовка   метода  нужно  использовать  сумму  nf_First  и
информационного кода полосы прокрутки.  Этот процесс описан
в  разделе  "Уведомляющие  сообщения управляющих элементов"
Главы 16.


                     Пример программы: SBarTest
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Программа SBarTest создает приложение для  термостата,
показанное на Рис.  12.5. Полный текст программы содержится
в файле SBARTEST.PAS на ваших дистрибутивных дискетах.


         Использование управляющих элементов редактирования
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Управляющие элементы   редактирования    могут    быть
описаны,    как   интерактивные   статические   управляющие
элементы.  Это прямоугольные области (с рамкой или без)  на
экране,  которые  пользователь  приложения  может заполнять
текстом,  изменять   или   удалять.   Управляющий   элемент
редактирования  наиболее  удобен  в качестве поля для ввода
данных на экране. Они обеспечивают следующие операции:

- Ввод текста пользователем.
- Динамическое отображение текста приложением.
- Вырезание, копирование и вставка в буфер вырезанного изоб-
  ражения.
- Многострочное  редактирование (удобно для текстовых редак-
  торов).

На Рис.   12.7  показано  окно  с  двумя  управляющими
элементами редактирования.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±ІІІІІІІІІІІІEdit Control TesterІІІІІІІІІІІІІІІІІІІІі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і                                                        і
і Оригинал:                Копия:                        і
іЪДДДДДДДДДДДДДДДДДї ЪДДДї ЪДДДДДДДДДДДДДДДДДДДДДДї      і
ііDefault Text     і і±>±і іDEFAULT.TEXT          і      і
іАДДДДДДДДДДДДДДДДДЩ АДДДЩ АДДДДДДДДДДДДДДДДДДДДДДЩ      і
і                                                        і
і                                                        і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

   Рис. 12.7 Окно с управляющими элементами редактирования.


        Построение управляющих элементов редактирования
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Конструктор Init управляющего элемента  редактирования
аналогичен  конструктору статического управляющего элемента
и  воспринимает  6  обычных  параметров,   плюс   начальная
текстовая   строка,   максимальная   длина  строки  и  флаг
Multiline  типа  Boolean.  Конструктор  TEdit   описывается
следующим образом:

constructor TEdit.Init(AParent: PWindowsObject;
         AnID: Integer; ATitle: PChar;
      X, Y, W, H, ATextLen: Integer; Multiline: Boolean);

     По умолчанию  управляющий элемент редактирования имеет
стили   ws_Child,   ws_Visible,   es_TabStop,   es_Left   и
es_AutoHScroll. Так как управляющий элемент должен включать
в себя завершающий нулевой символ, параметр длины текста на
самом  деле  на  1  превышает  максимальное число символов,
допустимых в строке редактирования.

     Если Multiline  имеет  значение  True,  то  управление
редактированием  имеет стиль es_MultiLine,  es_AutoVScroll,
ws_VScroll и  ws_HScroll.  Приведем  типичные  конструкторы
управляющих     элементов    редактирования    (один    для
однострочного элемента, другой - для многострочного):

EC1:=New(PEdit, Init(@Self, id_EC1, 'Default Text', 20, 50,
           150, 30, 40, False));
EC2:=New(PEdit, Init(@Self, id_EC2, '', 20, 20, 200, 150,
           40, True));


 Использование буфера вырезанного изображения и меню Edit
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вы можете   передавать   текст  непосредственно  между
объектом управляющего  элемента  редактирования  и  буфером
вырезанного изображения Windows, используя для этого вызовы
методов.  Часто вам бывает нужно предоставить  пользователю
доступ  к  этим  методам через меню редактирования.  Объект
управляющего    элемента    редактирования    автоматически
отреагирует на выбор из меню таких вариантов, как EditіCopy
и EditіUndo. TEdit определяет основанные на командах методы
(например,  CMEditCopy и CMEditUndo),  которые вызываются в
ответ на конкретный выбор (команду) меню в порождающем окне
управляющего  элемента редактирования.  CMEditCopy вызывает
Copy, а CMEditUndo вызывает Undo.


     Следующая таблица  содержит  список  методов,  которые
вызываются в ответ на выбор пункта меню:

Управляющие элементы редактирования и меню EditТаблица12.7
ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДї
і   Операция           і     Метод TEdtі    Команда менюі
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
іКопирование текста в  і  Cut          і cm_EditCut     і
ібуфер вырезанного     і               і                і
іизображения.          і               і                і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
іВырезание текста в    і  Copy         і cm_EditCopy    і
ібуфер вырезанного     і               і                і
іизображения.          і               і                і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
іВставка текста из     і  Paste        і cm_EditPaste   і
ібуфера вырезанного    і               і                і
іизображения.          і               і                і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
іОчистка всего элементаі  Clear        і cm_EditClear   і
іредактирования.       і               і                і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
іУдаление выделенного  і  DeleteSelectionі cm_EditDeleteі
ітекста.               і                 і              і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДґ
іОтмена последнего     і  Undo           і cm_EditUndo  і
іредактирования.       і                 і              і
АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДЩ

    Чтобы добавить в окно меню  редактирования,  содержащее
управляющий  элемент редактирования,  определите для окна с
помощью команд,  перечисленных в Таблице 12.7, ресурс меню.
Никаких новых методов вам писать не нужно.

     Имеется также   один   дополнительный   метод  в  виде
булевской функции CanUndo,  который  определяет,  можно  ли
отменить последнюю операцию редактирования.



             Опрос управляющих элементов редактирования
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Иногда нужно организовать опрос управляющих  элементов
редактирования для проверки допустимости введенного текста,
записи  ввода  для  его  последующего   использования   или
копирования  ввода  в  другой  управляющий  элемент.  TEdit
поддерживает несколько методов опроса.  Многие  из  опросов
управляющих  элементов редактирования и методов модификации
возвращают или требуют от  вас  указать  номер  строки  или
позицию  символа  в  строке.  Все  эти индексы начинаются с
нуля.  Другими словами, первая строка - это нулевая строка,
а  первый символ в любой строке это нулевой символ.  Самыми
важными  методами  запроса   являются   GetText,   GetLine,
NumLines и LineLength.

МетодыопросауправляющихэлементовредактированияТаблица12.8
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДї
іВыполняемое действие                і Вызываемый методі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДґ
іОпределение изменения текста        і IsModified      і
іСчитывание всего текста             і GetText         і
іСчитывание строки                   і GetLine         і
іПолучение числа строк               і GetNumLines     і
іПолучение длины данной строки       і GetLineLength   і
іПолучение индекса выделенного текстаі GetSelection    і
іПолучение диапазона символов        і GetSubText      і
іПодсчет символов перед строкой      і LineIndex       і
іПоиск строки, содержащей индекс     і GetLineFromProc і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДЩ

     Вы можете заметить, что методы запросов TEdit, которые
возвращают  текст  из управляющего элемента редактирования,
сохраняют  форматирование  текста.  Это  важно  только  для
многострочных управляющих элементов редактирования, которые
допускают появление нескольких строк текста.  В этом случае
возвращаемый  текст,  который  занимает  несколько  строк в
управляющем элемента редактирования содержит в конце каждой
строки два дополнительных символа:  возврат каретки (#13) и
смена строки (#10).  Если этот  текст  снова  помещается  в
управляющий  элемент редактирования,  вставляется из буфера
вырезанного изображения,  записывается в файл или выводится
на  принтер,  то  строки  разбиваются  так,  как это было в
управляющем элемента редактирования.

     Следовательно, при использовании  метода  запроса  для
получения определенного числа символов, нужно учитывать эти
два символа, которые заканчивают строку. GetText ищет текст
в управляющем элементе редактирования. Он заполняет строку,
на которую указывает переданный аргумент PChar,  содержимым
управляющего   элемента   редактирования,  включая  перевод
строки. Общее число символов задается вторым параметром. Он
возвращает   значение   False,   если  управляющий  элемент
редактирования  пуст,  или  содержит  текста  больше,   чем
помещается  в  предоставленную строку.  Следующая процедура
считывает из управляющего элемента редактирования строку  и
выделенный текст:

    procedure TTestWindow.ReturnText(RetText: PChar);
    var TheText: array[0..20] of Char;
    begin
     if EC1^.GetText(@TheText, 20) then
      RetText:=@TheText
     else RetText:=nil;
    end;

    procedure TTestWindow.ReturnText(RetText: PChar);
    var TheText: array[0..20] of Char;
    begin
      RetText:=nil;
      with EC^ do
      if NumLines >= LineNum then
         if LineLength(LineNum) < 11 then
             if GetLine(@TheText, 20, LineNum) then
                 RetText := @TheText;
     end;

     procedure TestWindow.ReturnLineText(RetText: PChar;
                                         LineNum: Integer);
     var
       TheText: array[0..20] of Char;
     begin
       with EC1^ do
       begin
         GetSelection(SelStart, SelEnd);
         GetSubText(TheText, SelStart, SelEnd);
       end;
         RetText := TheText;
     end;


          Модификация управляющих элементов редактирования
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для традиционной  программы  ввода текста вам может не
потребоваться  непосредственно  модифицировать  управляющий
элемент редактирования.  Пользователь модифицирует текст, а
программа считывает этот текст методом опроса.  Однако,  во
многих  других  случаях использование управляющего элемента
редактирования  требует,   чтобы   ваше   приложение   явно
заменяло,    вставляло,    удаляло    и   выбирало   текст.
ObjectWindows обеспечивает подобное поведение и кроме  того
предоставляет     возможность     использовать    прокрутку
управляющего элемента редактирования.

                  Методы модификации
 управляющих элементов редактирования   Таблица 12.9
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДї
Выполняемое действие        і Вызываемый метод     і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДґ
Удаление всего текста       і Clear                і
Удаление выделенного текста і DeleteSelection      і
Удаление диапазона символов і DeleteSubText        і
Удаление строки текста      і DeleteLine           і
Вставка текста              і Insert               і
Вставка текста из буфера    і Paste                і
вырезанного изображения     і                      і
Замена всего текста         і SetText              і
Выделение диапазона текста  і SelectRange          і
Прокрутка текста            і Scroll               і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДЩ


                Пример программы: EditTest
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     EditTest -  это  программа,  которая помещает на экран
основное  окно,  которое   будет   порождающим   для   двух
управляющих   элементов  редактирования,  двух  статических
управляющих элементов и кнопки.  Данное  окно  показано  на
Рис. 12.7.

     Когда пользователь щелкает на командной кнопке кнопкой
"мыши",   текст    из    левого    управляющего    элемента
редактирования   (EC1)   копируется  в  правый  управляющий
элемент редактирования (EC2).  В EC2 текст преобразуется  в
буквы  верхнего  регистра,  поскольку оно было построено со
стилем es_UpperCase.  Если в C1 никакой текст не выбран, то
в  EC2  копируется весь текст.  Если в EC1 выбран некоторый
текст,  то будет скопирован именно он.  Меню редактирования
обеспечивает  функции редактирования независимо от того,  с
каким управляющим  элементов  редактирования  идет  работа.
Полный файл EDITTEST.PAS и файл ресурса EDITTEST содержатся
на ваших дистрибутивных дискетах.


                Использование комбинированных блоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Управляющий элемент   типа   комбинированного    блока
является  сочетанием  двух  других  управляющих  элементов:
блока списка и  управляющего  элемента  редактирования.  Он
служит  тем  же  целям,  что  и  блок  списка  -  позволяет
пользователю выбрать один элемент списка из прокручиваемого
списка   элементов   текста,   нажимая  на  кнопку  "мыши".
Управление  редактированием,  вынесенное  в  верхнюю  часть
блока  списка предоставляет иной механизм выбора,  позволяя
пользователю   ввести   текст   нужного   элемента.    Если
отображается  область  списка  комбинированного  блока,  то
автоматически  выбирается  нужный  элемент.  Тип  TComboBox
является  производным  от  типа  TListBox  и  наследует его
методы модификации, опроса и выбора элементов списка. Кроме
того,  TComboBox  предоставляет  методы  по манипулированию
списком,  находящемся в комбинированном  блоке,  который  в
некоторых случаях может раскрываться по запросу.


                  Три типа комбинированных блоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Имеются три   типа  комбинированных  блоков:  простые,
раскрывающиеся и раскрывающиеся со списком.  На  Рис.  12.8
показан  вывод  трех  типов комбинированных блоков с блоком
списка.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫStatic Control TesterЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і                                                         і
і  Блок списка           Простой комбинированный блок     і
і  ЪДДДДДДДДДДї          ЪДДДДДДДДДДДДДДДДДДДДДДДДДДї     і
і  іa         і          і                          і     і
і  іb         і          АВДДДДДДДДДДДДДДДДДДДДДДДДДґ     і
і  іc         і           іa                        і     і
і  іd         і           іb                        і     і
і  іe         і           іc                        і     і
і  іf         і           іd                        і     і
і  АДДДДДДДДДДЩ           АДДДДДДДДДДДДДДДДДДДДДДДДДЩ     і
і                                                         і
і  Раскрывающийся комбинированный Комбинированный блок с  і
і  блок                           раскрывающимся списком  і
і  ЪДДДДДДДДДДДДДДДДДїЪДДДї ЪДДДДДДДДДДДДДДДДДДДДДДВДДДї  і
і  і                 іі v і іc±±±±±±±±±±±±±±±±±±±±±і v і  і
і  АДДДДДДДДДДДДДДДДДЩАДДДЩ АДДДДДДДДДДДДДДДДДДДДДДБДДДЩ  і
і                                                         і
і                                                         і
і                                                         і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

Рис. 12.8 Три типа комбинированных блоков и блок списка.

Перечень стилей комбинированного блока  Таблица 12.10
ДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДД
 Стиль           іВозможность скрытого іСоответствие текста
ДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДД
Простой          і      нет            і      нет
Раскрывающийся   і      есть           і      нет
Раскрывающийся соі      есть           і      да
списком          і                     і
ДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДД

 С точки  зрения  пользователя  между  различными   стилями
комбинированных блоков существуют следующие различия:

     * Простые комбинированные блоки.

       Простой комбинированный блок не может делать область
       списка скрытой.  Его  область  редактирования  ведет
       себя      аналогично      управляющему      элементу
       редактирования.   Пользователь   может   вводить   и
       редактировать текст,  и текст не обязан совпадать ни
       с  одним  из  элементов  в  списке.  При  совпадении
       выбирается соответствующий элемент списка.

     * Раскрывающиеся комбинированные блоки.

       Раскрывающиеся комбинированные   блоки   ведут  себя
       аналогично  простым  комбинированным  блокам,  но  с
       одним  исключением.  В  начальной  стадии  работы их
       область  списка  не  отображается.  Она  появляется,
       когда    пользователь    нажимает    стрелку   вниз,
       расположенную  справа  от  области   редактирования.
       Раскрывающиеся      комбинированные      блоки     и
       раскрывающиеся комбинированные блоки  списков  очень
       удобны,   когда   нужно   поместить   большое  число
       управляющих элементов в маленькую область. Когда они
       не  используются,  то  занимают  значительно меньшую
       площадь,  чем простой комбинированный блок или  блок
       списка.

     * Раскрывающиеся комбинированные блоки списка.

       Область списка   в   раскрывающемся  комбинированном
       блоке списка ведет себя  подобно  области  списка  в
       спускающемся  комбинированном блоке - появляется при
       необходимости и исчезает,  когда не нужна.  Эти  два
       типа комбинированных блоков отличаются поведением их
       областей  редактирования.   Раскрывающиеся   области
       редактирования    ведут    себя    подобно   обычным
       управляющим элементам редактирования. Раскрывающиеся
       области  редактирования списка ограничиваются только
       отображением   одного    элемента    списка.    Если
       редактируемый  текст  соответcтвует элементу списка,
       то никаких дополнительных символов ввести нельзя.


                 Выбор типа комбинированного блока
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Раскрывающиеся комбинированные  блоки  списка   удобно
использовать  тогда,  когда  не  допускаются никакие другие
варианты,  кроме перечисленных в области списка.  Например,
при   выборе  принтера  для  печати  можно  выбрать  только
принтер, к которому есть доступ в вашей системе.

     С другой стороны, раскрывающиеся комбинированные блоки
могут воспринимать выбор, который отличается от приведенных
в списке  элементов.  Раскрывающийся  комбинированный  блок
можно  использовать  для  выбора  файлов  на  диске  при их
открытии или записи.  Пользователь может либо просматривать
каталоги  в  поисках  нужного  файла,  либо  ввести  полный
маршрут и имя файла в области редактирования, независимо от
того, присутствует ли это имя файла в области списка.


                 Построение комбинированных блоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Кроме обычных   6   параметров   объектов  управляющих
элементов конструктор Init  для  TComboBox  воспринимает  в
качестве  аргументов  стиль  и  максимальную  длину текста.
Конструктор TComboBox описывается следующим образом:

     constructor TComboBox.Init(AParent: PWindowsObject;
                     AnID: Integer: X, Y, W, H: Integer;
                              AStyle, ATextLen: Word);

      Все комбинированные   блоки,  построенные  с  помощью
Init,  имеют стили ws_Child,  ws_Visible,  cbs_AutoHScroll,
cbs_Sort (отсортированный список),  и VScroll (вертикальная
полоса прокрутки). Параметр стиля - это один из стандартных
стилей    комбинированных   блоков   Windows:   cbs_Simple,
cbs_DropDown или cbs_DropDownList.  Параметр  длины  текста
работает  подобно  соответствующему  параметру управляющего
элемента  редактирования,   ограничивая   число   символов,
которые    можно    ввести    в    область   редактирования
комбинированного блока.

     Следующие строки  приведут  к  созданию  спускающегося
комбинированного блока списка с неотсортированным списком:

     CB3: = New(PComboBox, Init(@Self, id_CB3, 190, 160,
                150, 100, cbs_DropDownList, 40));
     CB3^.Attr.Style:=CB3^.Attr.Style and (not cbs_Sort);


                 Модификация комбинированных блоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TComboBox определяет  два  метода  для  демонстрации и
сокрытия области списка  в  раскрывающихся  комбинированных
блоках  и  раскрывающихся  комбинированных  блоках  списка:
ShowList и HideList.  Обе  эти  процедуры  не  нуждаются  в
аргументах.   Вызывать  эти  методы  для  демонстрации  или
сокрытия списка,  когда пользователь нажимает стрелку  вниз
справа от области редактирования,  не нужно.  В этом случае
работает автоматический  механизм  комбинированных  блоков.
Эти  методы  полезны  только для принудительного вывода или
сокрытия списка.


                     Пример программы: CBoxTest
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Программа CBoxTest реализует приложение, показанное на
Рис.  12.8. В нем использованы все три типа комбинированных
блоков.  CB1 - это простой комбинированный  блок,  CB2  это
раскрывающийся   комбинированный   блок,   а   CB3   -  это
раскрывающийся комбинированный блок списка.  Нажатие кнопок
Show  и  Hide  выполняет  принудительный  вывод  и сокрытие
правого верхнего комбинированного блока,  CB3, путем вызова
методов ShowList и HideList.

          Примечание: Полный   текст   файла   CBOXTEST.PAS
      содержится на ваших дистрибутивных дискетах.

              Установка значений управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для управления  сложными  блоками диалога или окнами с
множеством дочерних окон управляющих  элементов  вы  обычно
можете  для  хранения и выяснения состояния его управляющих
элементов  создать  производный  тип   объекта.   Состояние
управляющего  элемента  включает  в себя текст управляющего
элемента  редактирования,  положение  полосы  прокрутки   и
установку кнопки с зависимой фиксацией.


               Для чего используется буфер передачи?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     В качестве  альтернативы  вы  можете   не   определять
производный  объект,  а  определить соответствующую запись,
представляющую состояние  управляющих  элементов  окна  или
диалога.  Эта запись называется буфером передачи, поскольку
легко передает  информацию  о  состоянии  между  буфером  и
набором управляющих элементов.

     Например, ваша  программа  может  иметь  режимный блок
диалога и после его закрытия, выделить информацию из буфера
передачи  относительно состояния каждого из его управляющих
элементов.    Следовательно,    при    повторном     вызове
пользователем блока диалога, его управляющие элементы будут
выведены в соответствии с  их  состоянием  перед  последним
закрытием   диалога.   Кроме  того,  вы  можете  установить
начальное состояние каждого из управляющих элементов  и  на
основании данных буфера передачи. Вы можете явно передавать
данные  в  любом  направлении  в  любой   момент   времени,
например,   установить   значения   управлений  равными  их
предыдущим значениям.  Окно или безрежимный блок диалога  с
управляющими  элементами  также могут использовать механизм
передачи для установки или выяснения информации о состоянии
в любой момент времени.

     Механизм передачи     требует     для    представления
управляющих элементов,  для которых  вы  будете  передавать
данные, использования объектов ObjectWindows. Это означает,
что вы  должны  использовать  InitResource  для  связывания
объектов   с  управляющими  элементами  в  блоках  и  окнах
диалога.

           Примечания: Связь   управляющих   элементов    с
      управляющими   объектами   описывается   в  Главе  11
      "Объекты диалоговых блоков".

     Чтобы использовать  механизм   передачи,   вы   можете
сделать следующее:

     * Определить буфер передачи.
     * Определить соответствующее окно.
     * Передать данные.


                    Определение буфера передачи
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Буфер передачи  - это запись с одним полем для каждого
управляющего элемента,  участвующего в передаче.  Окно  или
диалог  могут  также  иметь управляющие элементы,  значения
которых не устанавливаются механизмом  передачи.  Например,
командные кнопки,  у которых нет состояния,  не участвуют в
передаче. Это же справедливо для групповых блоков.

     Для определения буфера передачи нужно определить  поле
для  каждого участвующего управляющего элемента диалога или
окна.  Определять поля для каждого управления  диалога  или
окна  не  требуется - нужно лишь определить поля для тех из
них,  которые будут получать и принимать значения по вашему
желанию.  Этот  буфер  передачи хранит один из каждых типов
управляющих  элементов,  кроме  командной  кнопки  и  блока
группы:

type
TSampleTransferRecord = record
  Stat1: array[0..TextLen-1] of Char; { статический текст }
  Edit1: array[0..TextLen-1] of Char; { текст управляющего
                                   элемента редактирования}
  List1Strings: PStrCollection;      { строки блока списка}
  List1Selection: Integer; { индекс выбранных строк }
  ComboStrings: PStrCollection; { строки комбинированного
                                   блока }
  ComboSelection: array[0..TextLen-1] of Char; { выбранные
                                   строки }
  Check1: Word;                 { проверка состояния блока}
  Radio1: Word; { состояние кнопки с независимой фиксацией}
  Scroll1: ScrollBarTransferRec;  {  диапазон полосы
                                  прокрутки и т.д. }
end;


     В каждом типе управляющего элемента хранится различная
информация.  Буфер  передачи   для   каждого   стандартного
управляющего элемента поясняется в следующей таблице:

                     Поля буфера передачи
для каждого типа управляющего элемента  Таблица 12.11
ЪДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іТип управляющегоі            Буфер передачи             і
і   элемента     і                                       і
ГДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іСтатический     і Символьный массив  размером до  макси-і
і                і мальной длины текста, плюс завершающийі
і                і нулевой символ.                       і
і                і                                       і
ГДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іРедактирование  і Текстовый буфер управляющего  элементаі
і                і редактирования размером до  длины, оп-і
і                і ределенной в текстовом поле TextLen.  і
і                і                                       і
ГДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іБлок списка     і                                       і
і одиночный выборі Набор строк в списке, плюс целочислен-і
і                і ный индекс выделенной строки.         і
і                і                                       і
імножественный выборіНабор строк в списке,плюс запись,со-і
і                і держащая индексы всех выделенных  эле-і
і                і ментов.                               і
і                і                                       і
ГДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іКомбинированный блокНабор строк в списке,плюс  выбраннаяі
і                і строка.                               і
і                і                                       і
ГДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іКнопка с независимойЗначенияWordс указывающими состоянияі
іфиксацией       і bf_Unchecked, bf_Checked и bf_Grayed. і
і                і                                       і
ГДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іКнопка с зависимойіЗначения Word суказывающими состоянияі
іфиксацией       і bf_Unchecked, bf_Checked и bf_Grayed. і
і                і                                       і
ГДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іПолоса прокруткиі Запись типа TScrollBarTransferRec, со-і
і                і храняющая диапазон полосы прокрутки  иі
і                і позицию в ней.                        і
і                і                                       і
АДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

   Тип TScrollBarTransferRec имеет вид:

   TScrollBarTransferRec := record
    LowValue : Integer;
    HighValue: Integer;
    Position : Integer;
   end;


                        Определение окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Окно или диалоговый  блок,  которые  используют  буфер
передачи,  должны создавать объекты участвующих управляющих
элементов в той последовательности,  в которой определяются
их  соответствующие  поля буфера передачи.  Для подключения
механизма передачи к объекту окна или диалога нужно  просто
установить  значение его поля TransferBuffer в указатель на
определенный вами буфер передачи.


         Использование буфера передачи с диалоговым блоком
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для случая  окон  с  управляющими  элементами  объекты
управляющих элементов конструируются с использованием Init.
Для диалогов и окон диалогов нужно использовать конструктор
InitResource. Например (используется определенный ранее тип
TSampleRecord):

     type
      TSampleTransferRecord = record
        .
        .
        .
      PParentWindow = ^TParentWindow;
      TParentWindow = object(TWindow)
       TheDialog: PDialog;
       TheBuffer: SampleTransferRecord;
        .
        .
        .
        .
constructor TParentWindow.Init(AParent: PWindowsObject;
                               ATitle: PChar);
var
 Stat1: PStatic;
 Edit1: PEdit;
 List1: PListBox;
 Combo1: PComboBox;
 Check1: PCheckBox;
 Radio1: PRadioButton;
 Scroll1: PScrollBar;
begin
 TWindow.Init(AParent, ATitle);
 TheDialog^.Init(@Self, PChar(101));
 New(Stat1, InitResource(TheDialog, id_Stat1));
 New(Edit1, InitResource(TheDialog, id_Edit1));
 New(List1, InitResource(TheDialog, id_List1));
 New(Combo1, InitResource(TheDialog, id_Combo1));
 New(Check1, InitResource(TheDialog, id_Check1));
 New(Radio1, InitResource(TheDialog, id_Radio1));
 New(Scroll1, InitResource(TheDialog, id_Scroll1));
 TheDialog^.TranssferBuffer:=@TheBuffer;
end;

Для управляющих   элементов,    построенных    с    помощью
InitResource, механизм передачи разрешается автоматически.



               Использование буфера передачи с окном
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для случая окна с управляющими элементами  используйте
для   конструирования   объектов  управления  в  надлежащей
последовательности Init,  а не InitResource. Другое отличие
между  диалогами  и  окнами  состоит  в  том,  что механизм
передачи  по  умолчанию  для  управляющих  элементов   окна
запрещен. Для разрешения использования механизма вызывается
EnableTransfer:

constructor TSampleWindow.Init(AParent: PWindowsObject;
                               ATitle: PChar);
begin
  inherited Init(AParent, ATitle);
  Edit1 := New(PEdit, Init(@Self, id_Edit1, '', 10, 10,
               100, 30, 40, False));
  Edit1^.EnableTransfer;
end;

Чтобы явно   исключить  управляющий  элемент  из  механизма
передачи,    вызовите    после    его    создания     метод
DisableTransfer.

                          Передача данных
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В большинстве   случаев   передача   данных   в   окно
выполняется автоматически, но в любой момент вы можете явно
передать данные.


                       Передача данных в окно
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     После создания  окна  или  диалогового  блока   данные
автоматически.    Для    создания    экранного    элемента,
представляющего  оконный   объект,   конструктор   вызывает
SetupWindow.  Затем  для загрузки данных из буфера передачи
вызывается  TransferData.  Окно  SetupWindow   интерактивно
вызывает SetupWindow для каждого из дочерних окон,  так что
дочерние  окна  имеют  возможность  передать  свои  данные.
Поскольку порождающее окно устанавливает свои дочерние окна
в порядке их построения,  данные в буфере  передачи  должны
следовать в том же порядке.

     Если объект   управляющего  элемента  был  построен  с
помощью  InitResource  или  если  порождающее  окно   явным
образом   разрешило  межанизм  передачи  путем  вызова  для
управляющего    элемента    EnableTransfer,    то    методы
управляющего объекта SetupWindow вызывают TransferData.


                Передача данных из диалогового окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда режимное   диалоговое  окно  получает  командной
сообщение с идентификатором  управляющего  элемента  id_OK,
оно  автоматически передает данные из управляющего элемента
в буфер  передачи.  Обычно  это  сообщение  указывает,  что
пользователь  для  завершения  диалога  щелкнул  "мышью" на
кнопке OK,  так что  диалог  автоматически  обновляет  свой
буфер  передачи.  Затем,  если  вы снова выполняете диалог,
диалоговый  блок  передает  текущие  данные  в  управляющие
элементы.


                      Передача данных из окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Однако, вы  можете  явно  передавать  данные  в  любом
направлении в любой момент  времени.  Например,  вы  можете
передать   данные   из   управляющих   элементов  окна  или
безрежимного диалога.  Вы также можете  сбросить  состояния
управляющих элементов,  используя данные буфера передачи, в
ответ на щелчок "мышью" на кнопке Reset  (сброс).  В  обоих
случаях    используется   метод   TransferData.   Константа
tf_SetData  обозначает  передачу   данных   из   буфера   в
управляющий  элемент,  а  константа tf_GetData - передачу в
другом   направлении.   Например,   вы    можете    вызвать
TransferData в методе Destroy объекта окна:

     procedure TSampleWindow.Destroy;
     begin
      TransferData(tf_GetData);
      TWindow.Destroy;
     end;


Поддержка передачи   для   специализированных   управляющих
элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
 Вы можете  изменить способ передачи данных для конкретного
управляющего  элемента  или  включить   новый   управляющий
элемент,  определенный  вами в механизме передачи.  В обоих
случаях вам просто нужно написать метод Transfer для вашего
управляющего   объекта,   который   если   установлен  флаг
tf_GetData  копирует  данные  из  управляющего  элемента  в
место,   задаваемое   указателем.   Если   установлен  флаг
tf_SetData,  то  просто  скопируйте  данные  по   заданному
указателю  в  управляющий  элемент.  Рассмотрим  в качестве
примера TStatic.Transfer:

     function TStatic.Transfer(DataPrt: Pointer;
                               TransferFlag: Word): Word;
     begin
      if TransferFlag = tf_GetData then
             GetText(DataPrt, TextLen)
      else if TransferFlag = tf_SetData then
              SetText(DataPtr);
      Transfer:=TextLen;
     end;

     Метод Transfer   должен   всегда   возвращать    число
переданных байт информации.


                     Пример программы: TranTest
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Основное окно    программы    TranTest   воспроизводит
режимный диалог с полями,  в  которые  пользователь  вводит
данные  об имени и адресе.  Буфер передачи используется для
хранения этой информации и  отображения  ее  в  управляющих
элементах  диалога  при повторном его выполнении.  Обратите
внимание на то,  что нам  не  нужно  определять  новый  тип
объекта  диалога  для  установки  и  поиска данных диалога.
Также обратите ваше внимание на то,  что мы непосредственно
манипулируем  данными буфера передачи,  поэтому статическое
управление при первом выводе диалога гласит "First  Mailing
Label"  (первая  почтовая  этикетка),  а при всех остальных
появлениях "Subsequent Mailing Label"  (следующая  почтовая
этикетка).

           Примечание: Полный  текст программы содержится в
      файле TRANTEST.PAS на ваших дистрибутивных дискетах.


Использование специализированных управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Windows обеспечивает   механизм,    позволяющий    вам
создавать  свои  собственные виды управляющих элементов,  а
ObjectWindows  облегчает  создание  объектов,  использующих
преимущества   управляющих   элементов.  В  данном  разделе
обсуждается  использование  специализированных  управляющих
элементов   Borland,   которые   придают  своеобразный  вид
работающим  в  Windows   приложениям   Borland,   а   затем
описывается,  как  создавать  свои  собственные  уникальные
управляющие элементы.


Специализированные управляющие элементы Borland для Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Специализированные управляющие  элементы  Borland  для
Windows   (BWCC)  обеспечивают  выразительный  внешний  вид
приложений Borland для Windows.  Основными средствами  BWCC
являются:

     * командные кнопки с графическими изображениями;

     * серый "рельефный" фон диалоговый блоков;

* трехмерные кнопки с зависимой и независимой фиксацией.

     ObjectWindows дает  вам возможность простого доступа к
BWCC,  так  что  вы  можете  придать   своим   приложениями
стандартный для Borland вид.


                   Использование стандартных BWCC
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows позволяет  легко  добавлять  BWCC в ваши
приложения Windows.  Нужно просто добавить  модуль  BWCC  в
оператор uses программы:

     uses BWCC;

     Использование BWCC  автоматически позволяет вам делать
следующее:

     * использовать  загружаемые  из  ресурсов  управляющие
       элементы BWCC;

     * создавать в вашей программе BWCC.

     Например, с   помощью   пакета  разработчика  ресурсов
Resource WorkShop  вы  можете  создать  ресурсы  диалоговых
блоков,    использующие    специализированные   управляющие
элементы  Borland.  Включение  в  оператор  uses  программы
модуля  BWCC  обеспечивает для вашей программы информацию о
том,  где   искать   динамически   компонуемую   библиотеку
(BWCC.DLL),  содержащую  код,  который  обеспечивает работу
BWCC.

     Кроме того,  после  добавления   модуля   BWCC   любые
создаваемые в программе объекты управляющих элементов будут
иметь вид и характеристики управляющих элементов Borland.


                           Средства BWCC
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     BWCC добавляет к стандартным управляющим  элементам  в
стиле  Windows некоторые новые стили,  но подчиняется также
новым соглашения и предположениям.  Если  вы  создаете  все
свои   новые   управляющие   элементы   из   ресурсов,   то
беспокоиться об этом вам не нужно.  Однако  при  построении
управляющих   элементов   в   программном  коде  вам  может
потребоваться  использовать   некоторые   новые   стили   и
следовать соглашениям.


                          Расширение BWCC
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     BWCC обеспечивает  кнопки с графическими изображениями
для всех стандартных командных  кнопок  Windows.  То  есть,
имеются   графические   изображения,   предусмотренные  для
командных  кнопок,   для   которых   Windows   обеспечивает
стандартный идентификатор:  id_Abort, id_Cancel, id_Ignore,
id_No, id_Ok, id_Retry и id_Yes.

          Создание кнопок с графическими изображениями

     В своих приложениях вы можете обеспечить для командных
кнопок   собственные  графические  образы.  Все  что  нужно
предусмотреть - это шесть ресурсов графических  изображений
(битовых     массивов),     пронумерованных    относительно
идентификатора  управляющего   элемента   вашей   командной
кнопки.   Например,  если  вы  хотите  создать  графическую
командную кнопку с идентификатором id_MyButton, то создаете
ресурсы  битовых массивов с идентификаторами ресурса 1000 +
id_MyButton, 2000 + id_MyButton, 3000 + id_MyButton, 4000 +
id_MyButton,  5000  +  id_MyButton  и  6000  + id_MyButton.
Каждый представляемый битовый массив  показан  в  следующей
таблице:

Ресурсыбитовыхмассивовдлякомандных кнопок BWCCТаблица12.12
ЪДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДї
і    Образ               і Идентификатор   і Идентификаторі
і                        і  ресурса VGA    і  ресурса VGA і
ГДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДґ
і    Командная кнопка    і 1000 + идент.   і  2000 + иденті
і    в фокусе            і                 і              і
і                        і                 і              і
ГДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДґ
і    Нажатая командная   і 3000 + идент.   і  4000 + иденті
і    кнопка              і                 і              і
і                        і                 і              і
ГДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДґ
і    Командная кнопка    і 5000 + идент.   і  6000 + иденті
і    не в фокусе         і                 і              і
і                        і                 і              і
АДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДЩ

     Графические образы  командных  кнопок VGA должны иметь
ширину 63 и высоту 39  элементов  изображения.  Графические
образы командных кнопок EGA должны иметь ширину 63 и высоту
39 элементов изображения.

     Для текста  следует   использовать   шрифт   Helvetica
размером 8 пунктов,  а вокруг образа кнопки,  находящейся в
фокусе,  следует выводить рамку из точек. Набор графических
изображений  для  командных  кнопок  с  идентификатором 201
показан на следующем рисунке:

ЪДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДДїЪДДДДДДДДДДДДДДї
і±±±±±±±±±±±±±±±±±±і  і±±±±±±±±±±±±±±±±±±іі±±±±±±±±±±±±±±і
і±±±ІІ±±±±±±Add±±±±і  і±±±ІІ±±±±±±Add±±±±іі±±±ІІ±±±±±±Addі
і±ІІІІІІ±±±±Pen±±±±і  і±ІІІІІІ±±±±Pen±±±±іі±ІІІІІІ±±±±Penі
і±±±ІІ±±±±±±±±±±±±±і  і±±±ІІ±±±±±±±±±±±±±іі±±±ІІ±±±±±±±±±і
і±±±±±±±±±±±±±±±±±±і  і±±±±±±±±±±±±±±±±±±іі±±±±±±±±±±±±±±і
АДДДДДДДДДДДДДДДДДДЩ  АДДДДДДДДДДДДДДДДДДЩАДДДДДДДДДДДДДДЩ
        1201                  3201                5201

ЪДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДДїЪДДДДДДДДДДДДДДДДДДї
і              і± і          .....   іі          .....  ±і
і   ІІ      Addі± і   ІІ    : Add :  іі   ІІ    : Add : ±і
і ІІІІІІ    Penі± і ІІІІІІ  : Pen :  іі ІІІІІІ  : Pen : ±і
і   ІІ         і± і   ІІ     .....   іі   ІІ     .....  ±і
і              і± і                  іі ±±±±±±±±±±±±±±±±±і
АДДДДДДДДДДДДДДЩ± АДДДДДДДДДДДДДДДДДДЩАДДДДДДДДДДДДДДДДДДЩ
  ±±±±±±±±±±±±±±±
        2201              4201                6201

     Рис. 12.9  Графические  ресурсы  для  командной кнопки
BWCC с идентификатором 201.


                     Создание ваших собственных
            специализированных управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Простейший способ     создания     специализированного
управляющего элемента состоит в фактическом создании  окна,
которое  действует  как  управляющий  элемент,  но вовсе не
является окном.  Этот подход используется в программе Steps
в  Части  1  данного  руководства.  Тот  же  используемый в
программе Steps метод применяется для ее  объекта  палитры,
который можно использовать,  например, для создания объекта
инструментальной  полосы.  Таким   "управляющие   элементы"
являются  наследниками  TWindow,  а не TControl,  поскольку
TControl имеет дело  только  со  стандартными  управляющими
элементами Windows.

     Другим стандартным          способом          создания
специализированного    управляющего    элемента    является
построение  в  динамически  компонуемой  библиотеке  нового
класса  окон.  После  этого  вы  можете  создавать  объекты
ObjectWindows,   использующие   этот   новый  класс.  Пакет
разработчика    ресурсов    также    может     использовать
специализированные  управляющие элементы,  созданные в DLL.
Информацию об использовании специализированных  управляющих
элементов  в  ресурсах  диалоговых блоках вы можете найти в
"Руководстве пользователя по пакету разработчика ресурсов".

   Примечание: О классах окон рассказывается в Главе 10.


             Глава 13. Проверка допустимости данных
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows представляет   вам   несколько    гибких
способов   проверки   допустимости  информации,  набираемой
пользователем в управляющем элементе редактирования,  путем
связи    объектов   проверки   допустимости   с   объектами
управляющих   элементов    редактирования.    Использование
объектов   проверки   допустимости   облегчает   добавление
механизма проверки допустимости к существующим  приложениям
ObjectWindows или для изменения способа проверки в поле его
данных.

     Данная глава охватывает следующие темы,  относящиеся к
проверке допустимости:

     * Три вид проверки допустимости данных.

     * Использование объектов проверки допустимости.

     * Как работает проверка допустимости.

     Проверка допустимости  обрабатывается методом CanClose
интерфейсных объектов.  В любой момент вы можете  проверить
содержимое   любого   конкретного   управляющего   элемента
редактирования или экрана  данных,  вызвав  метод  CanClose
объекта,  но  ObjectWindows  предусматривает также механизм
автоматизации проверки допустимости данных.  В  большинстве
случаев проверка допустимости данных практически не требует
от программиста никаких усилий.


               Три вида проверки допустимости данных
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Существует три различных  типа  проверки  допустимости
данных,  и ObjectWindows поддерживает их по-разному.  Этими
тремя видами являются:

     * Фильтрация ввода.

     * Проверка допустимости каждого элемента.

     * Проверка допустимости полных экранов.

     Заметим, что     эти      методы      не      являются
взаимно-исключающими.   Ряд  стандартных  средств  проверки
допустимости могут комбинировать в одном механизме проверки
допустимости различные методы.

     Важно запомнить, что проверка допустимости выполняется
объектом проверки допустимости,  а не объектом управляющего
элемента  редактирования.  Если  вы уже создали для особого
назначения    специализированный    управляющий     элемент
редактирования,   то   возможно  сдублировали  возможность,
встроенную  в  управляющие  элементы  редактирования  и  их
средства проверки допустимости.

     В разделе данной главы "Как работают средства проверки
допустимости"  описываются  различные  способы,  с  помощью
которых   объекты   управляющего   элемента  редактирования
автоматически вызывают объекты проверки допустимости.


                          Фильтрация ввода
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Простейший способ обеспечения включения в поле  только
допустимых данных состоит в обеспечении ввода пользователем
только допустимых данных.  Например,  числовое  поле  ввода
может  быть ограничено вводом пользователем только цифровых
данных.

     Объект фильтра  проверки  допустимости   ObjectWindows
представляет  общий механизм,  ограничивающий вид символов,
которые пользователь может  вводить  в  данном  управляющем
элементе   редактирования.  Объекты  проверки  допустимости
рисунков могут также контролировать форматирование  и  типы
символов, которые может набирать пользователь.


                 Проверка допустимости каждого поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Иногда удобно    гарантировать,   чтобы   пользователь
обеспечивал для  конкретного  поля  допустимый  ввод  перед
переходом  к  следующему  полю.  Этот подход часто называют
"проверкой допустимости по табуляции",  поскольку переход в
новое поле обычно выполняется по клавише Tab.

     В качестве примера можно привести приложение,  которое
выполняет поиск в базе данных,  где пользователь  вводит  в
поле  некоторые  виды  ключевой  информации,  а  приложение
отвечает  на  это  считыванием  соответствующей  записи   и
фильтрацией   остальных   полей.   В  таком  случае  вашему
приложению перед действием по клавише  требуется  проверка,
что  пользователь  набрал  в  этом ключевом поле правильную
информацию.


                Проверка допустимости полных экранов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Проверить допустимость полных экранов вы можете  тремя
различными способами:

     * Проверкой допустимости режимных окон.
     * Проверкой допустимости при изменении фокуса.
     * Проверкой допустимости по запросу.

               Проверка допустимости режимных окон

     Когда пользователь закрывает режимное окно,  оно перед
закрытием автоматически проверяет допустимость  всех  своих
подобластей  просмотра  (если  закрывающей командой не была
cmCancel).  Для проверки допустимости всех подобластей окно
вызывает метод CanClose каждой подобласти, и если каждый из
них возвращает True,  то окно можно закрыть.  Если любая из
подобластей  возвращает  значение  False,  то  окно закрыть
нельзя.

     Пока пользователь  не  обеспечит  допустимые   данные,
режимное   окно   с   недопустимыми  данными  можно  только
отменить.

                Проверка допустимости по запросу

     В любой момент вы можете указать окну на необходимость
проверки  всех  его  подокон  путем вызова метода CanClose.
CanClose по существу спрашивает  окно  "Если  сейчас  будет
дана  команда закрытия,  являются ли все поля допустимыми?"
Окно вызывает методы CanClose всех своих  дочерних  окон  в
порядке   включения   и   возвращает  True,  если  все  они
возвращают значение True.

     Вызов CanClose не обязывает вас  фактически  закрывать
окно.   Например,   вы   можете   вызвать  CanClose,  когда
пользователь "нажимает" командную кнопку Save (Сохранение),
обеспечивая   проверку   допустимости   данных   перед   их
сохранением.

     Вы можете   проверить   любое   окно   (режимное   или
безрежимное)   и   в  любое  время.  Однако  автоматическую
проверку допустимости при закрытии  имеют  только  режимные
окна. Если вы используете безрежимные окна ввода данных, то
нужно  обеспечить,  чтобы  приложение   перед   выполнением
действий с введенными данными вызывало метод CanClose окна.




    Использование механизма проверки допустимости данных
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Использование объекта  проверки  допустимости данных с
управляющим элементом редактирования требует двух шагов:

     * Построение объекта проверки допустимости.
     * Присваивание     объекта    проверки    допустимости
       управляющему элементу редактирования.

     После того,   как   вы   построите   объект   проверки
допустимости   и   свяжите   его  с  управляющим  элементом
редактирования,  вам не потребуется взаимодействовать с ним
непосредственно.  Управляющий элемент редактирования знает,
когда вызывать  методы  проверки  допустимости  и  в  какие
моменты.


             Построение объектов проверки допустимости
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Так как  объекты  проверки  допустимости  не  являются
интерфейсными объектами,  их конструкторам требуется только
информация,  достаточная  для  установки  критерия проверки
допустимости.  Например,   объект   проверки   допустимости
числового    диапазона   воспринимает   два   параметра   -
минимальное и максимальное значения в допустимом диапазоне:

     constructor TRangeValidator.Init(AMin, AMax: Integer);



              Добавление к управляющим элементам
          редактирования средств проверки допустимости
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Каждый управляющий элемент редактирования имеет поле с
именем Validator, установленное по умолчанию в nil, которое
может указывать на объект проверки допустимости. Если вы не
присваиваете объекта полю Validator, то управляющий элемент
редактирования ведет себя так,  как  описано  в  Главе  12.
После  присваивания  с  помощью вызова SetValidator объекта
проверки допустимости  управляющий  элемент  редактирования
автоматически проверяется им при обработке основных событий
и при самом вызове для проверки допустимости.

     Обычно, как    показано    ниже,    объект    проверки
допустимости строится и присваивается в одном операторе:

     .
     . {  создание  трехсимвольного  управляющего  элемента
      редактирования }

 Ed := New(PEdit, Init(@Self, id_Me, '', 10, 10, 50, 30, 3,
                False));
 Ed^.SetValidator(New(PRangeValidator, Init(100, 999)));
     .
     .
     .


                 Как работает проверка допустимости
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В ObjectWindows предусмотрено несколько видов объектов
проверки    допустимости,    которые    должны   охватывать
большинство  ваших  потребностей  по  проверке  данных.  Из
абстрактных  типов  проверки  допустимости  вы можете также
построить свои собственные производные типы.

     В данном разделе освещаются следующие темы:

     * Виртуальные методы объекта проверки допустимости.
     * Стандартные типы объекта проверки допустимости.


                Методы объекта проверки допустимости
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Каждый объект   проверки   допустимости  наследует  от
абстрактного  объектного  типа  TValidator  четыре   важных
метода.   Различным   образом   переопределяя  эти  методы,
наследующие объекты проверки  допустимости  выполняют  свои
конкретные   задачи   по   проверке.  Если  вы  собираетесь
модифицировать стандартные  объекты  проверки  допустимости
или написать собственные объекты проверки допустимости,  то
нужно понимать,  что делает каждый из этих методов и как их
используют управляющие элементы редактирования.

     Этими четырьмя методами являются следующие:

     * Valid

     * IsValid

     * IsValidInput

     * Error

     Единственными методами,   вызываемыми   вне   объекта,
являются  Valid  и  IsValidInput.   Error   и   IsValid   -
единственные  методы,  вызываемые  другими методами объекта
проверки допустимости.


                    Проверка допустимости данных
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Основным внешним  интерфейсом  с  объектами   проверки
допустимости данных является метод Valid. Аналогично методу
CanClose интерфейсных объектов,  Valid  представляет  собой
булевскую функцию,  которая возвращает значение True,  если
переданная ей строка содержит допустимые  данные.  Один  из
компонентов    метода    CanClose   управляющего   элемента
редактирования является вызов метода Valid с переданным ему
текущим текстом управляющего элемента редактирования.

     При использовании   средств  проверки  допустимости  с
управляющими  элементами  редактирования  вам  никогда   не
требуется  вызывать  или переопределять метод Valid объекта
проверки допустимости.  По умолчанию Valid возвращает True,
если возвращает True метод IsValid.  В противном случае для
уведомления пользователя  об  ошибке  и  возврата  значения
False вызывается Error.


                       Проверка полной строки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

    Объекты проверки   допустимости   содержат  виртуальный
метод   IsValid,   который    воспринимает    в    качестве
единственного  аргумента  строку  и  возвращает True,  если
строка представляет допустимые данные. IsValid - это метод,
который  выполняет  фактическую проверку допустимости,  так
что  если  вы   создаете   собственные   объекты   проверки
допустимости, то почти всегда переопределяете IsValid.

     Заметим, что  метод  IsValid  не вызывается вами явно.
Используйте для вызова IsValid метод  Valid,  так  как  для
уведомления  пользователя в случае возврата методом IsValid
значения False Valid вызывает метод Error. Не путайте также
проверку допустимости сообщением об ошибке.


                Проверка допустимости нажатий клавиш
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда объект   управляющего   элемента  редактирования
получает имеющее для него значение событие нажатия клавиши,
он    вызывает    метод   IsValidInput   объекта   проверки
допустимости. По умолчанию методы IsValid всегда возвращают
True.  Это означает, что воспринимаются все нажатия клавиш.
Однако,  наследующие объекты  проверки  допустимости  могут
переопределять  метод  IsValidInput,  чтобы отфильтровывать
нежелательные нажатия клавиш.

     Например, средства  проверки  допустимости  диапазона,
которые  используются  для  числового ввода,  возвращают из
IsValidInput True только для цифр и символов '+' и '-'.

     IsValidInput воспринимает   два   параметра.    Первый
параметр  -  это  параметр-переменная,  содержащая  текущий
текст ввода.  Второй параметр  -  это  булевское  значение,
указывающее,    следует    ли   перед   попыткой   проверки
допустимости  применять  к  строке  ввода  дополнение   или
заполнение.   TPictureValidator   -   это  единственный  из
стандартных объектов  проверки  допустимости,  использующий
второй параметр.


                  Сообщение о недопустимых данных
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Виртуальный метод  Error уведомляет пользователя,  что
содержимое управляющего элемента редактирования  не  прошло
проверку   допустимости.   Стандартные   объекты   проверки
допустимости  в  общем  случае  представляет  простой  блок
сообщения,  уведомляющий пользователя, что содержимое ввода
недопустимо,  и описывающее,  каким должен быть  правильный
ввод.

     Например, метод   Error   для   проверки  допустимости
диапазона создает блок сообщения, указывающий, что значение
в  управляющем  элементе  редактирования не находится между
указанными минимальным и максимальным значениями.

     Хотя большинство   объектов   проверки    допустимости
переопределяют   Error,   вам   не   следует  вызывать  его
непосредственно. Метод Error вызывается методом Valid, если
IsValid   возвращает   False   (что  является  единственным
моментом, когда необходимо вызывать Error).


             Стандартные средства проверки допустимости
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows включает в себя шесть стандартных  типов
объектов проверки допустимости,  включая абстрактный объект
проверки допустимости и следующие  пять  специальных  типов
таких объектов:

     * Фильтрация.
     * Проверка диапазона.
     * Проверка допустимости с просмотром.
     * Проверка допустимости с просмотром строк.
     * Проверка допустимости с просмотром шаблонов.


              Абстрактный объект проверки допустимости
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Абстрактный тип  TValidator  служит  базовым типом для
всех объектов проверки допустимости,  но сам по себе он  не
делает  ничего  полезного.  По  существу,  TValidator - это
объект проверки допустимости,  для которого всегда допустим
любой ввод: IsValid и IsValidInput возвращают True, а Error
не   выполняет   никаких    функций.    Наследующие    типы
переопределяют  IsValid и/или IsValidInput для фактического
определения того, какие значения являются допустимыми.

     Если никакие  из  других  объектных   типов   проверки
допустимости  не  годятся  в  качестве исходных,  вы можете
использовать  TValidator   в   качестве   отправной   точки
собственных объектов проверки допустимости.


                             Фильтрация
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Фильтрующие объекты   проверки   допустимости   -  это
простая  реализация  средств  проверки  допустимости,   при
которой  проверяется  только набираемый пользователем ввод.
Конструктор  фильтрующего  объекта  проверки   допустимости
воспринимает один параметр - набор допустимых символов:

  constructor TFilterValidator.Init(AValidChars: TCharSet);

     TFilterValidator переопределяет    IsValidInput    для
возврата True только в  том  случае,  если  все  символы  в
текущей   строке   ввода   содержатся  в  наборе  символов,
переданных     конструктору.      Управляющие      элементы
редактирования  включают символы только в том случае,  если
IsValidInput возвращает True,  так  что  нет  необходимости
переопределять  IsValid.  Поскольку  символы проходят через
фильтр ввода, полная строка допустима по определению.

     Потомки TFilterValidator,  такие как  TRAngeValidator,
могут   сочетать  фильтрацию  ввода  с  другими  проверками
завершенной строки.


                         Проверка диапазона
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Объект проверки допустимости диапазона  TRangeVaidator
- это потомок TFilterValidator, которые воспринимают только
числа  и  добавляют   к   итоговым   результатам   проверку
диапазона.    Конструктор   воспринимает   два   параметра,
определяющим   минимальное   и   максимальное    допустимое
значение:

     constructor TRangeValidator.Init(AMin, AMax: Integer);

     Объект проверки   допустимости  диапазона  сам  строит
числовое   средство   проверки-фильтрации,   воспринимающее
только  цифры  '0'..'9'  и  символы  плюса и минуса.  Таким
образом, наследуемый IsValidInput обеспечивает отфильтрацию
только цифр.  Затем TRangeValidator переопределяет IsValid,
чтобы  он  возвращал  True  только  если  введенные   числа
находятся    в   допустимом   диапазоне,   определяемом   в
конструкторе.   Метод   Error   выводит   блок   сообщения,
указывающий,   что   введенное   значение   находится   вне
диапазона.


                 Проверка допустимости с просмотром
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Абстрактный объект проверки допустимости с  просмотром
TLookupValidator   обеспечивает   основу  для  общего  типа
объекта  проверки  допустимости,  который  для  определения
допустимости   сравнивает  введенное  значение  со  списком
воспринимаемый элементов.

     TLookupValidator -  это   абстрактный   тип,   который
никогда  не  используется  сам  по  себе,  но служит важным
изменением и дополнением к  стандартному  объекту  проверки
допустимости.

           Примечание: Пример работы такого объектного типа
      вы можете найти в разделе по преобразованию строк.

     Новый метод,   вводимый   объектом    TLookupValidator
называется Lookup.  По умолчанию Lookup возвращает значение
False, но при образовании производного абстрактного объекта
проверки допустимости c просмотром вы можете переопределить
Lookup  для  сравнения  переданной  строки  со  списком   и
возвращать True, если строка содержит допустимую запись.

     TLookupValidator переопределяет  IsValid  для возврата
True  только  если  Lookup   также   возвращает   True.   В
наследующих  типах  проверки  допустимости с просмотром вам
следует переопределять не IsValid, а Lookup.


                           Просмотр строк
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Рабочий пример   объекта   проверки   допустимости   с
преобразованием     представляет    TStringLookupValidator,
сравнивающий   переданную    из    управляющего    элемента
редактирования  строку  с  элементами в списке строк.  Если
переданная  строка  содержится  в  списке,  метод   объекта
проверки  допустимости с просмотром строки возвращает True.
Конструктор воспринимает  только  один  параметр  -  список
допустимых строк:

     constructor       TStringLookupValidator.Init(AString:
                                        PStringCollection);

     Чтобы после построения объекта проверки допустимости с
просмотром  использовать  другой  список  строк,  передайте
новый  список   методу   NewStringList   объекта   проверки
допустимости  (который  уничтожает  старый  список и задает
новый).

     TStringLookupValidator переопределяет методы Lookup  и
Error,  так  что  Lookup  возвращает True,  если переданная
строка содержится в наборе строк,  а Error выводит на экран
блок  сообщения,  указывающий,  что  строка  отсутствует  в
списке.


                  Проверка допустимости по шаблону
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Объекты проверки допустимости  с  шаблоном  сравнивают
строки,  набранные пользователем,  с шаблоном,  описывающим
формат допустимого ввода.  Применяемые шаблоны совместимы с
теми, которые используются для контроля ввода в реляционной
базе данных Paradox фирмы Borland.  При построении  объекта
проверки   допустимости   по   шаблону   используется   два
параметра:  строка,  содержащая образ шаблона,  и булевское
значение,   указывающее,  нужно  ли  заполнять  по  шаблону
литеральные строки.

           Примечание: Синтаксис  шаблонов  описывается   в
      справочнике. См. TPXPictureValidator.Picture.

     constuctor TPictureValidator.Init(const APic: String;
                                       AAutoFill: Boolean);

     TPictureValidator переопределяет Error, IsValidInput и
IsValid и добавляет новый метод Picture.  Изменения в Error
и IsValid просты:  Error выводит на экран  блок  сообщения,
указывающий,  какой  формат должна иметь строка,  а IsValid
возвращает True  только  если  True  возвращается  функцией
Picture,  позволяя получать новые производные типы проверки
допустимости по шаблону путем переопределения только метода
Picture.  IsValidInput  проверяет символы по мере набора их
пользователем,  допуская   только   те   символы,   которые
разрешены   в   шаблоне   формата,   и   возможно  дополняя
литеральные символы из шаблона.

     Метод Picture пытается сформатировать заданную  строку
ввода  в  соответствии  с  шаблоном  формата  и  возвращает
значение,  указывающее степень успеха: полный, неполный или
ошибка.

                       Глава 14. Объекты MDI
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Многодокументальный интерфейс  (MDI)  -  это  стандарт
интерфейса  для  приложений  Windows,   которые   позволяют
пользователю  одновременно работать с несколькими открытыми
документами.  Документ, в этом смысле, это обычно связанная
с файлом задача,  например, редактирование текстового файла
или работа с файлом электронной таблицы.  В приложениях MDI
пользователь  может,  например,  иметь  несколько  открытых
файлов  в  одном   приложении.   Возможно,   что   вы   уже
использовали приложения MDI:  Microsoft Exel, администратор
программ Windows,  администратор файлов  Windows.  Стандарт
MDI  является  также  частью  спецификации  общего  доступа
пользователя (CUA) фирмы IBM.
     ObjectWindows предусматривает   объекты,   позволяющие
легко писать приложения MDI.

                    Что такое приложение MDI?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Имеются определенные компоненты,  которые присутствуют
в каждом приложении MDI.  Чаще всего основное окно вызывает
окно с рамкой.  В области клиента окна-рамки есть невидимое
окно  -  окно клиента MDI - которое содержит дочернее окно,
вызывающее  дочерние  окна  MDI.  Это  очень  важно,   т.к.
обработка   дочерних   окон   MDI   происходит  скрытно  от
пользователя.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫMDI ConformistЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і MDI Children                                            і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї          і
іі±±±±±±±±±±±±±±±±±±Child #1±±±±±±±±±±±±±±±±±±±і          і
іГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ          і
іі ЪДДЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї     і
іі і Xі±±±±±±±±±±±±±±±±±±±±Child #2±±±±±±±±±±±±±±±±±і     і
іі АДДГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ     і
іі    і ЪДДЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДїі
іі    і і Xі±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫChild #3ЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvіі
іАДДДДі АДДГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґі
і     і    і ЪДДДї                                     ^ іі
і     і    і і X і  CanClose    блоки минимизации и ДДДЩ іі
і     АДДДДі АДДДЩ              максимизации             іі
і          і                       ^                     іі
і          АДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДЩі
                дочернее окно MDI ДЩ                      і
і ЪДДДї                                                   і
і і  <ЕДДД пиктограмма                                    і
і АДДДЩ                                                   і
і Child #4             ^                                  і
АДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                       і                     ^
      кно клиента MDI ДЩ                     і
                            окно-рамка MDI  ДЩ

       Рис. 14.1 Компоненты приложения MDI.

                        Меню дочернего окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Строка меню  окна-рамки  содержит  меню,   управляющее
дочерними  окнами  MDI.  Меню дочернего окна содержит такие
элементы как Tile (Вывод без перекрытия),  Cascade (Вывод с
перекрытием),  Arrange  (Упорядочить)  и Close All (Закрыть
все).  Имя  каждого  открытого   окна   MDI   автоматически
добавляется к концу этого меню с выбором текущего окна.

                         Дочерние окна MDI
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Каждое дочернее    окно    MDI     имеет     некоторые
характеристики     перекрывающего     окна.    Его    можно
максимизировать до полного размера  окна  клиента  MDI  или
минимизировать  в пиктограмму,  которая помещается к нижней
границе окна-рамки. Дочернее окно MDI никогда не выходит за
границы  его окна-рамки (обрамляющего окна).  Дочернее окно
MDI  не  может  иметь  меню,  поэтому   все   его   функции
реализуются  меню  окна-рамки.  Заголовок каждого дочернего
окна MDI часто  представляет  собой  имя  открытого  файла,
связанного   с  этим  окном,  хотя  его  поведение  заранее
неизвестно и определяется программой.  Можно  рассматривать
приложение  MDI  как  мини-сеанс  Windows,  когда несколько
приложений представлены окнами или пиктограммами.


                      Окна MDI в ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows определяет типы для представления  рамок
MDI   и  клиентов  MDI.  Это  соответственно  TMDIWindow  и
TMDIClient.  TMDIWindow является производным от TWindow, но
TMDIClient  на  самом  деле  представляет собой управляющий
элемент и является производным от  TControl.  В  приложении
MDI  ObjectWindows,  окно-рамки владеет своим окном клиента
MDI  и  хранит  его  в  поле  ClientWnd.  Окно-рамка  также
содержит  каждое  из  дочерних  окон MDI в связанном списке
ChildList.  Дочерние окна MDI  являются  экземплярами  типа
объекта, производного от написанного вами TWindow.

     Методы TMDIWindow      занимаются      в      основном
конструированием и управлением дочерними окнами MDI,  окном
клиента  MDI  и  обработкой  выбора в меню.  Главная работа
TMDIClient происходит скрытно от пользователя и  состоит  в
управлении дочерними окнами MDI.  При разработке приложений
MDI вы в общем случае будете  создавать  новые  производные
типы  для  своих  рамок  и  дочерних окон соответственно от
TMDIWindow и TWindow.


                     Построение приложения MDI
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Построение приложения MDI в ObjectWindows представляет
собой относительно простую задачу:

     * Построение основного окна MDI.

     * Установка меню дочернего окна.

     * Предоставление  основному  окну возможности создания
       дочерних MDI.

     Окно MDI  обрабатывает  для  вас   все   специфические
функции,  а  ваши  функции,  специфические  для приложения,
могут перейти в дочерние окна.


                        Построение рамки MDI
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Окно-рамка MDI   всегда   является   основным    окном
приложения,    поэтому    оно   конструируется   в   методе
InitMainWindow его объекта приложения.  Однако,  существует
два  аспекта  рамки  MDI,  которые  отличают  его от других
основных окон:

     * Рамка MDI всегда является  основным  окном,  поэтому
       оно   никогда  не  имеет  порождающего  окна.  Таким
       образом,    TMDIWindow.Init    нет     необходимости
       воспринимать    в   качестве   параметра   указатель
       порождающего окна.

     * Окно-рамка MDI всегда должно  иметь  меню,  так  что
       вторым параметром Init является описатель меню.  Для
       основных окон,  отличных от  MDI  и  производных  от
       TWindows,   вы   определяете   Init   для  установки
       Attr.Menu    в    допустимый     описатель     меню.
       TMDIWindow.Init устанавливает для вас AttrMenu.

     Типичный метод InitMainWindow для приложения MDI может
выглядеть следующим образом:

     procedure TMDIApplication.InitMainWindow;
     begin
       MainWindow := New(PMyFrame, Init('Заголовок рамки',
                         LoadMenu(HInstance, 'MenuName'));

     Если предположить,   что   TMyFrame   -   это  потомок
TMDIWindow,  при этом будет создаваться  окно-рамка  MDI  с
заголовком  "Заголовок  рамки"  и  строкой  меню,  заданной
ресурсом "MenuName".


                    Создание меню дочерних окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Меню окна-рамки должно включать в себя меню  дочернего
окна в стиле MDI. Открытие дочернего окна MDI добавляет его
заголовок к меню дочернего окна,  а закрытие дочернего окна
удаляет   его   из   списка.   Это  позволяет  пользователю
активизировать  любое  дочернее  окно,  даже  если  оно  не
является видимым.

     Окно-рамка должно знать, каким элементом меню верхнего
уровня является меню его дочернего окна.  Объект TMDIWindow
хранит  целое значение позиции в поле объекта ChildMenuPos.
TMDIWindow.Init первоначально устанавливает ChildMenuPos  в
ноль,  указывая крайний левый элемент меню верхнего уровня.
Однако,  для  установки  позиции  ChildMenuPos  вы   можете
переопределить  Init  для своего производного от TMDIWindow
типа:

constructor TMyMDIWindow.Init(ATitle: PChar; AMenu: HMenu);
     begin
       inherited Init(ATitle, AMenu);
       ChildMenuPos := 1;
     end;

     TMDIWindow.Init также  вызывает  InitClientWindow  для
конструирования  объекта  TMDIClient,  который будет служит
его окном клиента MDI.  TMDIWindow.SetupWindow создает окно
клиента MDI.


                     Создание дочерних окон MDI
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TMDIWindow определяет   автоматический  метод  реакции
CreateChild,  который  вызывается  при   выборе   из   меню
варианта,    результатом    которого    будет   команда   с
идентификатором  Create_Child.  Обычно  этот  вариант  меню
называется New или Create. Как это определено в TMDIWindow,
CreateChild конструирует и создает дочернее окно  MDI  типа
TWindow    вызовом    TMDIWindow.InitChild.   Для   задания
корректного типа дочернего окна (производного от  TWindow),
переопределим InitChild для вашего типа окна-рамки MDI:

     function MyMDIWindow.InitChild: PWindowsObject;
     begin
      InitChild:=New(PMyChild, Init(@Self,
                     'Новое дочернее окно'));
     end;



                    Автоматические дочерние окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Может потребоваться,     чтобы     ваша     окно-рамка
воспроизводило  только  одно  дочернее  окно  MDI при своем
первом появлении.  Для  этого  первого  дочернего  окна  вы
можете явно задать его размер. В отличие от других дочерних
окон,  дочерние окна  MDI  должны  быть  сконструированы  и
созданы  в методе SetupWindow окна-рамки MDI,  а не в Init.
Вы также должны явно  создать  экранный  элемент  дочернего
окна с помощью вызова MakeWindow:

     procedure MyMDIWindow.SetupWindow;
     var
        ARect: TRect;
        NewChild: PMyChild;
     begin
        TMDIWindow.SetupWindow;
        NewChild:=PMyChild(InitChild);
        GetClientRect(HWindow, ARect);
      with NewChild^.Attr, ARect do
      begin
         W:=(right*4) div 5;
         H:=(bottom*3) div 5;
         Title:='Child #1';
      end;
        Application^.MakeWindow(NewChild);
     end;

     В некоторых  приложениях   вам   может   потребоваться
создать дочернее окно MDI в ответ на более чем один выбор в
меню.  Например,  пункты меню New и Open в редакторе  файла
могут  приводить  к  возникновению  нового дочернего окна с
заголовком в виде имени файла. В этом случае определите для
построения  дочернего  окна  методы автоматической реакции.
ObjectWindows   определяет   команды    cm_MDIFileOpen    и
cm_MDIFileNew,  что облегчает дифференциацию от стандартных
cm_FileOpen и cm_FileNew.




                   Управление дочерним окном MDI
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Тип окна   MDI   в   ObjectWindows   содержит   методы
манипулирования  дочерними окнами MDI приложения MDI.  Хотя
большая часть скрытой работы делается в TMDIClient,  доступ
к данным и функциям происходит через метод TMDIWindow.

     TMDIWindow определяет   методы  реакции  на  сообщения
Windows,  которые автоматически реагируют на выбор  команды
стандартного меню MDI: Title, Cascade, Arrange Icon и Close
All.  Эти методы ожидают основанных на командах сообщений с
заранее  определенными  константами  идентификаторов  меню.
Обязательно используйте эти идентификаторы  при  построении
ресурса меню дочернего окна:

Стандартные методы, команды и действия MDI    Таблица 14.1
ЪДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДї
іДействие     і Константа ID меню   і Метод TMDIWindow    і
ГДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДґ
іTile         і cm_TileChildren     і CM_TileChildren     і
іCascade      і cm_CascadeChildren  і CM_CascadeChildren  і
іArrange Iconsі cm_ArrangeChildIconsі CM_ArrangeChildIconsі
іClose All    і cm_CloseChildren    і CM_CloseChildren    і
АДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДЩ

     Методы реакции  TMDIWindows,  подобные CMTileChildren,
вызывают другие методы TMDIWindows,  такие как  CMChildren.
Эти  методы  вызывают  методы  TMDIClient  с тем же именем,
например,  TMDIClient^.TileChildren.  Для   переопределения
такого   автоматического   поведения  нужно  переопределить
TMDIWindow.TileChildren или другой  метод  TMDIWindow.  Для
дочерних окон MDI не подходит реагирование на основанные на
командах сообщения, генерируемые меню дочернего окна.


                Настройка активизации дочернего окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Пользователь приложения     MDI     может     свободно
активизировать  любое  открытое или минимизировать дочернее
окно  MDI.  Однако,  вам  может  потребоваться  предпринять
некоторые  действия,  когда пользователь дезактивирует одно
дочернее  окно   активизацией   другого.   Например,   меню
окна-рамки   может  отражать  текущее  состояние  активного
дочернего окна,  выделяя  его  цветом.  Каждый  раз,  когда
дочернее  окно  становится  активным  или  неактивным,  оно
получает сообщение Windows wm_MDIActivate.  Определив метод
реакции  на  это  с  общение для дочернего окна,  вы можете
отслеживать,  какое дочернее окно активно и  соответственно
реагировать.


                Обработка сообщений в приложении MDI
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Как и   для   обычных  порождающих  и  дочерних  окон,
основанные на командах и дочерних идентификаторах сообщения
Windows сначала поступают в дочерние окна для их восприятия
и обработки.  Затем сообщения поступают в порождающее окно.
Однако,  в  случае  приложения  MDI  сообщения  поступают к
текущему дочернему окну MDI,  затем к окну клиента MDI,  и,
наконец,  к  окну-рамке  MDI  (которое является порождающим
окном для всех  дочерних  окон  MDI).  Следовательно,  меню
окна-рамки  можно  использовать  для  управления  работой в
текущем   активном   дочернем   окне   MDI.   Затем    шанс
отреагировать получают окно клиента и окно-рамка.


                       Пример приложения MDI
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Программа MDITest  создает приложение MDI,  показанное
на Рис.  14.1. Полный текст файла MDITEST.PAS содержится на
ваших дистрибутивных дискетах.


                      Глава 15. Объекты печати
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Один из наиболее трудных аспектов  программирования  в
Windows   -  это  вывод  на  принтер.  ObjectWindows  путем
использования  ряда  модулей   и   инкапсуляции   поведения
устройства  печати  и  самой распечатки делает печать более
простой.

     Данная глава описывает основы процесса  печати,  после
чего описываются следующие задачи:

     * Построение объекта принтера.

     * Создание распечатки.

       - Печать документа.

       - Печать содержимого окна.

     * Передача распечатки на принтер.

     * Выбор другого принтера.

     * Настройка конфигурации принтера.


               Почему печать представляет трудности?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     С одной стороны печать в Windows достаточно проста. Вы
можете использовать для генерации распечатки те же  функции
GDI,  что  используются  для  вывода образов на экран.  Для
вывода  текста  используется   функция   TextOut,   а   для
вычерчивания прямоугольника - Rectangle.

     С другой стороны, процесс осложняется, так как Windows
требует непосредственного "общения" с  драйверами  принтера
через  вызовы  Escape  или  получения адреса DeviceMode или
ExtDeviceMode.  Это  еще  более   осложняется   требованием
Windows, чтобы приложение считывало имя драйвера устройства
из файла WIN.INI.  Кроме того,  устройства печати  обладают
большими     возможностями    проверки    допустимости    и
возможностями разрешения, чем видеоустройства.

     ObjectWindows не может преодолеть все  препятствия  на
этом пути,  но делает процесс печати более простым и легким
для понимания.


                       Печать в ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Модуль ObjectWindows  OPrinter   предусматривает   для
упрощения  печати  два  объекта  -  TPrinter  и  TPrintout.
TPrinter инкапсулирует  доступ  к  устройствам  печати.  Он
предоставляет возможность конфигурирования принтера, выводя
диалог,  в  котором  пользователь  может   выбрать   нужный
принтер,  а  также  установить параметры печати,  такие как
графическое разрешение  или  ориентация  (горизонтальная  и
вертикальная) печати.

     TPtintout инкапсулирует  задачу  печати  документа.  К
принтеру этот объект имеет такое же отношение,  как TWindow
-  к экрану.  Рисование на экране выполняется методом Paint
объекта TWindow,  а печать на принтере - методом  PrintPage
объекта  TPrintout.  Чтобы  напечатать  что-то на принтере,
приложение должно передать методу  Print  объекта  TPrinter
экземпляр TPrintout.


                    Построение объекта принтера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В большинстве  случаев  приложению  требуется в каждый
момент времени доступ только к одному принтеру.  Простейшим
способом   реализации  этого  является  задание  в  объекте
основного окна  поля  с  именем  Printer  (типа  PPrinter),
которые  другие  объекты  в  программе  вызывают  для целей
печати.  Чтобы  сделать  принтер  доступным,  поле  Printer
должно указывать на экземпляр TPrinter.

     В большинстве  приложений  это  просто.  Основное окно
приложения   инициализирует   объект   принтера,    который
использует  заданный  по  умолчанию  принтер,  указанный  в
WIN.INI:

     constructor TSomeWindow.Init(AParent: PWindowsObject;
                                  ATitle: PChar);
     begin
        Inherited Init(AParent, ATitle);
         .
         .
         .
        Printer := New(PPrinter, Init);
     end;

     В некоторых  случаях  может  возникать   необходимость
использовать  в  приложении различные принтеры одновременно
из различных окон.  В этом случае постройте объект принтера
в   конструкторах   каждого   такого  окна,  затем  смените
устройство принтера на один или более таких принтеров. Если
программа    использует    различные    принтеры,   но   не
одновременно,  то возможно лучше использовать один и тот же
объект  принтера  и  при  необходимости  выбирать различные
принтеры.

     Хотя вы  можете  сомневаться  насчет   переопределения
конструктора TPrinter для использования принтера, отличного
от  заданного  в  системе   по   умолчанию,   рекомендуемой
процедурой    является    использование   конструктора   по
умолчанию,  а затем смена связанного с объектом устройства.
См. раздел "Выбор другого принтера".


                        Создание распечатки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Единственной "хитрой"   частью   процесса   печати   в
ObjectWindows являются создание  распечатки.  Этот  процесс
аналогичен  написанию  метода  Paint  для объекта окна:  вы
используете графические функции  Windows  для  генерации  в
контексте устройства нужного графического образа.  Контекст
устройства    оконного    объекта     обрабатывает     ваши
взаимодействия  с  устройством экрана;  аналогичным образом
контекст устройства распечатки изолирует вас от  устройства
печати.

     Примечание: Графические  функции  Windows поясняются в
      Главе 17.

     Чтобы создать объект распечатки,  постройте новый тип,
производный от TPtintout, который переопределяет PrintPage.
В очень простых случаях это  все,  что  требуется  сделать.
Если  документ  имеет  размер более одной страницы,  то вам
нужно также переопределить HasNextPage для  возврата  True.
Текущий  номер  страницы  передается  в  качестве параметра
PrintPage.

     Объект распечатки  имеет   поля,   содержащие   размер
страницы и контекст устройства, который уже инициализирован
для  принтера.  Объект  принтера  устанавливает   значения,
вызывая    метод    объекта    распечатки   SetPrintParams.
Используйте контекст устройства объекта распечатки в  любом
вызове графических функций Windows.

     Модуль OPrinter включает в себя два специализированных
объекта распечатки,  которые показывают диапазон  сложности
распечаток.  Объект TWindowPrintout,  печатающий содержимое
окна,  очень   прост.   TEditPrintout,   который   печатает
содержимое   управляющего  элемента  редактирования,  очень
сложен, так как имеет множество возможностей.


                          Печать документа
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Windows рассматривает          распечатку          как
последовательность страниц,  поэтому задачей вашего объекта
распечатки     является     превращение     документа     в
последовательность  станичных  образов  для печати Windows.
Аналогично  тому  как  оконные  объекты  используются   для
отображения  образов на экране дисплея,  объекты распечатки
используются для печати образов на принтере.

     ObjectWindows предусматривает    абстрактный    объект
распечатки   TPrintout,   из  которого  вы  можете  создать
производные объекты распечатки.  Вам нужно переопределить в
TPrintout только несколько методов.

     Ваши объекты распечатки должны делать следующее:

     * Устанавливать параметры принтера.

     * Подсчитывать страницы.

     * Отображать каждую страницу в контексте устройства.

     * Указывать, есть ли еще страницы.

     Остальная часть   этой   главы   ссылается  на  пример
программы  PrnTest,  записанной  на  ваших   дистрибутивных
дискетах   под   именем   PRNTEST.PAS.   PrnTest  считывает
текстовый файл в набор строк,  а затем по команде  печатает
документ. Объект PrnTest описывается следующим образом:

     type
       PTextPrint = ^TTextPrint;
       TTextPrint = object(TPrintout);
        TextHeight, LinesPerPage, FirstOnPage, LastOnPage:
            Integer;
         TheLines; PCollection;
         constructor Init(ATitle: PChar;
                        TheText: PPCharCollection);
      function GetDialogInfo(var Pages: Intger): Boolean;
                        virtual;
      function HasNextPage(Page: Word): Boolean; virtual;
      procedure SetPrintParams(ADC: HDC; ASize: TPoint);
                          virtual;
      procedure PrintPage(Page: Word; var Rect: TRect;
                          Flags: Word); virtual;
     end;



                     Задание параметров печати
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Перед запросом  распечатки  документа  объект принтера
предоставляет  вашему  документу  возможность  разбивки  на
страницы.   Для   этого   вызываются   два  метода  объекта
распечатки - SetPrintParams и GetDialogInfo.

     Функция SetPrintParams предназначена для инициализации
структур данных,  которые могут потребоваться для получения
эффективной распечатки отдельных страниц.  SetPrintParams -
это   первая  возможность  вашей  распечатки  обратиться  к
контексту устройства и задать для принтера размер страницы.
Приводимый   ниже   фрагмент  программы  показывает  пример
переопределенного метода SetPrintParams.

     Если вы переопределяете  SetPrintParams,  убедитесь  в
вызове наследуемого метода, устанавливающего значения полей
распечатки объекта.


                        Подсчет страниц
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     После вызова  SetPrintParams  объект  печати  вызывает
булевскую   функцию   GetDialogInfo.  GetDialogInfo  задает
информацию,  необходимую для вывода  на  экран  диалогового
блока,  позволяющего  пользователю  выбрать  перед  печатью
диапазон страниц.  В подсчете  страниц  в  GetDialogInfo  и
индикации вывода диалогового блока имеются два аспекта.

     Функция GetDialogInfo     воспринимает    единственный
параметр-переменную Pages, которую она должна устанавливать
в  число  страниц  в  документе или в 0,  если она не может
подсчитать страницы. Возвращаемое значение равно True, если
вы  хотите вывести диалоговый блок,  и False для подавления
его вывода.

     По умолчанию GetDialogInfo устанавливает Pages в  0  и
возвращает True,  что означает,  что она не знает,  сколько
может  получиться  страниц,  и  что  перед  печатью   будет
выводиться    диалоговый    блок.    GetDialogInfo   обычно
переопределяется для установки  Pages  в  число  страниц  в
документе и возвращает True.

     Например, PrnTest  подсчитывает,  сколько строк текста
выбранного шрифта может  поместиться  в  области  печати  в
SetPrintParams,  а  затем использует это число для подсчета
количества   страниц,   которые    нужно    напечатать    в
GetDialogInfo:

     procedure TTextPrint.SetPrintParams(ADC: HDC;
                                         ASize: TPoint);
     var TextMetrics: TTextMetric;
     begin
   inherited SetPrintParams(ADC, ASize);  { установить DC и
                                              размер Size }
   GetTextMetrics(DC, TextMetrics); { получить информацию о
                                         размере текста }
   TextHeigh := TextMetrics.tmHeight; { вычислить высоту
                                            строки }
   LinesPerPages := Size.Y div TextHeight; { и число строк
                                              на странице }
     end;

     function TTextPtint.GetDialogInfo(var Pages: Integer):
                                       Boolean);
     begin
       Pages:= TheLines^.Count div LinesPerPage + 1;
   GetDialogInfo := True { вывод перед печатью диалогового
                               блоки }
     end;



                       Печать каждой страницы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда объект   принтера   предоставляет    возможность
разбивки  документа  на  страницы,  то  для  печати  каждой
страницы он вызывает метод  PrintPage  объекта  распечатки.
Процесс   распечатки   только   части  документа,  которому
принадлежит данная страница,  аналогичен определению  того,
какую   часть  прокручиваемого  окна  нужно  отображать  на
экране.   Например,   можно   отметить   подобие    методов
отображения окна и отображения страницы:

     procedure TTextWindow.Paint(PaintDC: HDC;
        var PaintInfo: TPaintStruct);
     var
        Line: Integer;
        TextMetrics: TTextMetric;
        TheText: PChar;

        function TextVisible(ALine: Integer): Boolean;
        begin
          with Scroller^ do
         TextVisible := IsVisible(0, (ALine div YUnit) +
                YPos, 1, Attr.W div YUnit);
          end;

     begin
       GetTextMetrics(PaintDC, TextMetrics);
       Scroller^.SetUnits(TextMetrics.tmAveCharWidth,
           TextMetrics.tmHeight);
       Line := 0;
 while (Line < FileLines^.Count) and TextVisible(Line) do
       begin
         TheText := PChar(FileLines^.At(Line));
         if TheText <> nil then
      TextOut(PaintDC, 0, Line * Scroller^.YUnit, TheText,
              StrLen(TheText));
         Inc(Line);
       end;
     end;

procedure TTextPrint.PrintPage(Page: Word; var Rect: TRect;
                                    Flags: Word);
var
  Line: Integer;
  TheText: PChar;
begin
  FirstOnPage := (Page - 1) * LinesPerPage;
  LastOnPage := (Page * LinesPerPage) - 1;
  if LastOnPage >= TheLines^.Count then
    LastOnPage := TheLines^.Count - 1;
  for Line := FirstOnPage to LastOnPage do
  begin
    TheText := Theines^.At(Line);
    if TheText <> nil then
      TextOut(DC, 0, (Line - FirstOnPage) * TextHeight,
          TheText, StrLen(TheText));
  end;
end;

     При написании  методов  PrintPage следует иметь в виду
следующее:

     * Независимость от устройств.  Убедитесь,  что в вашем
       коде    не   делается   предположений   относительно
       масштаба,  коэффициента относительного удлинения или
       цветах.  Для  различных устройств видеоотображения и
       печати эти характеристики могут отличаться,  так что
       в программе следует избегать такой зависимости.

     * Возможности      устройств.     Хотя     большинство
       видеоустройств  поддерживают   все   операции   GDI,
       некоторые принтеры этого не делают. Например, многие
       устройства  печати  (такие   как   графопостроители)
       совсем не воспринимают графических изображений.  При
       выполнении сложных задач вывода в программе  следует
       вызывать функцию API Windows GetDeviceCaps,  которая
       возвращает важную  информацию  о  данном  устройстве
       вывода.

                    Указание оставшихся страниц
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     У объектов   распечатки   имеется   также    последняя
обязанность  -  указать объекту принтера,  имеются ли после
данной страницы еще печатаемые страницы.  Метод HasNextPage
воспринимает в качестве параметра номер строки и возвращает
значение Boolean,  указывающее, существуют ли еще страницы.
По  умолчанию HasNextPage всегда возвращает значение False.
Чтобы напечатать несколько страниц, ваши объекты распечатки
должны  переопределять HasNextPage для возврата True,  если
документ имеет больше страниц для  печати,  и  False,  если
переданным параметром является последняя страница.

     Например, PrnTest     сравнивает    номер    последней
напечатанной  строки  с  последней  строкой   в   файле   и
определяет, нужно ли печатать еще страницы:

     function TTextPrint.HasNextPage(Page: Word): Boolean;
     begin
       HasNextPage := LastOnPage < TheLines^.Count - 1;
     end;

     Убедитесь, что  HasNextPage  возвращает  в   некоторой
точке  значение  False.  Если HasNextPage всегда возвращает
True, то процесс печати попадет в бесконечный цикл.


                    Другие соглашения по печати
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Объекты распечатки  содержат  также  несколько  других
методов,    которые    вы    можете    при    необходимости
переопределить.   Методы   BeginPrintint   и    EndPrinting
вызываются,  соответственно,  перед  печатью и после печати
любого документа. Если вам требуется специальная установка,
вы  можете  выполнить  ее  в  BeginPrinting  и  отменить  в
EndPrinting.

     Печать страниц выполняется последовательно.  То  есть,
для  каждой  страницы в последовательности принтер вызывает
метод PrintPage.  Однако,  перед первым  вызовом  PrintPage
объект  принтера  вызывает  BeginDocument,  передавая номер
первой и последней страницы, которые будут печататься. Если
для  вашего  документа  при  печати  страниц,  отличных  от
первой,  требуется специальная  подготовка,  переопределите
метод  BeginDocument.  После  распечатки последней страницы
вызывается соответствующий метод EndDocument.

     Может потребоваться   также   переопределение   метода
GetSelection.  GetSelection  указывает в своем возвращаемом
булевском значении,  имеет ли  документ  выделенную  часть.
Если  это  так,  диалоговое  окно  печати предоставляет вам
возможность  распечатать  только  эту   выделенную   часть.
Позицию  выделения указывают два параметра-переменных Start
и Stop. Например, TEditPrintout интерпретирует Start и Stop
как  позиции  символов,  но может представлять также строки
текста, страницы и т.д.


                       Печать содержимое окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Поскольку окно не разбивается на несколько страниц,  и
оконные  объекты  уже  знают,  как отображаться в контексте
устройства,  простейшим   видом   генерируемой   распечатки
является копия содержимого окна.

     Чтобы еще   более   облегчить   эту   общую  операцию,
ObjectWindows  обеспечивает  дополнительный   вид   объекта
распечатки    -    TWindowPrint.   Любой   оконный   объект
ObjectWindows   может   без   модификации   печатать   свое
содержимое  в  объект  TWindowPrintout.  Объекты распечатки
масштабируют образ для заполнения нужного числа  страниц  и
поддерживают коэффициент относительного удлинения.

     Создание объекта распечатки окна требует только одного
шага.  Все,  что требуется сделать - это  построить  объект
печати окна,  передавая ему строку заголовка и указатель на
окно, которое требуется напечатать:

     PImage := New(PWindowPrintout, Init('Заголовок',
                                           PSomeWindow));

     Часто возникает  необходимость в том,  чтобы окно само
создавало свою распечатку,  возможно  в  ответ  на  команды
меню:

     procedure TSomeWindow.CMPrint(var Msg: TMessage);
     var P: PPrintout;
     begin
    P := New(PWindowPrintout, Init('Дамп экрана', @Self));
       { передать образ на экран }
       Dispose(P, One);
     end;

     TWindowPrintout не    предусматривает    разбивки   на
страницы.  При печати документа вам нужно  печатать  каждую
страницу  отдельно,  но так как окна не имеют страниц,  вам
нужно напечатать только один образ.  Окно  уже  знает,  как
создать    этот    образ   -   оно   имеет   метод   Paint.
TWindowsPrintout печатается путем вызова метода Paint  окна
объекта  с  контекстом  устройства  печати вместо контекста
дисплея.


                    Вывод распечатки на принтер
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     При наличии  объекта  принтера  и  объекта  распечатки
фактическая    печать    выполняется   достаточно   просто,
независимо от того,  происходит это  из  документа  или  из
окна.  Все,  что вам нужно сделать - это вызов метода Paint
объекта принтера,  передача указателя на порождающее окно и
указателя на объект распечатки:

     Printer^.Print(PParentWindow, PPrintoutObject);

     В этом случае порождающее окно - это окно,  к которому
будут  присоединены  все   всплывающие   диалоговые   блоки
(например,  состояния  принтера  или сообщений об ошибках).
Обычно это будет окно, генерирует команду печати, такое как
основное  окно  со  строкой  меню.  В  процессе  печати для
предотвращения передачи  множественных  команд  печати  это
окно запрещается.

     Предположим, у  вас  есть  приложение,  основное  окно
которого является экземпляром TWidGetWindow.  В меню  этого
окна  вы можете выбрать команду меню для печати содержимого
окна,  генерирующую  команду  cm_Print.  Метод  реакции  на
сообщения может иметь следующий вид:

     procedure TWidgetWindow.CMPrint(var Msg: TMessage);
     var P: PPrintout;
     begin
       P := New(PWindowPrint, Init('Widgets', @Self));
       Printer^.Print(@Self, P);
       Dispose(P, Done);
     end;


                       Выбор другого принтера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда у  вас  в  приложении  есть объект принтера,  вы
можете  связать  его  с  любым  установленным   в   Windows
устройстве   печати.   По   умолчанию  TPrinter  использует
заданный по умолчанию принтер Windows (как это определено в
разделе устройств файла WIN.INI).

     Существует два    способа    задания   альтернативного
принтера:  непосредственно в программе и  через  диалоговое
окно пользователя.


                    Выбор принтера пользователем
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Наиболее общим  способом  назначения  другого принтера
является   вывод   диалогового    окна,    предоставляющего
пользователю  возможность  выбора  из  списка установленных
устройств печати.  TPtinter делает  это  автоматически  при
вызове его метода Setup.  Как показано на Рис.  15.1, Setup
использует    для    этого    диалогового    окна    объект
TPrinterSetupDlg.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫSelectPrinterЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і                                                       і
і      Printer and port:                                і
і      ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДї         і
і      іPostScript Printer on LPT1:         іvі         і
і      АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДЩ         і
і   ЪДДДДДДДДДДДї         ЪДДДДДДДДДДДї ЪДДДДДДДДДДДї   і
і   і±±±±OK±±±±±і         і±±Setup±±±±і і±±Cancel±±±і   і
і   АДДДДДДДДДДДЩ         АДДДДДДДДДДДЩ АДДДДДДДДДДДЩ   і
і                                                       і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 15.1 Диалоговое окно задания принтера.

                 Настройка конфигурации принтера

     Одна из  командных  кнопок  в  диалоге выбора принтера
позволяет пользователям изменить  конфигурацию  конкретного
принтера.    Кнопка    Setup    выводит   диалоговый   блок
конфигурации,  определенной  в  драйвере   принтера.   Ваше
приложение  не  может управлять внешним видом или функциями
диалогового блока конфигурации драйвера.



                  Назначение конкретного принтера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В некоторых  случаях вам может потребоваться назначить
для  своего  объекта  принтера   специфическое   устройство
печати.  TPrinter имеет метод SetDevice, который именно это
и делает.

     SetDevice воспринимает  в  качестве   параметров   три
строки: имя устройства, имя драйвера и имя порта.

                     Часть 3. Продвинутое
         программирование с использование ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


                     Глава 16. Сообщения Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Приложения Windows   управляются  событиями.  То  есть
вместо непосредственной обработки  оператор  за  оператором
управление   программой  определяется  внешними  событиями,
такие  как  взаимодействия  с  пользователем  и   системное
оповещение.  Приложения  узнают о событиях,  на которые они
должны реагировать, получая от Windows сообщения.

     Данная глава   охватывает   ряд   тем,   связанных   с
передачей,   получением  и  обработкой  сообщений,  включая
следующие вопросы:

     * что такое сообщение?

     * как выполняется диспетчеризация сообщений?

     * обработка сообщений Windows;

     * определение ваших собственных сообщений;

     * передача и адресация сообщений;

     * диапазоны сообщений.


                     Часть 3. Продвинутое
         программирование с использование ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


                     Глава 16. Сообщения Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Приложения Windows   управляются  событиями.  То  есть
вместо непосредственной обработки  оператор  за  оператором
управление   программой  определяется  внешними  событиями,
такие  как  взаимодействия  с  пользователем  и   системное
оповещение.  Приложения  узнают о событиях,  на которые они
должны реагировать, получая от Windows сообщения.

     Данная глава   охватывает   ряд   тем,   связанных   с
передачей,   получением  и  обработкой  сообщений,  включая
следующие вопросы:

     * что такое сообщение?

     * как выполняется диспетчеризация сообщений?

     * обработка сообщений Windows;

     * определение ваших собственных сообщений;

     * передача и адресация сообщений;

     * диапазоны сообщений.


                        Что такое сообщение?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если вы не используете  программирование,  управляемое
событиями,  Windows  может  выглядеть  достаточно  странной
операционной  средой.   Возможно,   вам   придется   писать
программы,  которые  основную  часть  своего времени просто
ждут ввода от пользователя (например, в операторе Readln).

     Программирование, управляемое событиями,  обходит  эту
ситуацию,  возлагая  обработку  ввода  от  пользователя  на
центральную  подпрограмму,  которую  вам  даже   не   нужно
вызывать.    В   этом   случае   Microsoft   Windows   сама
взаимодействует  с  пользователем   и   опрашивает   список
взаимодействий  для  каждого  работающего  приложения.  Эти
информационные пакеты называются сообщениями и представляют
собой просто структуры записей типа TMsg:

     type
       TMsg = record
         hwnd: HWnd;
         message: Word;
         wParam: Word;
         lParam: Longint;
         time: Longint;
         pt: TPoint;
     end;

     Поля записи  сообщения  дают  приложению  информацию о
том,  какой вид событий  сгенерировал  сообщение,  где  оно
произошло и какое окно должно на него реагировать.

     Относительно сообщений следует иметь в виду,  что ваше
сообщение в  общем  случае  получает  их  после  того,  что
произошло.  Например,  если  вы  изменяете  размер  окна на
экране, то объект окна получает сообщение wm_Size, когда вы
закончите    изменение    размера.    Некоторые   сообщения
запрашивают  выполнение   каких-то   действий.   Однако   в
большинстве случаев это уведомления о том, что пользователь
или  система  выполнили  некоторые  действия,  на   которые
следует реагировать вашей программе.


                        Именующие сообщения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Наиболее важным полем сообщений является поле message,
которое  содержит  одну  из  констант  сообщений   Windows,
начинающихся  с  wm_.  Каждое  сообщение Windows уникальным
образом    идентифицируется     16-битовым     числом     с
соответствующим  мнемоническим  идентификатором.  Например,
сообщение, являющееся результатом нажатия клавиши, содержит
в  поле  сообщения wm_KeyDown ($0100).  На сообщения обычно
ссылаются по их мнемоническим именам.


                     Откуда поступают сообщения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Генерировать сообщения позволяют  несколько  различных
событий:

     * взаимодействия  с  пользователем,  такие как нажатия
       клавиш, щелчок кнопкой "мыши" или ее буксировка;
     * вызовы функций Windows,  которым нужно информировать
       об изменениях другие окна;
     * ваша программа явно посылает сообщение;
     * другое  приложение  посылает  сообщение  через   DDE
       (динамический обмен данными);
     * сообщение  генерируется  самой  Windows   (например,
       сообщение об останове системы).

     Вашему приложению   в   общем  случае  не  важно,  как
генерируются  сообщения.   Основным   в   программировании,
управляемом   событиями,  является  генерация  сообщений  и
реакция на них.  Поскольку Windows и ObjectWindows берут на
себя  функции  по  доставке  сообщений  из  одного  места в
другое,  вы можете сосредоточиться на генерации сообщений с
соответствующими  параметрами и реакции на сообщения,  а не
на механизме их доставки из одного места в другое.


                 Обычная диспетчеризация сообщений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Обычные приложения Windows (то  есть  не  использующие
ObjectWindows) имеют цикл сообщения,  в котором выполняется
выборка и диспетчеризация сообщения.  По существу,  в цикле
сообщения  вызывается  связанная с окном функция,  заданная
описателем окна в поле hwnd записи сообщения.

     Каждое окно  имеет  функцию  окна,  заданную  при  его
создании.  Когда  Windows находит сообщение для конкретного
окна,  она передает сообщение функции данного окна. Функция
окна отсортировывает сообщения на основе типа сообщения,  а
затем   вызывает   подпрограмму   реакции   на   конкретное
сообщение.

     Обычный способ  обработки сообщений в приложении и его
окнах показывает программа GENERIC.PAS.  Вы можете  видеть,
что  оконная  функция каждого окна для сортировки сообщение
содержит большой оператор case.  Все это может выглядеть не
так плохо,  пока вы не осознаете тот факт, что в окне может
потребоваться обрабатывать более  100  различных  сообщений
Windows.  После  этого идея написания и обслуживания такого
оператора case будет выглядеть менее впечатляющей.

     Даже если у вас имеется  несколько  аналогичных  окон,
каждое из них будет, очевидно, иметь свою оконную функцию с
аналогичным большим оператором case.


                 Способ, предлагаемый ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows вносит    в    это    обычный     способ
диспетчеризации  сообщений  два основных улучшения.  Первое
состоит в том,  что цикл  сообщений  скрыт  в  ядре  вашего
объекта  приложения.  Все,  что  вам  нужно  сделать  - это
привести свое  приложение  в  действие,  вызвав  метод  Run
объекта   приложения.   После   этого  оно  будет  получать
сообщения Windows.

     Второе основное   улучшение   -   это   автоматическая
диспетчеризация  сообщений.  Вместо необходимости иметь для
каждого окна  оконную  функцию,  вы  просто  определяете  в
оконных  объектах  методы,  которые реагируют на конкретные
сообщения.  Эти  методы  называются  методами  реакции   на
сообщения.


                  Динамические виртуальные методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ключем к   автоматической   диспетчеризации  сообщений
является  расширение  описаний   в   объектах   виртуальных
методов, называемых динамическими виртуальными методами. По
существу вы связываете с методом целочисленный номер (такой
как  константа сообщения).  Ваша программа ObjectWindows (в
данном случае  цикл  сообщения  объекта  приложения)  может
затем вызвать этот метод на основе номера сообщения.

     Например, сообщение,  генерируемое  при нажатии в окне
левой  кнопки  "мыши",  содержит  в  своем   поле   message
wm_LButtonDown ($0201).  Когда цикл сообщения ObjectWindows
считывает для одного из  своих  окон  такое  сообщение,  то
выполняется  поиск  в  таблице  виртуальных методов данного
оконного  объекта  и   определяется   динамический   метод,
описанный для данного значения. Если такой метод найден, то
он  вызывается,  и  ему  в  качестве  параметра  передается
распакованная запись сообщения типа TMessage.  Если оконный
объект не описывает метод с данным  индексом  динамического
метода,   то   цикл   сообщения  вызывает  используемую  по
умолчанию оконную процедуру.


               Написание методов реакции на сообщение
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы описать  методы  реакции  на  сообщение,   нужно
задать  в  оконном  объекте  процедуру,  названную по имени
константы сообщения.  Например, чтобы ответить на сообщение
wm_LButtonDown, вам нужно описать методы следующим образом:

     type
       TMyWindow = object(TWindow)
          .
          .
          .
        procedure WMLButtonDown(var Msg: TMessage);
           virtual wm_First + wm_LButtonDown;
             .
             .
             .
     end;

     На самом  деле  метод может называться как угодно,  но
наименование  методов  по  сообщениям,   на   которые   они
реагируют, делают программу понятней. Единственным реальным
ограничением  является  то,  что  этот  метод  должен  быть
процедурой с единственным параметром типа TMessage.

     Поскольку для методов реакции ObjectWindows использует
несколько диапазонов,  а все индексы методы отсчитываются с
0,  в  качестве  смещения  используется константа wm_First.
Добавив для  каждого  метода  это  смещение,  вы  создадите
уникальный   индекс   динамического   метода.  Подробнее  о
диапазонах сообщений рассказывается  в  разделе  "Диапазоны
сообщений" данной главы.


                        Что такое сообщение?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Теперь, когда вы знаете, как написать метод реакции на
сообщение, можно рассмотреть, какая информация содержится в
сообщении.  Запись TMessage, передаваемая методу реакции на
сообщение, выглядит следующим образом:

     type
       TMessage = record
           Receiver: HWnd;
           Message: Word;
           case Integer of
             0: (
               WParam: Word;
               LParam: Longint;
               Result: Longint);
             1: (
               WParamLo: Byte;
               WParamHi: Byte;
               LParamLo: Word;
               LParamHi: Word;
               ResultLo: Word;
               ResultHi: Word);
     end;

     Поля Receiver и Message для объектов ObjectWindows  не
особенно   полезны,  поскольку  описатель  Receiver  обычно
представляет собой тоже самое,  что и поле HWindow оконного
объекта,  а  Message  уже  отсортировано  в цикле сообщения
ObjectWindows.

     Однако другие три поля очень важны.  WParam и LParam -
это  16- и 32-битовые параметры,  передаваемые в сообщениях
от Windows.  Result содержит код результата,  который может
потребоваться  передать  обратно.  Заметим,  что TMessage -
вариантная запись,  так что вы можете обращаться к старшему
и младшему байту слов параметров.


                          Поля параметров
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Поля параметров  записи  сообщения  имеют  для каждого
сообщения  свой  смысл.  Однако,  можно  сделать  некоторые
обобщения.

                             WParam

     Параметр WParam  типа  Word обычно содержит описатель,
идентификатор   (например,    идентификатор    управляющего
элемента) или булевское значение. Например, параметр WParam
сообщения wm_SetCursor содержит описатель окна,  в  котором
находится   курсор.   Уведомляющие  сообщения  управляющего
элемента,  такие  как   bn_Clicked,   содержат   в   WParam
идентификатор   соответствующего   управляющего   элемента.
wm_Enable  использует  WParam  для   булевского   значения,
указывающего, разрешено или запрещено соответствующее окно.

                             LParam

     Параметр LParam    типа    Longint   обычно   содержит
значение-указатель двух переменных размером в слово,  таких
как координаты x и y.  Например,  параметр LParam сообщения
wm_SetText  указывает  на  строку  с   завершающим   нулем,
содержащую устанавливаемый текст.  Сообщения "мыши",  такие
как wm_LButtonDown,  используют LParam для записи координат
события   "мыши".   Благодаря   вариантным   частям  записи
сообщения,  LParamLo содержит x-координату,  а  LParamHi  -
y-координату.


                            Поле Result
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Поле Result  сообщения TMessage управляет возвращаемым
значением   сообщения.   Иногда    программа,    посылающая
сообщение,  ожидает  возврата конкретного значения,  такого
как булевское значение, указывающее успешное или неуспешное
выполнение  или  код ошибки.  Вы можете задать возвращаемое
значение, присвоив значение полю Result.

     Например, когда  пользователь  пытается   восстановить
окно  из  состояния  пиктограммы,  ему посылается сообщение
wm_QueryOpen.   По   умолчанию   wm_QueryOpen    возвращает
булевское  значение  True  (не ноль).  Если вы хотите иметь
окно,  которое всегда выводится в виде пиктограммы,  то  вы
можете  ответить  на  сообщение  wm_QueryOpen  и установить
Result в 0. Это означает, что окно не может быть открыто:

     procedure TIconWindow.WMQueryOpen(var Msg: TMessage);
     begin
       Msg.Result := 0;
     end;



            Объектно-ориентированная обработка сообщения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Одним из огромных преимуществ  обработки  сообщения  в
ObjectWindows (кроме того,  что можно избавиться от больших
операторов    case)    является     обработка     сообщений
объектно-ориентированным  способом.  То есть,  ваши оконные
объекты  наследуют  возможность  определенной  реакции   на
сообщения,   и   вам   нужно  только  изменить  реакцию  на
конкретные  сообщения,  которые  ваш  объект   обрабатывает
по-другому.


                   Отмена поведения по умолчанию
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Иногда, когда   вы   переопределяете  используемую  по
умолчанию реакцию на сообщение,  это  делается  потому  что
данное  поведение  просто нежелательно.  Простейшим случаем
является  ситуация,  когда   объект   должен   игнорировать
сообщение,  а  не  отвечать  на  него.  Для этого вы можете
просто  написать  пустой  метод   реакции   на   сообщение.
Например,  следующий  метод  сообщает управляющему элементу
редактирования,  что  нужно  игнорировать  передаваемые   в
сообщении wm_Char символы:

     procedure TNonEdit.WMChar(var Msg: TMessage);
     begin
     end;

                   Замена поведения по умолчанию
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Более полезным  подходом,  чем  простое  игнорирование
сообщения,  является  замена  поведения по умолчанию чем-то
совершенно  другим.  Например,  следующий  метод   сообщает
управляющему  элементу  редактирования,  что вместо вставки
символа при нажатии любой  клавиши  нужно  давать  звуковой
сигнал:

     procedure TBeepEdit.WMChar(var Msg: TMessage);
     begin
       MessageBeep(0);
     end;

     Звуковой сигнал по  нажатию  клавиш  сам  по  себе  не
особенно  полезен,  но  дает  хорошую иллюстрацию.  В общем
случае  вы  можете  заменить  используемое   по   умолчанию
поведение некоторым другим. Определяемая вами реакция будет
единственной.

                 Дополнение поведения по умолчанию
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Иногда может  возникнуть  потребность в комбинировании
некоторых действий с используемой по умолчанию реакцией  на
сообщение.    ObjectWindows    предоставляет    для   этого
объектно-ориентированный способ.  Обычно,  когда вы хотите,
чтобы   объект   выполнял   некоторые  действия  на  основе
используемого по умолчанию поведения,  вы можете встроить в
свой     переопределенный    метод    наследуемый    метод.
ObjectWindows позволяет вам делать это также для реакции на
сообщения.

                     Вызов наследуемых методов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Предположим, например,  что вы создали  новый  оконный
объект  и  хотите,  чтобы  он  в дополнение к другим обычно
выполняемым действиям он давал звуковой сигнал при щелчке в
окне левой кнопкой "мыши". Все, что вам нужно сделать - это
вызов   в   вашем   новом   методе   наследуемого    метода
TWindow.WMLButtonDown:

    procedure TBeepWindow.WMLButtonDown(var Msg: TMessage);
     begin
       inherited WMLButtonDown(Msg);
       MessageBeep(0);
     end;

     В данном   случае  неважно,  размещаете  ли  вы  вызов
наследуемого метода WMLButtonDown перед  или  после  вызова
MessageBeep. Вам нужно решить, должен ли ваш метод вызывать
наследуемые действия перед специальной обработкой или после
нее (на основе того,  нужны ли вам параметры сообщения, или
требуется их изменить).

     Следует иметь в виду, что вы можете изменять параметры
Msg  перед  вызовом наследуемого метода.  Однако делать это
следует  аккуратно,  так  как   передача   параметров   вне
диапазона может привести к тому, что ваша программа вызовет
сбой  Windows,  особенно  если   эти   параметры   содержат
описатели   или   указатели.   Если  вы  будете  аккуратны,
изменение Msg может оказаться полезным, но нужно учитывать,
что это может быть также опасным.


             Вызов процедур, используемых по умолчанию
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Как вы  могли  заметить,  в  данном разделе при вызове
наследуемых методов используется не  такой  пример,  как  в
предыдущих  разделах.  Вы,  возможно,  ожидали,  что  новый
управляющий элемент редактирования для  обработки  действия
по  умолчанию будет вызывать свой наследуемый метод WMChar.
Это имеет смысл,  но не будет работать,  так как  TEdit  не
имеет метода WMChar, поэтому производный из TEdit объект не
может вызывать WMChar в качестве наследуемого метода.

     К счастью,  ваши объекты все равно  могут  наследовать
реакцию  на  сообщения.  Когда ObjectWindows диспетчеризует
сообщение объекту,  и этот объект не определяет конкретного
метода  реакции,  ObjectWindows  передает  запись  TMessage
методу с именем  DefWndProc  -  используемой  по  умолчанию
оконной процедуре. DefWndProc знает, как применять действия
по  умолчанию  для  всех  сообщений.  Таким  образом,  если
компилятор  дает  ошибку,  когда  вы  пытаетесь наследовать
метод реакции на сообщения, поскольку для данного сообщения
нет наследуемого метода, вызовите вместо этого DefWndProc.

     Например, чтобы  в  дополнение  к  вставке  набираемых
символов добавить к  управляющему  элементу  редактирования
звуковой   сигнал,   вам   нужно   вызвать   MessageBeep  и
DefWndProc:

     procedure TBeepEdit.WMChar(var Msg: TMessage);
     begin
       MessageBeep(0);
       DefWndProc(Msg);
     end;

     Вызов DefWndProc   вы   можете    рассматривать    как
используемый   вместо   всех   не   определенных  конкретно
наследуемых методов реакции на сообщения.  Отметим, однако,
что это применяется только к сообщениям Windows.  Командные
сообщения,  уведомляющие сообщения и управляющие  сообщения
имеют    свои   собственные   используемые   по   умолчанию
обработчики сообщений.  Эти сообщения и их используемые  по
умолчанию процедуры описываются в следующем разделе.


     Командные, уведомляющие и управляющие идентификаторы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Сообщение - это просто запись данных, идентифицируемая
конкретным  значением  в  поле  message,  а   ObjectWindows
экономит  вам  массу времени и усилий путем сортировки этих
сообщений и диспетчеризации их методам реакции на сообщения
в  ваших  объектах.  Однако,  сообщение  Windows wm_Command
имеет много  вариантов,  которые  нужно  отсортировывать  с
помощью   большого   оператора  case.  ObjectWindows  также
выполняет это для вас.

     Например, сообщение wm_Command посылается  при  выборе
элемента  меню  или нажатии оперативной клавиши.  В обычном
приложении сообщение Windows передавалось бы вашей  функции
окна,   где   в   большом  операторе  case  нужно  было  бы
отсортировать   различные   сообщения,    вызывая    другие
подпрограммы  при обнаружении wm_Command.  Эта подпрограмма
должна в  свою  очередь  определить,  какая  была  передана
команда (с помощью другого большого оператора case).


                        Командные сообщения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows обрабатывает  команды меню и оперативных
клавиш путем отдельной диспетчеризации командных  сообщений
в  основном  аналогично другим сообщениям Windows.  Реально
обработка выполняется внутри метода WMCommand ваших оконных
объектов,   наследуемого   из   TWindowsObject.  Но  вместо
обработки самих команд WMCommand выполняет  диспетчеризацию
командных   сообщений   на  основе  генерируемого  командой
идентификатора меню или оперативной клавиши.

     Например, если   вы   определяете   элемент   меню   с
идентификатором cm_DoSomething, в ваших объектах следует на
основе этого идентификатора определить методы реакции:

     type
       TSomeWindow = object(TWindow)
         .
         .
         .
         procedure CMDoSomething(var Msg: TMessage);
            virtual cm_First + cm_DoSomething;
       end;

  procedure TSomeWindow.CMDoSomething(var Msg: TMessage);
     begin
       { реакция на команду }
     end;

     Аналогично wm_First,   cm_First   -   это    константа
ObjectWindows,  определяющая  начало  диапазона  сообщений.
Ваши  командные  константы  должны   лежать   в   диапазоне
0..24319.

                  Обработка команд по умолчанию

     Чтобы вызвать  используемую  по  умолчанию  реакцию на
команду,  для  нее  обычно  вызывается  наследуемый   метод
реакции.   Если  в  объекте-предке  не  определяется  метод
реакции  на  конкретную  команду,  по  умолчанию  обработка
выполняется   с   помощью   DefCommandProc.  DefCommandProc
работает  во  многом  аналогично  методу   DefWndProc   для
сообщений Windows, но обрабатывает команды.


                       Уведомляющие сообщения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Команды не  обязательно  должны  поступать от меню или
командных клавиш.  Управляющие элементы  в  окнах  посылают
сообщения своим порождающим окнам, когда вы щелкаете на них
"мышью" или что-либо набираете.  Эти  сообщения  называются
уведомляющими сообщениями,  и ObjectWindows обрабатывает их
двумя различными путями.

     В основном  уведомления  могут  передаваться   объекту
управляющего  элемента  или  его  порождающему  окну.  Если
управляющий  элемент   имеет   связанный   с   ним   объект
ObjectWindows,   ObjectWindows   дает  объекту  возможность
сначала ответить на команду.  Это  называется  уведомлением
управляющего  элемента.  Если  управляющий элемент не имеет
соответствующего объекта,  или объект управляющего элемента
не   определяет  реакцию  на  команду,  то  ответить  имеет
возможность порождающее окно.  Это называется  уведомлением
порождающего объекта.


                 Уведомления управляющих элементов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Обычно управляющим  элементам  не требуется в ответ на
действия пользователя делать ничего  особенного;  ожидаемым
поведением  является поведение,  используемое по умолчанию.
Но если вы хотите,  чтобы управляющий элемент делал  что-то
дополнительно или что-то другое,  то уведомляющие сообщения
позволяют вам осуществить это.

     Предположим, например, что вы хотите, чтобы при каждом
щелчке кнопкой "мыши" раздавался звуковой сигнал. Вы можете
просто  задать  для  объекта  кнопки   метод   реакции   на
уведомление:

     type
       TBeepButton = object(TButton)
         procedure BNClicked(var Msg: TMessage);
             virtual nf_First + bn_Clicked;
       end;

     procedure TBeepButton.BNClicked(var Msg: TMessage);
     begin
       MessageBeep(0);
     end;

     ObjectWindows определяет    в    качестве    смещения,
задающего  диапазон используемых в уведомлениях управляющих
элементов сообщений, константу nf_First.


                  Уведомление порождающего объекта
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если управляющий элемент не  имеет  связанного  с  ним
интерфейсного объекта, или управляющий объект не определяет
реакции  на  конкретную  команду,  уведомляющие   сообщения
посылаются    вместо    объекта    управляющего    элемента
порождающему   окну   управляющего   элемента.   Так    как
порождающее  окно  должно  знать,  какой из его управляющих
элементов  вызвал   уведомление,   уведомляющее   сообщение
порождающему    окну    основывается    на   идентификаторе
управляющего элемента.

     Например, чтобы    ответить    на    уведомление     о
взаимодействиях  с  управляющим элементом с идентификатором
id_MyControl, вы можете определить метод следующим образом:

     type
       TMyWindow = object(TWindow)
          .
          .
          .
        procedure IDMyControl(var Msg: TMessage);
          virtual id_First + id_MyControl;
        end;

     procedure TMyWindow.IDMyControl(var Msg: TMessage);
     begin
       { реакция на сообщение }
     end;

     В качестве    смещения    в    диапазоне    сообщений,
используемых   для   реакции   на  уведомления  управляющих
элементов, ObjectWindows определяет константу id_First.

     Windows редко   определяет   реакцию   на   конкретные
управляющие элементы,  заданную по умолчанию.  Однако, если
вы хотите позаботиться о заданном по  умолчанию  поведении,
то   можете  вызвать  DefChildProc.  DefChildProc  работает
аналогично DefWndProc,  но  обрабатывает  вместо  сообщений
Windows уведомляющее сообщение порождающему объекту.

                    Уведомления управляющих
                элементов и порождающих объектов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Возможно, иногда  вам потребуется,  чтобы одновременно
на  некоторое  взаимодействие  пользователя  с  управляющим
элементом реагировали и управляющий элемент,  и порождающее
окно.  ObjectWindows также обеспечивает способ  реализовать
это.    Поскольку    уведомление    порождающего    объекта
предусматривает  реакцию   по   умолчанию,   когда   объект
управляющего элемента не определяет реакции на уведомление,
все,  что нужно сделать - это вызов реакции по умолчанию  в
дополнение реакции управляющего элемента.

     Например, с    учетом    приведенного   выше   объекта
TBeepButton вы можете также уведомлять порождающее  окно  с
помощью добавления вызова DefNotificationProc:

     procedure TBeepButton.BNClicked(var Msg: TMessage);
     begin
       MessageBeep(0);
       DefNotificationProc(Msg);
     end;

     Вызов DefNotificationProc    обеспечивает    получение
уведомляющего   сообщения    на    основе    идентификатора
порождающего   окна  управляющего  элемента,  как  если  бы
управляющий элемент вовсе не определял реакции.


              Определение ваших собственных сообщений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Windows резервирует  для  собственного   использования
1024  сообщения.  В  этот диапазон попадают все стандартные
сообщения.   Начало   диапазона   сообщений    определяется
константой    wm_User.    Чтобы    определить    сообщение,
используемое    окнами    вашей    программы,    определите
идентификатор     сообщения,    попадающий    в    диапазон
wm_User..wm_User+31744.

     Чтобы избежать конфликта со стандартными  сообщениями,
вам  следует  определить идентификаторы своих сообщений как
константы на основе wn_User.  Например,  в приложении,  где
требуется  три  определенных  пользователем  сообщения,  вы
можете описать их следующим образом:

     const
        wm_MyFirstMessage  = wm_User;
        wm_MySecondMessage = wm_User + 1;
        wm_MyThirdMessage  = wm_User + 2;

     Реакция на  ваши сообщения аналогично реакции на любое
другое сообщение:

     TCustomWindow = object(TWindow)
         .
         .
         .
       procedure WMMyFirstMessage(var Msg: TMessage);
           virtual wm_First + wm_MyFirstMessage

     Согласно общему  правилу,  определенные  пользователем
сообщения  следует  использовать  для  внутреннего   обмена
сообщения.  Если  вы  посылаете  определенное пользователем
сообщение другому  приложению,  нужно  убедиться,  что  это
другое  приложение  определяет  сообщение  также,  как  это
делается в коде  вашего  приложения.  Внешние  коммуникации
лучше обрабатываются с помощью динамического обмена данными
(DDE).


                         Передача сообщений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     До сих пор мы определяли реакцию на сообщения,  но  не
говорили   пока   о   том,   как   генерировать  сообщения.
Большинство сообщений Windows генерируются самой Windows  в
ответ  на  действия пользователя или системные события.  Но
ваша программа можете генерировать сообщения либо моделируя
действия   пользователя,  либо  манипулирую  элементами  на
экране.

     ObjectWindows уже   обеспечивает   для   вас   способы
передачи  многих  сообщений,  которые  в  противном  случае
пришлось бы передавать вручную. Например, общим случаем для
генерации   сообщений   является   работа   с   управляющим
элементами.  Чтобы добавить строку в блок  списка,  Windows
определяет   такие  сообщения  как  lb_AddString,  а  чтобы
отменить выбор кнопки с зависимой фиксацией или выбрать  ее
- bm_SetCheck. ObjectWindows определяет методы для объектов
управляющих      элементов      (TListBox.AddString       и
TCheckBox.SetCheck),  посылающие для вас эти сообщения, так
что вам даже не нужно думать об их использовании.

     Возможно вы  найдете,  что  для  большинства   функций
(которые в противном случае пришлось бы выполнять передачей
сообщений) уже существуют объектные методы.


                  Передача и отправление сообщений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Тем не менее,  иногда возникает необходимость передачи
сообщений в окна вашего приложения. Windows предусматривает
две  функции,  позволяющие  вам  генерировать  сообщения  -
SendMessage  и  PostMessage.  Основное  отличие  этих  двух
функций состоит в том,  что SendMessage  ожидает  обработки
сообщения  перед  возвратом.  PostMessage  просто добавляет
сообщение в очередь сообщений и возвращает управление.

     Имейте в виду,  что SendMessage, особенно при вызове в
методе реакции на сообщение, может вызвать бесконечный цикл
или клинч,  приводящие к  сбою  программ.  Вам  следует  не
только избегать очевидных циклов,  таких как методы реакции
на сообщения,  генерирующих то же  сообщение,  которое  его
вызывает,  но избегать также передачи сообщений с побочными
эффектами.   Например,   метод   Paint   объекта,   который
вызывается  в ответ на сообщения wm_Paint,  очевидно должен
явным  образом  посылать  самому  себе   другое   сообщение
wm_Paint.  Но  он  должен  также  избегать других действий,
дающих в результате другое сообщение wm_Paint,  посылаемое,
пока метод еще активен,  таких как изменение размеров окна,
запрещение окна  или  создание/уничтожение  перекрывающихся
окон.


                         Передача сообщения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для передачи сообщения требуется следующее:  описатель
окна-получателя,  номер  сообщения  и  параметры   Word   и
Longint.  В  приложении ObjectWindows описателем получателя
является  обычно  поле   HWindow   интерфейсного   объекта.
Идентификатор    сообщения    -   это   просто   константа,
идентифицирующая конкретное сообщение,  которое  вы  хотите
передать (такая как wm_More или em_SetTabStops).  Параметры
в зависимости от сообщения могут быть различными.

     Значение, возвращаемое SendMessage - это значение поля
Result в записи сообщения при завершении обработки.  Имейте
в виду,  что если вы вызываете наследуемый или используемый
по  умолчанию  метод  реакции  на сообщение,  ваше значение
может быть перезаписано.

     Windows с     помощью     SendMessage     обеспечивает
ограниченное средство циркулярной рассылки сообщений.  Если
вы в качестве описателя  окна,  в  которое  нужно  передать
сообщение,  зададите $FFFF, Windows посылает сообщения всем
всплывающим и перекрывающимся окнам в системе (не только  в
вашем приложении). Таким образом, вы не должны использовать
циркулярную рассылку сообщений, определяемых пользователем,
так  как  не  может быть уверены,  что другое приложение не
определило данное сообщение каким-то другим способом.


                       Отправление сообщения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Отправление сообщения полезно использовать,  если  вас
не  особенно  волнует,  когда должна последовать реакция на
сообщение,  или вам нужно избежать  циклов,  которые  может
вызвать SendMessage.  Если все, что вам нужно сделать - это
убедиться в передаче  сообщения,  и  вы  можете  продолжать
работу,  не  ожидая  реакции,  то  можете  вызывать функцию
PostMessage.  Ее  параметры  идентичны  параметрам  функции
SendMessage.   PostMessage   не  следует  использовать  для
передачи сообщений управляющим элементам.


              Передача сообщения управляющему элементу
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Возможно, единственным случаем,  когда вам потребуется
передать   сообщение   элементу   на  экране,  не  имеющему
соответствующего объекта,  является случай, когда вам нужно
взаимодействовать  с  управляющим  элементом  в  диалоговом
окне.  Проще   всего   для   этого   использовать   объекты
(управляющего элемента, диалогового блока или обоих).

     Если управляющий элемент имеет связанный с ним объект,
вы можете просто использовать для получения  идентификатора
управляющего элемента поле HWindow объекта. Если диалоговый
блок имеет связанный с ним объект,  вы можете вызвать метод
SendDlgItemMsg  объекта  диалогового  блока,  для  которого
задаются идентификатор управляющего элемента, идентификатор
сообщения   и   два   параметра  сообщения.  В  большинстве
приложений ObjectWindows для вас  доступен  любой  их  этих
подходов.

     Если по   каким-то  причинам  у  вас  нет  ни  объекта
диалогового  блока,  ни  доступного  объекта   управляющего
элемента, вы можете послать сообщение управляющему элементу
в  диалоговом  окне   с   помощью   функции   API   Windows
SendDlgItemMessage,   которая   воспринимает   в   качестве
параметров  описатель  диалогового   блока,   идентификатор
управляющего   элемента,   идентификатор  сообщения  и  два
параметра сообщения.


                        Диапазоны сообщений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Сообщение определяется полем message записи  сообщения
(16-битовое   значение).   Windows  резервирует  для  своих
собственных стандартных  сообщений  0..$03FF,  а  остальные
сообщения    до    $7FFF   резервируются   для   сообщений,
определенных пользователем. Диапазоны остальных сообщений в
ObjectWindows   подразделяются   на   диапазоны   команд  и
уведомлений (как показано в следующей таблице):

                     Диапазоны сообщений      Таблица 16.1
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДї
і          Диапазон                   і    Значения    і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
і  Сообщения, зарезервированные       і  $0000-$7FFF   і
і  для Windows.                       і                і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
і  Сообщения, определяемые            і  $0400-$8FFF   і
і  пользователем.                     і                і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
і  Уведомляющие сообщения             і  $8000-$8FFF   і
і  управляющих элементов.             і                і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
і  Зарезервированные в Windows        і  $8F00-$8FFF   і
і  уведомляющие сообщения             і                і
і  управляющих элементов.             і                і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
і  Уведомляющие сообщения             і  $9000-$9FFF   і
і  порождающего объекта.              і                і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
і  Зарезервированные в Windows        і  $9F00-$9FFF   і
і  уведомляющие сообщения             і                і
і  порождающего объекта.              і                і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
і  Командные сообщения.               і  $A000-$FFFF   і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
і  Команды, зарезервированные         і  $FF00-$FFFF   і
і  в ObjectWindows.                   і                і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДЩ


                     ЪДДДДДДДДДДДДДДДДДДДДДДДДї
 cm_Internal ($FF00) ГДДДДДДДДДДДДДДДДДДДДДДДДґ
                     і                        і
                     і                        і
                     і         Команды        і
                     і                        і
                     і                        і
    cm_First ($A000) ГДДДДДДДДДДДДДДДДДДДДДДДДґ
 nf_Internal ($9F00) ГДДДДДДДДДДДДДДДДДДДДДДДДґ
                     і                        і
                     і      Уведомления       і
                     і управляющих элементов  і
                     і                        і
    nf_First ($9000) ГДДДДДДДДДДДДДДДДДДДДДДДДґ
 id_Internal ($8F00) ГДДДДДДДДДДДДДДДДДДДДДДДДґ
                     і                        і
                     і      Уведомления       і
                     і  порождающих объектов  і
                     і                        і
    id_First ($8000) ГДДДДДДДДДДДДДДДДДДДДДДДДґ ї
                     і                        і і
                     і                        і і
                     і       Сообщения,       і і
                     і      определенные      і Г wm_Count
                     і      пользователем     і і ($8000)
                     і                        і і
                     і                        і і
     wm_User ($A000) ГДДДДДДДДДДДДДДДДДДДДДДДДґ Щ
                     і    Сообщения Windows   і
     wm_First($0000) АДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 16.1 Диапазоны сообщений и команд.

          Глава 17. Интерфейс с графическими устройствами
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Многим типам  приложений   Windows   для   организации
полного  интерфейса  пользователя нужны только окна,  блоки
диалога и управляющие элементы.  Но  некоторым  приложениям
(например,    программами   рисования   и   манипулирования
изображениями) требуется наличие  графических  средств  для
заполнения  окон.  Эта  графика  может  быть в форме линий,
форм, текста и побитовых образов.

     Для предоставления       приложениям       графических
функциональных  возможностей  Windows  имеет набор функций,
называемый интерфейсом с графическим устройством - GDI. GDI
можно  представить  себе  как  графическую машину,  которую
используют   приложения   Windows   для    отображения    и
манипулирования графикой.  Функции GDI предоставляют вашему
приложению возможности рисования,  которые  не  зависят  от
используемого  дисплея.  Например,  вы  можете использовать
одни и те же функции для организации вывода на дисплей EGA,
на дисплей VGA и даже на принтер PostScript.

     Аппаратная независимость       реализуется       через
использование  драйверов   устройств,   которые   переводят
функции   GDI   в   команды,   воспринимаемые  используемым
устройством  вывода.  Это  означает,  что  вам   не   нужно
беспокоиться  о  том,  как конкретное устройство работает с
графическим  образом.  Вы  сообщаете  драйверу,  что  нужно
что-то сделать, и он работает с устройством как нужно.

                    Запись на устройство вывода
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В отличие от  традиционных  графических  программ  DOS
программы  Windows  никогда не выводят элементы изображения
непосредственно на экран или на принтер,  а записывают их в
логическую   сущность,   называемую   контекстом   дисплея.
Контекст дисплея - это виртуальная поверхность с  присущими
ей атрибутами,  такими как перо,  кисть,  шрифт, цвет фона,
цвет текста  и  текущая  позиция.  Для  вашего  приложения,
независимо от того, какое это на самом деле устройство, все
контексты устройства выглядят аналогично.

     Когда вы  вызываете  функции  GDI  для   рисования   в
контексте  устройства,  связанный с этим контекстом драйвер
устройства    переводит    действия    по    рисованию    в
соответствующие    команды.   Эти   команды   воспроизводят
насколько возможно точно  действия  рисования  на  дисплее,
независимо  от  возможностей самого дисплея.  Дисплей может
быть монохромным экраном низкого разрешения или  экраном  с
четырьмя миллионами цветовых оттенков.

     Контекст дисплея  можно представить себе как холст для
рисования.  Окно это - картинка,  включающая рамку.  Вместо
рисования  на  картине в рамке вы рисуете на холсте,  а уже
затем устанавливаете его  в  рамку.  Аналогично  этому,  вы
рисуете в контексте дисплея окна. Контекст дисплея обладает
рядом инструментов  рисования,  например,  ручки,  кисти  и
шрифты. Контекст дисплея - это управляемый Windows элемент,
похожий на элемент окна с  тем  исключением,  что  контекст
дисплея не имеет соответствующего элемента ObjectWindows.

     Нужно помнить   о   том,   что   контекст   устройства
представляет собой только часть устройства,  на котором  вы
реально  рисуете.  Хотя  вы  можете  рассматривать  вывод в
терминах всего окна  (рамки,  меню,  области  клиента)  или
печатаемой страницы,  контекст устройства охватывает только
ту часть,  где  вы  рисуете  -  область  клиента  окна  или
печатаемую часть страницы.

     Контекст устройства - это элемент, управляемый Windows
(аналогично оконному элементу,  только контекст  устройства
не имеет соответствующего объекта ObjectWindows).

                Чем отличаются контексты устройства?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для областей   клиента   окна   Windows   обеспечивают
специальные  контексты  устройства,  называемые контекстами
дисплея. Вместо представления самого устройства, такого как
экран   или   принтер,   контекст   дисплея  позволяет  вам
интерпретировать область клиента окна как целое устройство.

     На практике  контекст   дисплея   вам   не   требуется
интерпретировать   как-то   иначе,   чем   другой  контекст
устройства. Он позволяет вам работать так, как если бы ваше
окно   было   целым  устройством,  так  что  вам  не  нужно
беспокоиться о смещении позиции на экране и т.д.

                   Управление контекстом дисплея
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для организации  рисования в контексте дисплея сначала
нужно  получить  контекст   дисплея   для   нужного   окна.
Требования  к  памяти  со  стороны  контекста дисплея очень
велики,  поэтому  можно  одновременно  организовать  доступ
только  к  пяти контекстам дисплея в каждом сеансе Windows.
Это значит,  что каждое окно  не  может  поддерживать  свой
собственный  контекст  дисплея.  Оно  получает его только в
случае необходимости и освобождает при первой  возможности.
Это  может  несколько  обескуражить  вас,  но  вы не можете
управлять атрибутами контекста дисплея.  Другое окно и даже
другое приложение может сменить атрибуты контекста дисплея.
Кроме того,  средства рисования не являются  частью  памяти
контекста  дисплея.  Они  могут  быть  выбраны  в  контекст
дисплея каждый раз при его получении.


                    Работа с контекстом дисплея
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Обычно нужно  определять  поле  оконного  объекта  для
записи  описателя  текущего  контекста дисплея,  аналогично
тому, как в HWindow сохраняется описатель окна:

     type
       TMyWindows = object(TWindow)
          TheDC: HDC;
           .
           .
           .
       end;

     Чтобы получить для  окна  контекст  дисплея,  вызовите
функцию Windows GetDC:

     TheDC := GetDC(HWindow);

     Затем вы   можете  выполнить  операцию  изображения  в
контексте  дисплея.  Вы   можете   использовать   описатель
контекста дисплея в графических функциях Windows:

     LineTo(TheDC, Msg.LParamLo, Msg.LParamHi);

     Как только  вы  закончите работу с контекстом дисплея,
освободите его с помощью вызова функции ReleaseDC:

     ReleaseDC(HWindow, TheDC);

     Не вызывайте GetDC в строке дважды,  не включив  между
вызовами  вызов  ReleaseDC.  В  итоге  это  приведет к сбою
системы при работе программы,  так как  она  исчерпает  все
доступные контексты дисплея.


               Что содержится в контексте устройства?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Контекст устройства   содержит  набор  изобразительных
средств,  таких как перья,  кисти  и  шрифты.  Реально  эти
инструментальные   средства   не   существуют.  Они  просто
представляют  собой   удобный   способ   предположений   об
определенной группе изобразительных характеристик.

     Перо, например,     это    просто    удобный    способ
интерпретации   характеристик    линий    на    устройстве.
Графическая   линия   между   двумя   точками   имеет   три
характеристики:  ширину, цвет и стиль (например, пунктирная
линия   и   линия   из   точек),  которые  совместно  можно
рассматривать   как   "перо".   Эти    логические    группы
изобразительных  характеристик значительно упрощают графику
в Windows.

     Хотя обычно вам не нужно  будет  изменять  большинство
атрибутов  контекста дисплея,  важно по крайней мере знать,
что  в  нем  содержится.  Данный  раздел  кратко  описывает
некоторые  элементы  контекста  дисплея,  включая побитовые
отображения,  цвета,  области и  изобразительные  средства.
Некоторые  из этих тем также рассматриваются более подробно
в некоторых других разделах данной главы.


                         Побитовая графика
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Действительная поверхность      контекста      дисплея
называется   побитовым   отображением  (битовым  массивом).
Побитовые  отображения  представляют  конфигурацию   памяти
конкретного устройства.  Следовательно, они зависят от вида
адресуемого устройства.  Это  создает  проблему,  поскольку
охраненные  для  одного  устройства  побитовые  отображения
будут несовместимы с  другим  устройством.  GDI  имеет  ряд
средств    для    разрешения    этой    проблемы,   включая
аппаратно-независимые   побитовые   отображения.    Имеются
следующие    функции   GDI,   которые   создают   побитовые
отображения:  CreateCompatibleDC,  CreateCompatibleBitmap и
CreateDIBitmap.    Имеются   следующие   функции   GDI   по
манипулированию    побитовыми    отображениями:     BitBlt,
StretchBlt, StretchDIBits и SetDIBitsToDevice.


                      Изобразительные средства
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы выполнить     большую     часть     фактического
изображения,    контекст     дисплея     использует     три
инструментальных средства: перо, кисть и шрифт.

                              Перья

     Перо используется для изображения линий, дуг и ломаных
линий,   представляющих   собой   множественные    линейные
сегменты.  Атрибуты пера включают в себя его цвет, ширину и
стиль (например, пунктирная линия или линия из точек).

                              Кисти

     Кисть используется при закраске замкнутых фигур, таких
как  прямоугольники,  прямоугольники  с  округлыми краями и
многоугольники.   Функции,   рисующие   непрерывные   формы
используют  перо  для  вычерчивания  границ,  а кисть - для
закраски внутренней области.  Существуют четыре типа кистей
-   непрерывные,   с   засечками,   с  образцом  побитового
отображения  и  с   независимым   от   устройств   образцом
побитового отображения.

                             Шрифты

     Инструментальное средство   шрифта   используется  при
изображения в контексте дисплея текста.  Оно задаете высоту
шрифта, его ширину, семейство и имя гарнитуры.

     Все три   инструментальных   средства  используют  для
заполнения  пробелов  атрибут  фонового   цвета   контекста
дисплея.    Изобразительные    инструментальные    средства
подробнее освещаются в разделе  "Изобразительные  средства"
данной главы.


                                Цвет
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Цвет, который  устройство  использует  для  рисования,
хранится в цветовой палитре. Если вы желаете добавить цвет,
которого  нет  в  цветовой палитре,  то его можно добавить.
Более часто вы будете  настраивать  драйвер  устройства  на
аппроксимацию   нужного   цвета   путем  смешивания  цветов
палитры.  Работа  с  цветовой   палитрой   более   подробно
рассматривается   в  разделе  данной  главы  "Использование
цветовой палитры".


                         Режимы отображения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Очень трудно  выбрать  устройство   рисования,   когда
заранее  неизвестно,  какое устройство будет использоваться
для  отображения.  Большинство  приложений  игнорируют  эту
проблему и предполагают, что вполне удовлетворительно будет
работать  единица  рисования  по  умолчанию  (один  элемент
изображения).  Однако,  некоторые приложения требуют, чтобы
отображение точно воспроизводило  размеры  нужного  образа.
Для   таких   приложений  GDI  допускает  различные  режимы
отображения, некоторые из которых не зависят от аппаратуры.
Каждый   из   методов   распределения  имеет  свою  единицу
размерности  и  систему  координатной   ориентации.   Режим
распределения по умолчанию устанавливает начало координат в
левом  верхнем  углу  контекста  дисплея  с   положительным
направлением  оси X вправо и положительным направлением оси
Y   вниз.   Каждый   контекст   дисплея   имеет    атрибуты
распределения для интерпретации задаваемых вами координат.

     Иногда нужно   транслировать   логические  координаты,
используемые вами для рисования,  в  физические  координаты
побитового  отображения.  Для большинства приложений начало
координат для экрана - это его левый верхний угол,  но  для
окна  началом  координат  будет  левый верхний угол области
клиента.  Некоторые  окна  прокручивают  свою   поверхность
клиента так,  что начало координат не будет даже находиться
в области клиента.  Некоторые функции GDI работают только в
конкретной   системе   координат,   поэтому  преобразование
координат просто необходимо.  В GDI имеется ряд функций для
подобного      пересчета     координат:     ScreenToClient,
ClientToScreen, DPToLP и LPToDP.


                         Обрезание областей
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для предотвращения  рисования  вне  заданной   области
каждый  контекст  дисплея имеет атрибут области вырезанного
изображения.  Область вырезанного  изображения  может  быть
сложным  многоугольником  или  эллипсом,  внутри которого и
может происходить действительное рисование  на  виртуальной
поверхности  контекста дисплея.  Для большинства приложений
выделяемая по  умолчанию  область  вырезанного  изображения
будет  вполне  достаточной.  Изменять  эту область придется
только  для  приложений,  которые  воспроизводят  некоторые
специальные визуальные эффекты.


                Инструментальные средства рисования
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Контекст дисплея  управляет  отображением  графики  на
экране.  Для  иного  способа  отображения   графики   можно
изменить   инструментальные  средства,  с  помощью  которых
создается изображение.  Атрибуты  инструментальных  средств
задают   проявление  изображений  с  помощью  функций  GDI,
например,  LineTo, Rectange и TextOut. Перья задают внешний
вид линий,  кисти задают внешний вид закрашенных областей и
шрифт задает внешний вид изображаемого текста.

     Для задания атрибутов  инструмента  программа  Windows
выбирает   логический   инструмент   в   контекст  дисплея.
Логический  инструмент  создается  вашей  программой  путем
заполнения  полей определенной записи,  TLogPen,  TLogBrush
или  TLogFont.  Текущий  инструмент   -   это   инструмент,
определенный в Windows, представляющий самый общие варианты
атрибута,  например,  непрерывное черное перо,  серая кисть
или системный шрифт.


                 Основные инструментальные средства
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Основные инструментальные  средства создаются функцией
GDI GetStockObject. Например:

     var
       TheBrush: HBrush
     begin
       TheBrush:=GetStockObject(LtGray_Brush);
        .
        .
        .
     end;

где LtGray_Brush  -  это  целая  константа,  определенная в
модуле  WinTypes  в  ObjectWindows.  Приведем  список  всех
имеющихся констант основного инструментального средства:

           Основные инструменты рисования      Таблица 17.1
ЪДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДї
і  Кисти      і     Перья        і      Шрифты            і
ГДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
іWhite_Brush  і   White_Pen      і    OEM_Fixed_Font      і
іLtGray_Brush і   Black_Pen      і    ANSI_Fixed_Font     і
іGray_Brush   і   Null_Pen       і    ANSI_Var_Font       і
іDkGray_Brush і                  і    System_Font         і
іBlack_Brush  і                  і    Device_Default_Font і
іNull_Brush   і                  і    System_Fixed_Font   і
іHoolow_Brush і                  і                        і
АДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДЩ

     В отличие  от  логических   инструментальных   средств
основные   инструментальные  средства  не  удаляются  после
использования.


                Логические инструментальные средства
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Записи логических инструментов,  TLogPen,  TLogBrush и
TLogFont,  содержат  поля  для  хранения  каждого  атрибута
инструмента.  Например, TLogPen.lopnColor содержит значение
цвета ручки.  Каждый тип записи определяет свой собственный
набор атрибутов, соответствующий типу инструмента.


                          Логические перья
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вы можете создавать логические перья с помощью функций
Windows CreatePen или CreatePenInderect. Например:

     ThePen := CreatePen(ps_Dot, 3, RGB(0, 0, 210));
     ThePen := CreatePenInderect(@ALogPen);

     Определение записи TLogPen имеет следующий вид:

     TLogPen = record
        lopnStyle: Word;
        lopnWidth: TPoint;
        lopnColor: Longint;
     end;

     Поле стиля,  lopnStyle,  содержит константу,  задающую
стиль линии.


ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Константа                     Результат
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
    PS_SOLID            ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
    PS_DASH             -------------------------------
    PS_DOT              ...............................
    PS_DASHDOT          .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
    PS_DASHDOTDOT       -..-..-..-..-..-..-..-..-..-..-
    PS_NULL
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                      Рис.17.1 Стили линий для пера.

     Поле толщины,  lopnWidth, содержит точку, координата x
которой задает толщину линии в координатах  устройства.  На
экране  VGA,  если  задано значение 0,  то будет рисоваться
линия  толщиной  в  один  элемент   изображения.   Значение
координаты y игнорируется.  Поле цвета, lopnColor, содержит
значение   Longint,   байты   которого   задают    величины
интенсивности   основных   цветов   (красного,  зеленого  и
синего),  смешение которых и  дает  нужный  цвет.  Значение
lopnColor  должно  иметь  вид $00bbggrr,  где bb - значение
синего цвета, gg - значение зеленого цвета, а rr - значение
красного   цвета.   Доступный  диапазон  интенсивности  для
каждого первичного цвета от 0 до 255,  или от  0  до  FF  в
шестнадцатиричном исчислении.  Следующая таблица показывает
некоторые примеры значений цвета:

                     Примеры значений цвета
                                    Таблица 17.2
                 ЪДДДДДДДДДДДДДДВДДДДДДДДДДДДДДї
                 і   Значение   і   Цвет       і
                 ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДґ
                 і  $00000000   і  черный      і
                 і  $00FFFFFF   і  белый       і
                 і  $000000FF   і  красный     і
                 і  $0000FF00   і  зеленый     і
                 і  $00FF0000   і  синий       і
                 і  $00808080   і  серый       і
                 АДДДДДДДДДДДДДДБДДДДДДДДДДДДДДЩ

     В качестве   альтернативы  для  воспроизведения  цвета
можно использовать функцию RGB. RGB(0,0,0) возвратит черный
цвет, RGB(255,0,0) возвратит красный и т.д.



                          Логические кисти
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вы можете создавать логические кисти с помощью функций
Windows        CreateHatchBrush,        CreatePatternBrush,
CreateDIBPatternBrush или CreateBrushInderect. Например:

TheBrush := CreateHatchBrush(hs_Vertical, RGB(0, 255, 0));
TheBrush := CreateBrushInderect(@ALogBrush);

Определение записи TLogBrush имеет следующий вид:

TLogBrush = record
  lbStyle: Word;
  lbColor: Longint;
  lbHatch: Integer;
end;

     Поле стиля,   lbStyle,  содержит  константы,  задающие
стиль кисти:

     * bs_DIBPattern указывает,  что  образец  кисти  задан
       аппаратно-независимым побитовым отображением.

     * bs_Hatched   задает  один  из  заранее  определенных
       образцов штриховки (см. lbHatch).

     * bs_Hollow - это пустая кисть.

     * bs_Pattern использует левый  верхний  угол  8  на  8
       элементов побитового отображения,  которое находится
       в этот момент в памяти.

     * bs_Solid - это непрерывная кисть.

     Поле lbColor  содержит  значение   цвета,   аналогично
записи  TLogPen.  Это  поле игнорируется кистями со стилями
bs_Hollow и bs_Pattern.

     Поле lbHatch  содержит   целую   константу,   задающую
образец  штриховки  для  кисти  со стилем bs_Hatched.  Если
стиль  bs_DIBPattern,   то   lbHatch   содержит   описатель
побитового отображения.


ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
  Константа                      Результат
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                  //////////////////////////////////////
HS_BDIAGONAL      //////////////////////////////////////
                  //////////////////////////////////////

                  ++++++++++++++++++++++++++++++++++++++
HS_CROSS          ++++++++++++++++++++++++++++++++++++++
                  ++++++++++++++++++++++++++++++++++++++

                  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
HS_DIAGCROSS      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
                  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

                  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
HS_FDIAGONAL      \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
                  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

                  ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
HS_HORIZONTAL     ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                  ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                  іііііііііііііііііііііііііііііііііііііі
HS_VERTICAL       іііііііііііііііііііііііііііііііііііііі
                  іііііііііііііііііііііііііііііііііііііі

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Рис. 17.2 Стили штриховки для кисти.


                         Логические шрифты
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вы можете  создавать  логические  шрифты   с   помощью
функций Windows CreateFont или CreateFontInderect.

     Определение записи TLogBrush следующее:

     TLogFont = record
         lfHight: Integer;
         lfWidht: Integer;
         lfEscapement: Integer;
         lfOrientation: Integer;
         lfWeight: Integer;
         lfItalic: Byte;
         lfUnderline: Byte;
         lfStrikeOut: Byte;
         lfCharSet: Byte;
         lfOutPrecision: Byte;
         lfClipPrecision: Byte;
         lfQuality: Byte;
         lfPitchAndFamily: Byte;
         lfFaceName: array[0..lf_FaceSize - 1] of Byte;
     end;

     При использовании  TLogFont  для  создания  шрифта  вы
задаете атрибуты нужного вам шрифта. Однако, ваша программа
не  использует  эту  информацию  для  генерации  шрифта  на
экране. Вместо этого она отображает запрос экранного шрифта
в текущий экранный шрифт сеанса Windows.

     Поле lfHight задает необходимую высоту шрифта. Нулевое
значение  устанавливает размер по умолчанию.  Положительное
значение  есть  высота  элемента  в  логических   единицах.
Отрицательное значение воспринимается как положительное.

     Поле lfWidht  задает  нужную  ширину  букв  в единицах
устройства.  Если задан ноль, то коэффициент относительного
удлинения сохраняется.

     Для поворачиваемого    текста    lfEscapement   задает
значение в десятых долях градуса, на которое поворачивается
текст   против   часовой   стрелки.   lfOrientation  делает
аналогичный поворот каждого символа.

     Параметр lfWeight  задает  нужный  вес   символов.   В
качестве  значений  можно  использовать константы fw_Light,
fw_Normal, fw_Bold и fw_DontCare.

     Для трех атрибутов шрифта -  lfItalic,  lfUnderline  и
lfStrikeOut - нужно задать ненулевые значения.

     В поле  lfCharSet  требуется  задать  конкретный набор
символов,  ANSI_CharSet,  OEM_CharSet  или  Symbol_CharSet.
Набор  символов ANSI содержится в "Руководстве пользователя
по Microsoft Windows", в Приложении B. OEM_CharSet является
системно-зависимым.

     Поле lfOutPrecision   задает,  как  точно  создаваемый
Windows шрифт должен соответствовать запросам на размеры  и
позиционирование.    Значение    поля    по   умолчанию   -
Out_Default_Precis.  Поле  lfClipPrecision  задает   способ
рассмотрения  частично  видимых символов.  Значение поля по
умолчанию Clip_Default_Precis.

     Поле lfQuality показывает  как  точно  предоставляемый
Windows  шрифт  соответствует запрошенным атрибутам шрифта.
Может   быть    установлено    значение    Default_Quality,
Draft_Quality или Proof_Quality. Для значения Proof_Quality
жирные,  подчеркнутые,  наклонные   шрифты   и   шрифты   с
надпечаткой   синтезируются,   даже   если   их  нет.  Поле
lfPitchAndFamily задает шаг и семейство шрифта.  Оно  может
быть  результатом  логической  операции or между константой
шага и константой семейства.

           Константы шага и семейства шрифта  Таблица 17.3
      ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
      і  Константы шага     і     Константы семейства    і
      ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
      і   Default_Pitch     і      ff_Modern             і
      і   Fixed_Pitch       і      ff_Roman              і
      і   Variable_Pitch    і      ff_Script             і
      і                     і      ff_Swiss              і
      і                     і      ff_Decorative         і
      і                     і      ff_DontCare           і
      АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     И, наконец,  lfFaceName - это строка,  которая  задает
запрошенный вид букв.  Если задано значение 0,  то вид букв
будет  строиться  на  основании   значений   других   полей
TLogFont.   Приведем  несколько  примеров  исходного  кода,
определяющего записи TLogFont:

     procedure MyWindow.MakeFont;
     var
       MyLogFont: TLogFont;
     begin
       with MyLogFont do
       begin
         lfHight := 30;
         lfWidht := 0;
         lfEscapement := 0;
         lfOrientation := 0;
         lfWeight := fw_Bold;
         lfItalic := 0;
         lfUnderline := 0;
         lfStrikeOut := 0;
         lfCharSet := ANSI_CharSet;
         lfOutPrecision := Out_Default_Precis;
         lfClipPrecision := Clip_Default_Precis;
         lfQuality := Default_Quality;
         lfPitchAndFamily := Variable_Pitch or ff_Swiss;
         StrCopy(@FaceName, 'Helv');
      end;
      TheFont := CreateFontInderect(@MyLogFont);
     end;

     procedure MyWindow.MakeFont;
     var
       MyLogFont: TLogFont;
     begin
       with MyLogFont do
       begin
         lfHight := 10;
         lfWidht := 0;
         lfEscapement := 0;
         lfOrientation := 0;
         lfWeight := fw_Normal;
         lfItalic := Ord(True);
         lfUnderline := Ord(True);
         lfStrikeOut := 0;
         lfCharSet := ANSI_CharSet;
         lfOutPrecision := Out_Default_Precis;
         lfClipPrecision := Clip_Default_Precis;
         lfQuality := Default_Quality;
         lfPitchAndFamily := Fixed_Pitch or ff_DontCare;
         StrCopy(@FaceName, 'Courier');
      end;
      TheFont := CreateFontInderect(@MyLogFont);
     end;

     procedure MyWindow.MakeFont;
     var
       MyLogFont: TLogFont;
     begin
       with MyLogFont do
       begin
          lfHight:=30;
          lfWidht:=0;
          lfEscapement:=0;
          lfOrientation:=0;
          lfWeight:=fw_Normal;
          lfItalic:=0;
          lfUnderline:=0;
          lfStrikeOut:=0;
          lfCharSet:=Symbol_CharSet;
          lfOutPrecision:=Out_Default_Precis;
          lfClipPrecision:=Clip_Default_Precis;
          lfQuality:=Proof_Quality;
          lfPitchAndFamily:=Fixed_Pitch or ff_Roman;
          StrCopy(@FaceName, 'Rmn');
      end;
        TheFont:=CreateFontInderect(@MyLogFont);
     end;



  Использование изобразительных инструментальных средств
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Контекст дисплея  позволяет  вам  рисовать  в  окне и,
кроме  этого,   он   содержит   инструментальные   средства
рисования:  перья,  кисти,  шрифты  и  палитры,  которые вы
используете  для  рисования  текста  и   изображений.   При
рисовании  линии  в  контексте  дисплея  линия выводится со
следующими   атрибутами   текущего   пера:   цвет,    стиль
(непрерывная,   пунктирная   и   т.п.)   и   толщина.   При
закрашивании области она выводится со следующими атрибутами
текущей  кисти:  образец  и  цвет.  При  рисовании текста в
контексте  дисплея  он  выведется  с  атрибутами   текущего
шрифта:  шрифт (Modern, Roman, Swiss и т.п.), размер, стиль
(наклонный,  жирный и т.п.). Палитра содержит набор текущих
доступных цветов.

     Контекст дисплея   содержит  по  одному  типу  каждого
инструментального  средства  рисования.  Вновь   полученный
контекст  дисплея  содержит набор инструментальных средств,
используемых по умолчанию:  тонкое черное перо, непрерывная
черная кисть,  системный шрифт и палитра по умолчанию. Если
этот  набор  вас  устраивает,  то  нет  необходимости   его
изменять.

     Для изменения   набора   инструментальных  средств  по
умолчанию,  нужно создать новый инструментальный элемент  и
выбрать его в контекст дисплея.  Например, при выборе новой
ручки старая автоматически удаляется.  Мы  рекомендуем  вам
сохранять   старые  инструментальные  средства  и  повторно
устанавливать их после окончания использования новых:

     var
        NewPen, OldPen: HPen;
        TheDC: HDC;
     begin
        { задать ширину пера 10 }
        NewPen := CreatePen(ps_Solid, 10, RGB(0, 0, 0));
        TheDC := GetDC(AWindow^.HWindow);
        OldPen := SelectObject(TheDC, NewPen);
        { выполнить черчение }
        SelectObject(TheDC, OldPen);
        ReleaseDC(AWindow^.HWindow, TheDC);
        DeleteObject(NewPen);
     end;

     Как показано  в  данном  примере,   новый   инструмент
рисования  должен  быть  создан,  а  затем удален.  Подобно
контексту дисплея, элементы хранятся в памяти Windows. Если
их не удалить,  это приводит к потерям памяти и возможности
возникновения сбоя.  Как и для контекста дисплея, вы должны
хранить  описатели  инструментальных  средств  рисования  в
переменных типа HPen, HBrush, HFont и HPalette.

     Функция Windows DeleteObject удаляет  инструментальные
средства  рисования из памяти Windows.  Ни в коем случае не
удаляйте  инструментальные  средства   рисования,   которые
выбраны в данный момент в контекст дисплея!

     Контекст дисплея   может   хранить  только  по  одному
инструменту рисования каждого типа в данный момент времени,
поэтому   нужно   отслеживать   доступные  инструментальные
средства  отображения.  Очень  важно  удалить  их  все   до
завершения  работы  вашего  приложения.  Один  из  методов,
(использован в примере Главы 2) состоит в определении  поля
объекта   окна  с  именем  ThePen  для  хранения  описателя
текущего пера.  Когда  пользователь  выбирает  новый  стиль
пера,   создается   новое   перо,   а   старое   удаляется.
Следовательно,  окончательное перо  будет  удалено  методом
основного   окна  CanClose.  Вам  не  нужно  удалять  набор
инструментальных  средств  по  умолчанию,  поставляемый  во
вновь полученном контексте дисплея.

     Есть два   способа   создания  новых  инструментальных
средств  рисования.  Самый   простой   способ   состоит   в
использовании  существующего  альтернативного  инструмента,
называемого   основным   или   опорным.   Список   основных
инструментальных средств приведен в Таблице 17.1.

     Для установки  основного  инструментального средства в
объекте контекста дисплея используются методы  SetStockPen,
SetStockBrush, SetStockFont и SetStockPalette. Например:

     ThePen:=GetStockObject(Black_Pen);

     Не удаляйте  основные  инструменты  из памяти Windows,
поскольку  вы  будете  настраивать  их.  Иногда   возникает
ситуация,  когда нет основного инструмента, который имел бы
нужный  вам   атрибут.   Например,   все   основные   перья
воспроизводят тонкие линии, а вам требуется толстая. В этом
случае   имеется   два   способа    создания    настроенных
инструментальных  средств рисования.  Один способ состоит в
вызове    функций    Windows     CreatePen,     CreateFont,
CreateSolidBrush  или  CreateDIBPatternBrush.  Эти  функции
используют параметры,  которые описывают нужный инструмент,
и возвращают описатель инструментального средства,  который
используется в вызовах SelectObject.

     Другой способ  создания  настроенных  инструментальных
средств состоит в построении описания атрибутов логического
инструмента.  Логический инструмент реализуется структурами
данных Windows TLogPen,  TLogBrush, TLogFont и TLogPalette.
Например,  TLogPen имеет поля для хранения толщины цвета  и
стиля.    После    создания   записи   данных   логического
инструмента,  она  передается  в   качестве   параметра   в
CreatePenInderect,  CreateBrushInderect, CreateFontInderect
или  CreatePalette.  Эти   функции   возвращают   описатели
инструментального  средства которые могут быть использованы
в вызовах SelectObject.  В данном  примере  устанавливается
синее перо для изображения в контексте дисплея окна:

     procedure SampleWindow.ChangePenToBlue;
     var
        ALogPen: TLogPen;
        ThePen: HPen;
     begin
        ALogPen.lopnColor:=RGB(0, 0, 255);
        ALogPen.lopnStyle:=ps_Solid;
        ALogPen.lopnWidth.X:=0;
        ALogPen.lopnWidth.Y:=0;
        ThePen:=CreatePenInderect(@ALogPen);
        SelectObject(TheDC, ThePen);
     end;

                    Отображение графики в окнах
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Рисование -  это  процесс  отображения контекста окна.
Приложение Windows отвечает за рисование его  окон  при  их
первом   появлении   и   их   изменении,   например,  после
восстановления  из  пиктограммы  или   перекрытия   другими
окнами.  Windows  не обеспечивает автоматического рисования
контекста окон,  она только  информирует  окно,  когда  ему
нужно   нарисовать  себя.  Данный  раздел  показывает,  как
рисовать в окне,  объясняет механизм рисования и  объясняет
использование контекста дисплея.

     В данном   разделе   термин  "рисование"  относится  к
отображению графики в окне.  Рисование - это автоматическое
отображение  графики  при  первом  появлении  или изменении
окна.  С другой стороны рисование - это процесс создания  и
отображения  специфических  изображений  в  другие  моменты
времени под управлением программы.  Под графикой понимается
как текст,  так и элементы изображения, например, побитовые
отображения и прямоугольники.


                          Изображение окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда возникает  необходимость  нарисовать  окно,  оно
становится запрещенным.  Это значит что изображение дисплея
не соответствует действительности и должно  быть  изменено.
Это  происходит  в момент первоначального отображения окна,
восстановления из пиктограммы или  удаления  другого  окна,
которое  перекрывало  часть  данного  окна.  Во  всех  этих
случаях     Windows     посылает     сообщение     wm_Paint
соответствующему  приложению.  Это  сообщение автоматически
вызывает метод Paint вашего окна. Один из параметров Paint,
PaintDC,   представляет  собой  контекст  дисплея,  который
используется для рисования.

     Метод TWindow  Paint  ничего  не   рисует,   поскольку
объекты  TWindow  не  имеют  графики для рисования.  В типе
вашего окна определим метод Paint,  который будет  вызывать
методы и функции, изображающие в окне текст и графику.

     Единственное, что   вы  можете  сделать  с  контекстом
дисплея,  это выбрать в него  новый  инструмент  рисования,
например,  перья  других  цветов или кисти других образцов.
Вам придется указать эти инструменты  в  контексте  дисплея
рисования вашего метода Paint.

     После завершения  работы метода Paint контекст дисплея
рисования автоматически освобождается.

                         Стратегия графики
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Метод Paint отвечает за рисование текущего содержимого
окна в любой момент времени, включая первое появление этого
окна.  Следовательно, метод Paint должен уметь рисовать все
"постоянные" изображения окна.  Кроме того, он должен уметь
восстанавливать любые изображения, добавленные в окно после
его   первого   появления.   Для    воспроизведения    этой
"динамической"  графики  метод  Paint должен иметь доступ к
инструкциям или данным,  с  помощью  которых  было  создано
изображение.

     Вы можете  выбрать  один  из двух возможных вариантов.
Первый подход состоит в  выделении  нескольких  графических
методов  и при динамическом рисовании вызывать их из метода
Paint. Другой подход, показанный в примере Главы 3, состоит
в  хранении  данных,  относящихся  к графическому контексту
окна,  в  полях  объекта  этого  окна.  Эти  данные   могут
включать,   например,   координаты,   формулы  и  побитовые
распределения.  Затем   метод   Paint   повторно   вызывает
графические функции,  которые нужны для преобразования этих
данных в изображения.

     Используя эти стратегии и способность объекта  хранить
свои  собственные  данные и функции вы можете разрабатывать
очень развитые и впечатляющие графические приложения.


                         Рисование в окнах
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для рисования любого текста или изображения в  объекте
окна   сначала   нужно  получить  контекст  дисплея.  После
рисования  контекст  дисплея  нужно  освободить.  (В  одном
сеансе  Windows  доступны  только  пять элементов контекста
дисплея.)  Вы  можете  использовать   описатель   контекста
дисплея  в  качестве  аргумента  любой  графической функции
Windows.

                 Вызов графических функций окна

     Одно из правил GDI  состоит  в  том,  что  для  работы
функций  необходимо  в качестве аргумента задавать контекст
дисплея.  Обычно вы будете вызывать эти функции из  методов
типа окна. Например, TextOut - это функция рисования текста
на контексте дисплея в заданном месте:

     TheDC := GetDC(HWindow);
     TextOut(TheDC, 50, 50, 'Sample Text', 11);
     ReleaseDC(HWindow, TheDC);


                      Графические функции GDI
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Данный раздел описывает различные вызовы API,  которые
вы можете использовать для рисования изображений в окне.


                     Функции изображения текста
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Функция рисования   текста  использует  для  рисования
заданный текущий шрифт контекста дисплея.  Функция  TextOut
рисует текст в заданной точке.  TextOut выравнивает текст в
зависимости  от  текущих  значений  флагов   форматирования
текста. По умолчанию происходит выравнивание слева. Текущий
метод  выравнивания  можно  посмотреть  с  помощью  функции
GetTextAlign и установить с помощью функции SetTextAlign.

     Функция TextOut - это самая часто используемая функция
рисования  текста.  Используя  установленные  по  умолчанию
флаги  форматирования  текста,  данный  метод  Paint рисует
выравненный  слева  массив  символов,  левый  верхний  угол
которого имеет координаты (10,15).

     procedure TMyWindow.Paint(PaintDC: HDC;
                             var PaintINfo: TPaintStruct);
     var
        MyTextString: array[0..20] of Char;
     begin
        StrCopy(MyTextString, 'Hello, World');
        TextOut(PaintDC, 10, 15, MyTextString,
                               StrLen(MyTextString));
     end;

     ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     і
     і       (10, 15)
     і    * Hello Word
     і
     і

     Рис. 17.3 Результат выполнения функции TextOut.


                      Функции рисования линий
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Функции рисования  линии  используют   для   рисования
заданное текущее перо контекста дисплея.  Большинство линий
рисуется с использованием  функций  MoveTo  и  LineTo.  Эти
функции воздействуют на атрибут контекста дисплея - текущую
позицию.  Если использовать аналогию с карандашом и  листом
бумаги, то текущая позиция это точка, где карандаш касается
бумаги.

                     Функции MoveTo и LineTo

     Функция MoveTo перемещает текущую позицию  в  заданные
координаты.  Функция LineTo рисует линию из текущей позиции
к точке с заданными координатами. Заданные координаты затем
становятся  текущей позицией.  Следующий метод Paint рисует
линию от (100,150) до (10,15).

procedure TMyWindow.Paint(PaintDC: HDC; var PaintINfo:
                          TPaintStruct);
begin
  MoveTo(PaintDC, 100, 150);
  LineTo(PaintDC, 10, 15);
end;

     ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     і
     і       (10, 15)
     і    *
     і     \
     і      \
     і       \
     і        \
     і         * (100, 150)

     Рис. 17.4. Результат выполнения функции LineTo.

                        Функция PolyLine

     Функция Polyline   рисует   последовательность  линий,
соединяющих заданные  точки.  По  действию  она  аналогична
выполнению  последовательности  функций  MoveTo  и  LineTo,
однако,  Polyline выполняет эту операцию намного быстрее  и
никак  не  воздействует на текущую позицию пера.  Следующий
метод Paint рисует прямой угол.

     procedure TMyWindow.Paint(PaintDC: HDC; var PaintInfo:
                               TPaintStruct);
     var
      Points: array[0..2] of TPoint;
     begin
      Points[0].X:=10;
      Points[0].Y:=15;
      Points[1].X:=10;
      Points[1].Y:=150;
      Points[2].X:=100;
      Points[2].Y:=150;
      Polyline(PaintDC, @Points, 3);
     end;

     ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     і
     і       (10, 15)
     і    *
     і    і
     і    і
     і    і
     і    і
     і    +ДДДДД* (100, 150)


     Рис. 17.5. Результат выполнения функции Polyline.

                           Функция Arc

     Функция Arc   рисует   дуги   по   периметру  эллипса,
ограниченного заданным прямоугольником.  Дуга начинается  в
точке  пересечения  эллипса  и  линии  из  центра эллипса в
заданную точку начала. Дуга рисуется против часовой стрелки
до тех пор, пока она не достигнет точки пересечения эллипса
с линией из центра эллипса к заданной точке конца.

     Следующий метод   Paint   рисует   верхнюю    четверть
окружности  с  началом  в  (40,25)  и окончанием в (10,25),
используя ограничивающий  прямоугольник  (10,10),  (40,40),
начальную  точку  (0,0)  и конечную точку (50,0).  Действие
производится даже в том случае,  если заданная начальная  и
конечная точка не лежат на дуге.

     procedure TMyWindow.Paint(PaintDC: HDC;
                           var PaintInfo: TPaintStruct);
     begin
        Arc(PaintDC, 10, 10, 40, 40, 50, 0, 0, 0);
     end;



                         Изображение фигур
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Функции изображения  фигур  используют  текущее   перо
заданного  контекста  дисплея  для  изображения периметра и
текущую кисть для закраски внутренней области.  На  текущую
позицию они не влияют.

                        Функция Rectangle

     Функция Rectangle  рисует  прямоугольник от его левого
верхнего  угла  к  правому  нижнему.  Например,   следующий
оператор  метода  Paint  рисует прямоугольник от (10,15) до
(100,150).

     Rectangle(PaintDC, 10, 15, 100, 150);

     ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     і
     і  (10, 15)
     і    *ДДДДД*
     і    і±±±±±і
     і    і±±±±±і
     і    і±±±±±і
     і    і±±±±±і
     і    *ДДДДД* (100, 150)


     Рис. 17.6. Результат выполнения функции Rectangle.

                        Функция RoundRect

     Функция RoundRect рисует прямоугольник со скругленными
углами.  Скругления углов определены как четверти  эллипса.
Например,    следующий   оператор   метода   Paint   рисует
прямоугольник от (10,15) до (100,150),  углы которого будут
скруглены четвертями эллипса шириной 9 и высотой 11.

     RoundRect(PaintDC, 10, 15, 100, 150, 9, 11);

                         Функция Ellipse

     Функция Ellipse      рисует     эллипс,     задаваемый
ограничивающим его прямоугольником. Следующий пример рисует
эллипс в прямоугольнике от (10,15) до (110,70).

     Ellipse(PaintDC, 10, 50, 100, 150);

                       Функции Pie и Chord

     Функции Pie и Chord рисуют секторы эллипса. Они рисуют
дугу,  подобно функции Arc. Однако, результатом Pie и Chord
будут  области.  Функция  Pie соединяет центр эллипса с его
граничными точками.  Следующая функция Pie  рисует  верхнюю
четверть круга,  заключенного в прямоугольник от (10,10) до
(40,40).

     Pie(PaintDC, 10, 10, 40, 40, 50, 0, 0, 0);

     Функция Chord соединяет две граничные точки дуги.

     Chord(PaintDC, 10, 10, 40, 40, 50, 0, 0, 0);

                         Функция Polygon

     Функция Polygon рисует непрерывную  последовательность
сегментов  линий,  аналогично функции Polyline,  но в конце
работы замыкает область,  рисуя линию от последней заданной
точки  к первой заданной точке.  И,  наконец,  он заполняет
полученный   многоугольник   текущей   кистью,    используя
установленный режим закрашивания многоугольника.  Следующий
метод Paint рисует и закрашивает прямоугольный треугольник.

     procedure TMyWindow.Paint(PaintDC: HDC;
                           var PaintInfo: TPaintStruct);
     var
      Points: array[0..2] of TPoint;
     begin
      Points[0].X:=10;
      Points[0].Y:=15;
      Points[1].X:=10;
      Points[1].Y:=150;
      Points[2].X:=100;
      Points[2].Y:=150;
      Polygon(PaintDC, @Points, 3);
     end;

     ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     і
     і  (10, 15)
     і    *
     і    і\
     і    і±\
     і    і±±\
     і    і±±±\
     і    *ДДДДД* (100, 150)
       (10, 150)

     Рис. 17.7. Результат выполнения функции Polygon.


                        Использование палитр
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Некоторые типы  дисплейных  устройств компьютера могут
выводить множество цветов,  но только ограниченное их число
в каждый момент времени. Системная или физическая палитра -
это группа  или  набор  цветов,  которые  в  данный  момент
доступны  дисплею  для одновременного отображения.  Windows
дает  вашему  приложению  частичное   управление   цветами,
входящими   в   системную  палитру  устройства.  Если  ваше
приложение использует только  простые  цвета,  то  вам  нет
необходимости непосредственно использовать палитру.

     Однако, изменение  палитры системы воздействует на все
изображение,   имеющееся   на   экране,   включая    другие
приложения. Одно приложение может вызвать вывод всех других
приложений в  некорректных  цветах.  Администратор  палитры
Windows  разрешает  эту  проблему,  согласовывая  изменения
системной палитры  с  приложениями.  Windows  предоставляет
каждому   приложению   свою   логическую  палитру,  которая
представляет собой группу цветов, используемых приложением.
Администратор   палитры  связывает  запрошенные  логической
палитрой цвета с имеющимися цветами системной палитры. Если
запрошенный   цвет   отсутствует   в   системной   палитре,
администратор палитры может добавить его. Если в логической
палитре  задано  больше  цветов,  чем  может  содержаться в
системной палитре, то для дополнительных цветов подбирается
максимально похожий цвет системной палитры.

     Когда приложение    становится    активным,    имеется
возможность  заполнить   системную   палитру   цветами   из
логической   палитры.   Это   действие  может  повлиять  на
распределение цветов, заданных логическими палитрами других
приложений.  В любом случае Windows резервирует 20 цветов в
системной палитре для общего представления  цветовой  гаммы
всех приложений и самого Windows.


                         Установка палитры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Логические палитры  являются  инструментами рисования,
такими  же  как  перья  и  кисти,   описанные   в   разделе
"Инструментальные   средства   изображения".  Для  создания
логической  палитры  используется  функция   CreatePalette,
которая   берет  указатель  на  запись  данных  LogPalette,
создает новую палитру и возвращает  ее  описатель,  который
передается  в  SelectPalette  для выбора палитры в контекст
дисплея.  Запись TLogPalette содержит  поля  номера  версии
Windows (в настоящее время $0300),  число элементов палитры
и массив элементов палитры.  Каждый элемент палитры  -  это
запись  типа  TPaletteEntry.  Тип  TPaletteEntry  имеет три
байтовых поля для  спецификации  цвета  (peRed,  peGreen  и
peBlue) и одно поле для флагов (peFlags).

     GetStockObject(Default_Palette) создает   палитру   по
умолчанию,  состоящую  из   20   цветов,   которые   всегда
присутствуют в палитре системы.

     После выбора  палитры  в  контекст  дисплея  с помощью
SelectPalette, он должен до использования "реализовать" ее.
Это делается с помощью функции Windows RealizePalette:

     ThePalette := CreatePalette(@ALogPalette);
     SelectPalette(TheDC, ThePalette, 0);
     RealizePalette(TheDC);

     RealizePalette помещает   цвета  из  вашей  логической
палитры в системную  палитру  устройства.  Сначала  Windows
проверяет  соответствие цветов с уже имеющимися в системной
палитре,  а затем добавляет  ваши  новые  цвета  в  палитру
системы,  если  для  этого есть место.  Цветам,  которым не
нашлись идентичные цвета в системной  палитре,  подбирается
наиболее  соответствующий  цвет  из  палитры системы.  Ваше
приложение должно реализовать свою  палитру  до  рисования,
как   это  делается  для  других  инструментальных  средств
рисования.


                       Рисование с палитрами
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     После реализации палитры вашего приложения,  оно может
осуществлять  рисование с использованием его цветов.  Цвета
палитры можно задавать  прямо  или  косвенно.  Для  прямого
задания   цвета  используется  индекс  палитры,  TColorRef.
Индекс палитры TColorRef есть значение  типа  Longint,  где
старший  байт установлен в 1,  а индекс элемента логической
палитры  содержится  в  двух  младших   байтах.   Например,
$01000009  задает  девятый элемент логической палитры.  Это
значение можно использовать везде,  где ожидается  аргумент
TColorRef. Например:

     ALogPen.lopnColor := $01000009;

     Если ваше      дисплейное     устройство     допускает
использование  полного  24-битового  цвета  без   системной
палитры,  то  использование  индекса  палитры  неоправданно
ограничивает вас цветами вашей  логической  палитры.  Чтобы
избежать  этого ограничения,  вы можете задать цвет палитры
косвенно,   используя   относительное   значение    палитры
TColorRef. Относительное значение TColorRef почти совпадает
с абсолютным значением  RGB  TColorRef,  но  байт  старшего
разряда установлен в 2. Три младших байта содержат значение
цвета RGB.  Например,  $020000FF  задают  значение  чистого
красного  цвета.  Если  устройство  поддерживает  системную
палитру,  то Windows подберет  максимально  соответствующий
цвет   RGB   логической   палитры.   Если   устройство   не
поддерживает системную палитру,  то TColorRed  используется
так, как если бы он задавал явное значение RGB.



                           Запрос палитры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Windows определяет  функцию,  которая  позволяет   вам
получать информацию относительно палитры. GetPaletteEntries
воспринимает индекс,  диапазон и указатель на TPaletteEntry
и заполняет буфер заданными элементами палитры.


                        Модификация палитры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Есть два   способа   изменения   элементов  логической
палитры.  Функция  SetPaletteEntries  берет  те  же   самые
аргументы,   что  и  GetPaletteEntries  и  меняет  заданные
элементы на  те,  на  которые  указывает  третий  аргумент.
Обратите  внимание  на  то,  что произведенные изменения не
отражаются в системной палитре до вызова RealizePalette,  и
их   не  видно  до  перерисовки  области  клиента.  Функция
AnimatePalette  воспринимает  те  же   аргументы,   что   и
SetPaletteEntries,  но  используется  для быстрых изменений
палитры приложения,  и они немедленно становятся  видимыми.
При  вызове AnimatePalette элементы палитры с полем peFlags
установленным в константу  pc_Reserved  будут  заменены  на
соответствующие  новые  элементы,  и это найдет немедленное
отражение в системной палитре. На другие элементы это никак
не повлияет.

     Например, вам  нужно  взять  первые  десять  элементов
палитры, сменить их значение, добавив на единицу содержание
красного цвета и уменьшив содержимое синего и зеленого. Все
эти   изменения   должны   сразу    же    стать    видимыми
(Предполагается,   что   некоторые   из   элементов   имеют
установленное значение pc_Reserved):

  GetObject(ThePalette, SizeOf(NumEntries), @NumEntries);
     if NumEntries >= 10 then
     begin
   GetPaletteEntries(ThePalette, 0, 10, @PaletteEntries);
  for i:=0 to 9 do
begin
   PaletteEntries[i].peRed:=PaletteEntries[i].peRed+40;
   PaletteEntries[i].peGreen:=PaletteEntries[i].peGreen-40;
   PaletteEntries[i].peBlue:=PaletteEntries[i].peBlue-40;
end;
  AnimatePalette(ThePalette, 0, 10, @PaletteEntries);
     end;

     Вместо AnimatePalette мы могли бы использовать:

     SetPaletteEntries(ThePalette, 0, 10, @PaletteEntries);
     RealizePalette(ThePalette);

и затем перерисовать окно, чтобы увидеть изменения цветов.


                    Реакция на изменения палитры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда окно принимает сообщение wm_PaletteChanged,  это
свидетельствует о том,  что активное окно сменило системную
палитру  путем  реализации  ее  логической  палитры.  Окно,
принявшее  сообщение,  может  отреагировать  на  него тремя
способами:  оно  может  ничего  не  делать  (очень  быстрый
способ, но может привести к некорректным цветам), оно может
реализовать свою логическую  палитру  и  перерисовать  себя
(медленнее,  но цвета будут максимально корректными),  либо
оно может  реализовать  свою  логическую  палитру  и  затем
использовать  функцию  UpdateColors  для быстрого изменения
области  клиента  в  соответствии  с  системной   палитрой.
UpdateColors   в   общем   случае   работает  быстрее,  чем
перерисовка области клиента,  но при ее использовании могут
быть некоторая потеря точности в цветопередаче. Поле WParam
записи TMessage,  переданной в сообщении wm_PaletteChanged,
содержит описатель окна,  которое реализовало свою палитру.
Если  в  ответ  вы  решили  реализовать  свою   собственную
палитру,  сначала  убедитесь  в том,  что этот описатель не
является  описателем  вашего   окна,   чтобы   не   создать
бесконечного цикла.

     Программа PaTest   создает   и   реализует  логическую
палитру из восьми цветов.  При нажатии левой кнопки  "мыши"
она   будет  рисовать  раскрашенные  квадраты  с  образцами
каждого из цветов логической палитры.  При  нажатии  правой
кнопки   происходит   сдвиг   цветов   логической  палитры.
Используется  индекс  палитры  TColorRef,  поэтому,   когда
логическая  палитра  меняется  раскрашенные  квадраты также
сменят  свой  цвет.  При  использовании   индекса   палитры
TColorRef  может  оказаться  удобным  использование функции
PaletteIndex.

     Полный текст программы содержится в файле  PALTEST.PAS
на ваших дистрибутивных дискетах.

                Глава 18. Более подробно о ресурсах
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Программы Windows очень легко использовать,  т.к.  они
предоставляют пользователю стандартный интерфейс. Например,
большинство программ Windows используют меню для реализации
команд  программы,  и  курсор,  который позволяет применять
"мышь"  в  качестве  управления  такими   инструментальными
средствами,  как  указатель  "мыши"  стрелка  или кисть для
рисования.

     Меню и курсоры - это два  примера  ресурсов  программы
Windows.  Ресурсы это данные, хранимые в выполняемом (.EXE)
файле программы,  но они располагаются отдельно от обычного
сегмента   данных   программы.  Ресурсы  разрабатываются  и
специфицируются вне кода  программы,  затем  добавляются  к
скомпилированному  коду программы для создания выполняемого
файла программы.

     Следующие ресурсы вы будете создавать  и  использовать
наиболее часто:

     - Меню.
     - Блоки диалога.
     - Пиктограммы.
     - Курсоры.
     - Оперативные клавиши.
     - Графические изображения.
     - Строки символов.

     Обычно при   загрузке   приложения  в  память  Windows
оставляет  ресурсы  на   диске   и   загружает   в   случае
необходимости   отдельные  ресурсы  в  процессе  выполнения
программы.    За    исключением    побитовых    отображений
(графических  образов),  Windows  удаляет  ресурс из памяти
после окончания его использования. Если вы хотите загрузить
ресурс при загрузке программы или не хотите,  чтобы Windows
имела возможность  удалить  ресурс  из  памяти,  вы  можете
сменить   его   атрибуты.  Детальное  описание  создания  и
модификации ресурсов содержится в руководстве  пользователя
по пакету разработчика ресурсов.


                         Создание ресурсов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вы можете   создавать   ресурсы,   используя  редактор
ресурсов или компилятор ресурсов.  Паскаль поддерживает оба
эти  метода,  поэтому вы сами можете выбрать,  какой их них
является  более  удобным.  В  большинстве   случаев   проще
использовать  редактор  ресурсов  и  создавать ваши ресурсы
визуально.  Однако,  иногда   более   удобно   использовать
компилятор  ресурсов для компиляции файла описания ресурса,
который может  вам  встретиться  в  книге  или  в  журнале.
Независимо  от  выбранного  вами подхода вы обычно создаете
файл ресурса  (.RES)  для  каждого  приложения.  Этот  файл
ресурса  будет  содержать  двоичную информацию о всех меню,
диалогах,   графических   образах   и   других    ресурсах,
используемых вашим приложением.

     Двоичный файл  ресурса  (.RES)  добавляется  к  вашему
исполняемому  файлу  (.EXE)   в   процессе   компиляции   с
использованием директивы компилятора $R,  как это описано в
данной главе.  Вы также должны написать код,  который будет
загружать ресурсы в память.  Это придаст вам дополнительную
гибкость,  поскольку  ваша  программа  будет   использовать
память  лишь  для  ресурсов,  которые используются в данный
момент.  Загрузка ресурсов в память также рассматривается в
данной главе.


            Добавление ресурсов к выполняемой программе
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ресурсы хранятся  в  двоичном  формате  в  файле .RES,
поэтому они должны  быть  добавлены  к  выполняемому  файлу
приложения (.EXE).  Результатом будет файл,  который наряду
со скомпилированным кодом приложения будет содержать и  его
ресурсы.

 Есть три способа добавления ресурсов к выполняемому файлу:

     - Можно использовать редактор ресурсов для копирования
       ресурсов из файла .RES в уже  скомпилированный  файл
       программы .EXE.    Инструкции   по   этой   операции
       содержатся  в  руководстве  пользователя  по  пакету
       разработчика ресурсов.

     - Можно   задать  директиву  в  исходном  коде  файла.
       Например, эта программа на языке Паскаль:

        program SampleProgram;
        {$r SAMPLE.RES}
          .
          .
          .

       добавит файл  ресурсов  SAMPLE.RES  к   выполняемому
       файлу. Каждая программа на языке Паскаль может иметь
       только один файл ресурсов (хотя этот  файл  ресурсов
       может включать другие файлы ресурсов). Все эти файлы
       должны быть  файлами  .RES  и  хранить   ресурсы   в
       двоичном формате. Директива компилятора $R позволяет
       вам задать отдельный файл .RES.

     - Использовать компилятор ресурсов.


                   Загрузка ресурсов в приложение
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     После добавления  ресурса  к  выполняемому  файлу,  он
должен   быть   явно   загружен   приложением   до   своего
использования.  Конкретный способ загрузки ресурса  зависит
от типа ресурса.


                           Загрузка меню
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Меню окна  является  одним  из атрибутов его создания.
Другими словами это  характеристика  окна,  которая  должна
быть  задана  до создания соответствующего элемента меню (с
помощью метода  Create).  Следовательно,  меню  может  быть
задано   в   типе   конструктора   Init  или  вскоре  после
конструирования.  Ресурсы меню загружаются вызовом  функции
Windows   LoadMenu   со  строкой  идентификатора  меню  при
конструировании нового объекта окна. Например:

constructor SampleMainWindow.Init(AParent: PWindowsObject;
                                  ATitle: PChar);
begin
  TWindow.Init(AParent, ATitle);
  Attr.Menu:=LoadMenu(HInstance, PChar(100));
  .
  .
end;

     Код PChar(100)  переводит  целое  значение  100  в тип
PChar, совместимый с Windows тип строки. LoadMenu загружает
ресурс  меню  с  идентификатором  100  в новый объект окна.
Ресурс  может  иметь  символьное  имя  (строку),  например,
'SampleMenu',  а  не числовой идентификатор.  В этом случае
предыдущий код будет выглядеть следующим образом:

constructor SampleMainWindow.Init(AParent: PWindowsObject;
                                  ATitle: PChar);
begin
  TWindow.Init(AParent, ATitle);
  Attr.Menu:=LoadMenu(HInstance, 'SampleMenu');
  .
  .
end;

     Дополнительная информация  по  созданию  объектов окна
содержится в Главе 10, "Объекты окна".

     Для обработки выбора варианта меню просто определяется
метод  для  окна,  которое  владеет  этим  меню,  используя
специальное   расширение   заголовка   определения   метода
идентификатором cm_First:

    procedure HandleMenu101(var Msg: TMessage);
                                     virtual cm_First+101;

     Обратите внимание на то,  что 101  представляет  собой
выбранного варианта меню (а не самого ресурса меню). Каждый
пункт меню имеет уникальный целочисленный идентификатор.  В
этом  методе  задача  состоит в организации соответствующей
реакции на выбор пункта меню.  Обычно вы будете  определять
символьные константы для команд вашего меню.

                    Загрузка оперативных клавиш
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Оперативные клавиши  -  это   активные   клавиши   или
комбинации клавиш,  которые используются для задания команд
приложения.  Обычно оперативные  клавиши  определяются  как
эквиваленты  выбора пунктов меню.  Например,  клавиша Del -
это  стандартная   оперативная   клавиша,   которую   можно
использовать  как  альтернативу выбора пункта Delete в меню
Edit.  Однако,  оперативные  клавиши  могут   реализовывать
команды, которые не соответствуют элементам меню.

     Ресурсы оперативных    клавиш   хранятся   в   таблице
оперативных клавиш. Для загрузки таблицы оперативных клавиш
используется   функция  Windows  LoadAccelerators,  которая
просто возвращает описатель таблицы.  В отличие от  ресурса
меню, который связан с конкретным окном, ресурс оперативной
клавиши принадлежит  всему  приложению.  Каждое  приложение
может  иметь  только один такой ресурс.  Объекты приложения
резервируют одно  поле  объекта,  HAccTable,  для  хранения
описателя  ресурса  оперативных  клавиш.  Обычно  вы будете
загружать  ресурс  оперативных  клавиш  в  методе   объекта
приложения InitInstance:

     procedure SampleApplication.InitInstance;
     begin
        TApplication.InitInstance;
        HAccTable := LoadAccelerators(HInstance,
                                    'SampleAccelerators');
     end;

     Часто вы будете  определять  оперативные  клавиши  для
быстрого выбора вариантов меню.  Например, Shift+Ins обычно
используется для быстрого выбора команды Paste. Оперативные
клавиши генерируют основанные на команде сообщения, которые
идентичны сообщениям, генерируемым выбором пункта меню. Для
привязки  метода  реакции на выбор в меню с соответствующей
оперативной   клавишей   нужно   убедиться   в   том,   что
определенное   в   ресурсе   значение  оперативной  клавиши
идентично идентификатору элемента меню.


                      Загрузка блоков диалога
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Блоки диалога  являются  единственным  типом  ресурса,
который    непосредственно   соответствует   типу   объекта
ObjectWindows.  TDialog и  его  производные  типы,  включая
TDlgWindow,    определяют   объекты   интерфейса,   которые
используют  ресурсы  блока  диалога.  Каждый  объект  блока
диалога  обычно  связан  с  одним  ресурсом  блока диалога,
который задает его  размер,  местоположение  и  ассортимент
управляющих элементов (таких,  как командные кнопки и блоки
списка).

     При конструировании  блока  диалога   задайте   ресурс
объекта блока диалога. Как ресурсы меню и командных клавиш,
ресурс диалога может иметь символьное имя или целочисленный
идентификатор. Например:

     Adlg := New(PSampleDialog, Init(@Self, 'AboutBox'));
или
     Adlg := New(PSampleDialog, Init(@Self, PChar(120)));

     Дополнительная информация по созданию объектов диалога
содержится в Главе 11, "Объекты диалоговых блоков".


                   Загрузка курсоров и пиктограмм
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Каждый тип  объекта  окна  имеет специальные атрибуты,
называемые атрибутами  регистрации.  Среди  этих  атрибутов
есть   курсор   окна  и  пиктограмма.  Для  установки  этих
атрибутов  для  типа  окна  вы  должны   определить   метод
GetWindowClass (как и GetClassName).

     Например, вы  создаете  курсор  для выбора элементов в
блоке списка.  Курсор  имеет  вид  указательного  пальца  и
хранится  в ресурсе курсора с именем 'Finger'.  Кроме того,
вы  создаете  ресурс  пиктограммы  с  именем  'SampleIcon',
который  выглядит как улыбающееся лицо.  Вы должны написать
метод GetWindowClass следующим образом:

     procedure SampleWindow.GetWindowClass(var AWndClass:
                                           TWndClass);
     begin
        TWindow.GetWindowClass(AWndClass);
        AWndClass.hCursor:=LoadCursor(HInstance, 'Finger');
        AWndClass.hIcon:=LoadIcon(HInstance, 'SampleIcon');
     end;

     Однако, между курсором  и  пиктограммой  имеется  одно
отличие.  Оно состоит в том, что курсор задается для одного
окна,   а   пиктограмма   представляет   все    приложение.
Следовательно,  пиктограмма  устанавливается в типе объекта
только для основного окна.  У этого  правила  имеется  одно
исключение:   для   приложений,  которые  следуют  правилам
многодокументального интерфейса (MDI), каждое дочернее окно
MDI имеет свою собственную пиктограмму.
     Для использования одного из уже имеющихся курсоров или
пиктограмм  Windows,  передайте 0 в HInstance и используйте
значение idc_ (например,  idc_IBeam) для курсора и значение
idi_ (например, idi_Hand) для пиктограммы. Например:

     procedure SampleWindow.GetWindowClass(var AWndClass:
                                           TWndClass);
     begin
      TWindow.GetWindowClass(AWndClass);
    AWndClass.hCursor := LoadCursor(HInstance, idc_IBeam);
      AWndClass.hIcon := LoadIcon(HInstance, idi_Hand);
     end;

     Дополнительную информацию по регистрационным атрибутам
окна можно найти в Главе 10, "Объекты окна".


                    Загрузка строковых ресурсов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Принципиальная причина  выделения  строк  приложения в
качестве ресурсов состоит в облегчении  процесса  настройки
приложения   на   конкретное   применение  или  возможности
перевода  приложения  на  иностранный  язык.  Если   строки
определены  в  исходном  коде,  то  для  их  изменения  или
перевода нужно иметь доступ к исходному коду.  Если же  они
определены   как  ресурсы,  то  хранятся  в  таблице  строк
выполняемого  файла  приложения.  Вы  можете   использовать
редактор строк для перевода строк в таблице,  без изменения
и даже доступа к исходному коду.  Каждый  выполняемый  файл
может иметь только одну таблицу строк.

     Для загрузки строки из таблицы в буфер сегмента данных
вашего   приложения   используется   функция    LoadString.
Синтаксис LoadString следующий:

LoadString(HInstance, StringID,@TextItem,SizeOf(TextItem));

     * Параметр  StringID - это номер идентификатора строки
       (например,  601) в таблице строк.  Это  число  можно
       заменить константой.

     * Параметр   @TextItem   -  это  указатель  на  массив
       символов (PChar), который принимает строку.

     * Параметр SizeOf(TextItem) - это  максимальное  число
       символов,  передаваемых  в  @TextItem.  Максимальный
       размер ресурса строки 255 символов, поэтому передача
       буфера  из  256 символов гарантирует полную передачу
       строки.

     LoadString возвращает  число  скопированных  в   буфер
символов, или ноль, если ресурс не существует.

     Вы можете использовать ресурс строки для вывода текста
в блоке сообщения. Например, вы можете вывести сообщение об
ошибке.  В  данном  примере  вы определяете строку 'Program
unavailable'  в  таблице  строк  и  определяете   константу
ids_NoProgrm   в   качестве   идентификатора   строки.  Для
использования этого ресурса строки  в  блоке  сообщения  об
ошибке, вы можете написать следующую процедуру:

     procedure TestDialog.RunErrorBox(ErrorNumber:
                                      Integer); virtual;
     var
       TextItem: array[0..255] of Char;
     begin
       LoadString(HInstance, ids_NoPrgrm, @TextItem, 20);
       MessageBox(HWindow, @TextItem, 'Error', mb_OK or
                  mb_IconExclamation);
     end;

     Данный пример   загружает   отдельную  строку  в  блок
сообщения об ошибке.  Для  загрузки  списка  строк  в  блок
списка  вызывается  LoadString  для загрузки каждой строки,
затем вызывается AddString для добавления ее в блок списка.

     Другое использование  ресурса  строк  применяется  для
элементов меню, которые добавляются в меню вашего исходного
кода.  В этом случае сначала  получается  ресурс  строки  с
помощью   LoadString.   Затем  эта  строка  передается  как
параметр в вызовы функций Window CreateMenu  и  AppendMenu.
Например:

procedure SampleWindow.Init(AParent:
                            PWindpwsObject; ATitle:
                                 PChar);
     var
      TextItem: array[0..255] of Char;
     begin
        TWindow.Init(AParent, ATitle);
        Attr.Menu := LoadMenu(HInstance, PChar(100));
        LoadString(HInstance, 301, @TextItem, 20);
        AppendMenu(Attr.Menu, mf_String ormf_Enabled, 501,
                   @TextItem);
     end;



                  Загрузка графических изображений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Функция Windows     LoadBitmap    загружает    ресурсы
графических изображений (битовых  отображений).  LoadBitmap
загружает побитовое распределение в память и возвращает его
описатель. Например:

     HMyBit:=LoadBitmap(HInstance, PChar(501));

загружает ресурс  побитового  отображения с идентификатором
501 и записывает его описатель в переменную  HMyBit.  После
загрузки  побитового  отображения оно останется в памяти до
его явного удаления вами. В отличие от других ресурсов, оно
остается  в памяти даже после закрытия пользователем вашего
приложения.

     В Windows имеется ряд заранее определенных графических
изображений,  которые  используются  как часть графического
интерфейса Windows.  Ваше приложение  может  загружать  эти
изображения (например,  obm_DnArrow, obm_Close и obm_Zoom).
Как   и    предопределенные    пиктограммы    и    курсоры,
предопределенные   графические   изображения   могут   быть
загружены, если в вызове LoadBitmap вместо HInstance задать
ноль:

     HMyBit:=LoadBitmap(0,  PChar(obm_Close));

     После загрузки  графического  образа  ваше  приложение
может использовать его разными способами:

     * Для  рисования  картинки  на  экране.  Например,  вы
       можете  загрузить  побитовое  распределение  в  блок
       информации о приложении в качестве заставки.

     * Для создания кисти,  которую вы можете  использовать
       для заполнения областей экрана или для создания фона
       окна. Создав кисть по графическому образу, вы можете
       закрасить ей область фона.

     * Для  отображения  картинок вместо текста в элементах
       меню или элементах блока списка. Например, вы можете
       вместо   слова   'Arrow'  (стрелка)  в  пункте  меню
       поместить изображение стрелки.

     Дополнительная информация  относительно  использования
графики с побитовым отображением содержится в Главе 17.

     Если побитовое  отображение  не  используется,  то его
нужно удалить из памяти.  В противном случае занимаемая  им
память будет недоступна другим приложениям. Даже если вы не
удаляете   его   после   использования   приложением,    вы
обязательно   должны  удалить  его  до  прекращения  работы
приложения. Графический образ удаляется из памяти с помощью
функции Windows DeleteObject:

     if DeleteObject(HMyBit) then         { успешно };

     После удаления  графического изображения его описатель
становится некорректным, и его нельзя использовать.



   Использование побитовых отображений для создания кистей
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вы можете использовать графические образы для создания
кистей,  которые могут закрашивать области экрана.  Область
может  быть  закрашена сплошным цветом или в виде заданного
образца.   Минимальный   размер   используемого   в   кисти
графического   образа   составляет   8   на   8   элементов
изображения.  Если  вы   применяете   большее   графическое
изображение,  то  в  кисти  используется  только  его левый
верхний угол 8 на 8.  Предположим,  что вы хотите заполнить
область полосками, как это показано на Рис. 18.1.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫBitmap drawing testЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
і File    Help                                           і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і                                                        і
і    ±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±±Ы±Ы±Ы±Ы±Ы     і
і    ±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±±Ы±Ы±Ы±Ы±Ы     і
і    ±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±±Ы±Ы±Ы±Ы±Ы     і
і    ±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±±Ы±Ы±Ы±Ы±Ы     і
і    ±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±±Ы±Ы±Ы±Ы±Ы     і
і    ±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±±Ы±Ы±Ы±Ы±Ы     і
і    ±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±±Ы±Ы±Ы±Ы±Ы     і
і    ±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±±Ы±Ы±Ы±Ы±Ы     і
і    ±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±Ы±±Ы±Ы±Ы±Ы±Ы     і
і                                                        і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 18.1. Заполнение области экрана полосками.

     При заполнении области на Рис. 18.1 Windows циклически
копирует   кисть.    Действительный    размер    побитового
распределения  -  лишь  8  на  8 элементов изображения,  но
кистью можно закрасить весь экран.

     ЫЫЫЫЫЫ±±±±±±
     ЫЫЫЫЫЫ±±±±±±
     ЫЫЫЫЫЫ±±±±±±

     Рис. 18.2.   Ресурс   графического   изображения   для
создания кисти по образцу Рис. 18.1.

     Следующий код  помещает  образец графического образа в
кисть:

     procedure SampleWindow.MakeBrush;
     var
       MyLogBrush: TLogBrush;
     begin
       HMyBit := LoadBitmap(HInstance, PChar(502));
       MyLogBrush.lbStyle := bs_Pattern;
       MyLogBrush.lbHatch := HMyBit;
       TheBrush := CreateBrushInderect(@MyLogBrush);
     end;

     Для проверки образца, отобразим его в прямоугольнике:

     procedure MyWindow.Paint(PaintDC: HDC;
                              var PaintInfo: TPaintStruct);
     begin
       SelectObject(PaintDC, TheBrush);
       Rectangle(PaintDC, 20, 20, 200, 200);
     end;

     После использования кисти вы должны удалить и кисть, и
графическое изображение:

     DeleteObject(HMyBit);
     DeleteObject(TheBrush);


             Отображение графических изображений в меню
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для отображение    графических    образов    в    меню
используется функция ModifyMenu.  Она  меняет  существующий
элемент   меню   таким   образом,   что  выводит  побитовое
отображение вместо текста варианта  меню,  определенного  в
редакторе меню. Например, этот конструктор Init добавляет и
модифицирует меню окна:

     type
      MyLong = record
       case Integer of
        0: (TheLong: Longint);
        1: (Lo: Word;
            Hi: Word);
      end;

     constructor SampleWindow.Init(AParent: PWindowsObject;
                                   ATitle: PChar);
     var
        ALong: MyLong;
     begin
        TWindow.Init(AParent, ATitle);
        Attr.Menu := LoadMenu(HInstance, PChar(100));
        ALong.Lo := LoadBitmap(HInstance, PChar(503));
ModifyMenu(Attr.Menu, 111, mf_ByCommand or mf_Bitmap, 211,
                   PChar(ALong.TheLong));
          .
          .
          .
     end;

     В приведенном   выше  коде  111  -  это  идентификатор
команды варианта меню,  который изменяется,  а 211 это  его
новый идентификатор.  Однако, вы можете использовать один и
тот же идентификатор в обоих случаях.

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫStepsЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
іЫЫFileЫЫЫ  Help                                          і
ГДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іЫЫЫЫNewЫЫЫЫЫЫЫі                                          і
і    pick      і                                          і
і        me    і                                          і
і    Save      і                                          і
і    Save As   і                                          і
ГДДДДДДДДДДДДДДЩ                                          і
і                                                         і
і                                                         і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. 18.3.  Меню,  где  в  качестве  одного из пунктов
выбора использовано графическое изображение.

                          Глава 19. Наборы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Программисты, работающие  на  языке  Паскаль,   обычно
тратят   очень   много   времени   на   создание   кода  по
манипулированию и обеспечению структур  данных,  таких  как
связанные   списки  и  массивы  с  динамической  установкой
размеров. И очень часто один и тот же код имеет тенденцию к
повторному переписыванию и отладке.

     Что касается  традиционного  языка  Паскаль,  он  лишь
предоставляет вам встроенные типы  записи  и  массива.  Все
другие  структуры  остаются  на ваше усмотрение.  Например,
если вы собираетесь хранить данные в массиве, то обычно вам
нужно  написать код для создания массива,  импорта данных в
массив,  получение  данных  массива   для   обработки,   и,
возможно,   вывода   данных   на  устройство  ввода-вывода.
Позднее,  когда потребуется новый тип элемента массива,  вы
начинаете все сначала.

     Было бы замечательно,  если бы тип массива поставлялся
вместе с кодом,  обрабатывающего бы многие из тех операций,
которые  обычно  выполняются  с  массивом.  Это  был бы тип
массива,  который можно было  бы  расширять  без  нарушения
первоначального кода.  Все это является целью создания типа
ObjectWindows  TCollection.  Это  объект,  который   хранит
наборы   указателей   и   обладает   набором   методов   по
манипулированию ими.


                          Объекты наборов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Будучи объектами и тем самым имея  встроенные  методы,
наборы  обладают  двумя  дополнительными  чертами,  которые
имеют отношение к обычным  массивам  языка  Паскаль  -  это
динамическое установка размеров и полиморфизм.


              Динамическая установка размеров наборов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Размер стандартного   массива  в  стандартном  Паскале
фиксируется во время  компиляции.  Хорошо,  если  вы  точно
знаете,  какой размер должен иметь ваш массив, но это может
быть не столь хорошо к тому моменту, когда кто-нибудь будет
запускать  на  вашу  программу.  Изменение  размера массива
требует изменения исходного кода и перекомпиляции.

     Однако, для  наборов  вы  устанавливаете   только   их
начальный   размер,  который  динамически  увеличивается  в
процессе работы программы, для размещения в нем всех нужных
данных.  Это  делает ваше приложение в его скомпилированном
виде значительно более гибким.  Тем не менее, следует иметь
в виду,  что набор не может сжиматься, поэтому следует быть
аккуратным и не делать его неоправданно большим.


                        Полиморфизм наборов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Второй аспект,  по которому массивы могут ограничивать
ваше приложение,  состоит в том, что каждый элемент массива
должен иметь один и тот же тип,  и  этот  тип  должен  быть
определен при компиляции кода.

     Наборы обходят    это    ограничение    использованием
нетипизированных указателей.  Это сказывается не только  на
быстроте  и  эффективности,  но  наборы  могут  состоять из
объектов (и даже не из объектов) разного  типа  и  размера.
Набору  не  нужно  знать  что-либо об объектах,  которые он
обрабатывает.  Он просто организует связь с ними  в  случае
необходимости.

                       Проверка типа и наборы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Наборы ограничивают традиционную мощную проверку  типа
языка Паскаль.  Это означает,  что можете поместить нечто в
набор и когда запрашиваете это  назад,  компилятор  уже  не
может  проверить  ваших предположений относительно объекта.
Вы можете поместить нечто как PHedgehog (еж),  а  прочитать
назад   как   PSheep   (овца),  и  набор  никак  не  сможет
насторожить вас.

     Как программист,  работающий  на  языке  Паскаль,   вы
вполне  оправданно будете нервничать по поводу результатов.
Проверка типов  языка  Паскаль  в  конце  концов  сберегает
несколько  часов при поиске некоторых достаточно иллюзорных
ошибок.  Поэтому вы должны принять  во  внимание  следующее
предупреждение.   Вы   даже   представить  себе  не  можете
насколько трудно бывает искать ошибки несоответствия  типа,
поскольку  обычно  эту  работу  за вас выполнял компилятор!
Однако,  если вы обнаружите,  что ваша программа  сбивается
или   зацикливается,   тщательно  проверьте  хранимые  типы
объектов и считываемые из наборов.


   Объединение в набор элементов, не являющихся объектами
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вы даже можете добавить в набор нечто,  что вообще  не
является  объектом,  но  это  также может явиться серьезным
предметом   озабоченности.   Наборы    ожидают    получения
нетипизированных  указателей незаданного типа на нечто.  Но
некоторые методы TCollection предназначены  специально  для
работы  с наборами элементов,  производных от TObject.  Это
касается методов доступа к  потоку  PutItem  и  GetItem,  и
стандартной процедуры FreeItem.

     Например, это означает,  что вы можете хранить PChar в
наборе,  но  при  попытке  послать  этот  набор  в   поток,
результаты будут не столь успешными,  если вы не перепишете
стандартные методы набора GetItem  и  PutItem.  Аналогично,
при  попытке  освобождения  набора  будет  сделана  попытка
удаления каждого элемента с помощью FreeItem. Например, это
делает TStrCollection.

     Если вам  удастся  преодолеть  все  эти трудности,  вы
обнаружите,  что наборы  (и  построенные  вами  производные
наборов) являются быстрыми, гибкими и надежными структурами
данных.


                          Создание набора
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Создание набора столь же просто,  как и создание  типа
данных,  которые вы хотите в нем хранить.  Предположим, что
вы - консультант, и вам нужно хранить и искать номер счета,
фамилию и номер телефона каждого из ваших клиентов. Сначала
определим тип  объекта  клиента  (TClient),  который  будет
хранится в наборе (не забудьте определить тип указателя для
каждого нового типа объекта):

     type
       PClient=^TClient;
       TClient=object(TObject)
         Account, Name, Phone: PChar;
    constructor Init(NewAccount, NewName, NewPhone: PChar);
         destructor Done; virtual;
         procedure Print; virtual;
       end;

     Затем реализуем  методы  Init  и Done для размещения и
удаления данных о клиенте и  метод  Print  для  отображения
данных  о  клиенте в виде таблицы.  Обратите внимание,  что
поля объекта имеют тип  PChar,  поэтому  память  выделяется
только   для   той   части  строки,  которая  действительно
используется.  Функции StrNew и StrDispose очень эффективно
обрабатывают динамические строки.

     constructor TClient.Init(NewAccount, NewName,
                              NewPhone: PChar);
     begin
       Account := StrNew(NewAccount);
       Name    := StrNew(NewName);
       Phone    := StrNew(NewPhone);
     end;

     destructor TClientDone;
     begin
        StrDispose(Account);
        StrDispose(Name);
        StrDispose(Phone);
     end;

     procedure TClient.Print;
     begin
       Writeln( ' ',
        Account, '':10 - StrLen(Account),
        Name, '':20 - StrLen(Name),
        Phone, '':16 - StrLen(Phone));
     end;

     TClient.Done будет   автоматически   вызываться    для
каждого клиента при удалении всего набора. Сейчас вы просто
инициируете набор для хранения ваших клиентов и  вставляете
в   него   записи   о  клиентах.  Головное  тело  программы
(COLLECT1.PAS) будет выглядеть следующим образом:

     var
       ClientList: PCollection;
     begin
       ClientList:=New(PCollection, Init(10,5));
       with ClientList^ do
       begin
      Insert(New(PClient, Init('91-100', 'Anders, Smitty',
         '(406) 111-2222')));
      Insert(New(PClient, Init('90-167', 'Smith, Zelda',
         '(800) 555-1212')));
      Insert(New(PClient, Init('90-177', 'Smitty, John',
         '(406) 987-4321')));
      Insert(New(PClient, Init('90-160', 'Johnson, Agatha',
         '(302) 139-8913')));
      end;
      PrintAll(ClientList);
      SearchPhone(ClientList, '(406)');
      Dispose(ClientList, Done);
     end.

           Примечание: Процедуры  PrintAll  и   SearchPhone
      будут рассмотрены позднее.

     Обратите внимание,  насколько  просто  было  построить
набор.   Первый   оператор   размещает   новый    экземпляр
TCollection  с именем ClientList с начальным размером на 10
клиентов.  В  случае  необходимости  размещения  более   10
клиентов  в  ClientList,  его  размер  будет  увеличиваться
каждый раз на 5 клиентов.  Следующие два оператора  создают
новый объект клиента и вставляют его в набор. Вызов Dispose
в конце операции освобождает весь набор клиентов.

     Нигде не нужно было сообщать набору,  какой вид данных
предполагается  хранить  -  для  этого  просто используется
указатель.


                          Методы итератора
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вставка и удаление элемента не являются  единственными
общими  операторами  набора.  Очень  часто вы будете писать
циклы for  для  просмотра  всех  объектов  набора  с  целью
отображения  данных или выполнения некоторых вычислений.  В
других  случаях  вы  будете  искать  первый  или  последний
элемент  набора,  который удовлетворяет некоторому критерию
поиска.  Для  этих  целей  у  наборов  имеется  три  метода
итератора:  ForEach,  FirstThat  и LastThat.  Каждый из них
воспринимает указатель на процедуру или функцию в  качестве
своего единственного параметра.


                          Итератор ForEach
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ForEach воспринимает указатель на процедуру. Процедура
имеет  один  параметр,  который  является   указателем   на
хранимый  в  наборе  элемент.  Для  каждого элемента набора
ForEach   вызывает    процедуру    один    раз,    в    той
последовательности, в которой элементы появляются в наборе.
Процедура PrintAll в Collect1 показывает  пример  итератора
FoeEach.

     procedure PrintAll(C: PCollection);
      procedure CallPrint(P: PClient); far;
      begin
        P^.Print;    {Вызов метода Print}
      end;
     begin {Print}
       Writeln;
       Writeln;
       Writeln('Client list:');
       C^.ForEach(@CallPrint); {  распечатка  для   каждого
     клиента } end;

     Для каждого  элемента  набора,  переданного в качестве
параметра  в  PrintAll,  вызывается   вложенная   процедура
CallPrint.  CallPrint  просто  распечатывает  информацию об
объекте клиента в отформатированных колонках.

           Примечание: Итераторы должны вызывать  локальные
     процедуры far.

     Вам нужно  быть  аккуратным  с  сортировкой  процедур,
которые вы вызываете  итераторами.  Для  того,  чтобы  быть
вызванной   итератором,   процедура   (в   данном  примере,
CallPrint) должна:

     * Быть процедурой - она не  может  быть  функцией  или
       методом объекта,  хотя данный пример показывает, что
       процедура может вызвать метод.

     * Быть локальной (вложенной)  относительно  вызывающей
       ее программы.

     * Описываться как дальняя процедура директивой far или
       директивой компилятора {$F+}.

     * Воспринимать указатель на элемент набора в  качестве
       своего единственного параметра.



                   Итераторы FirstThat и LastThat
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Кроме возможности  приложения  процедуры   к   каждому
элементу набора,  часто бывает очень нужно найти конкретный
элемент  набора  на  основании  некоторого  критерия.   Это
является  предназначением  итераторов FirstThat и LastThat.
Как это следует из  их  имен,  они  просматривают  набор  в
противоположных  направлениях до момента нахождения первого
элемента набора,  который удовлетворяет критерию  булевской
функции, переданной в качестве элемента.

     FirstThat и  LastThat  возвращают  указатель на первый
(или  последний)  элемент,  который  удовлетворяет  условию
поиска. Предположим, что в приведенном ранее примере списка
клиентов, вы не можете вспомнить номер счета клиента или не
помните точно написание имени клиента.  К счастью, вы точно
помните,  что это был ваш первый клиент из  штата  Монтана.
Следовательно, вы можете организовать поиск первого клиента
с кодом штата 406 (поскольку ваш  список  клиентов  ведется
хронологически).    Данная   процедура   использует   метод
FirstThat, который и сделает всю работу:

procedure SearchPhone(C: PCollection; PhoneToFind: PChar);
 function PhoneMatch(Client: PClient: PClient): Boolean;
     far;
 begin
  PhoneMatch := StrPos(Client^.Phone, PhoneToFind) <> nil;
 end;
var
  FoundClient: PClient;
begin     { SearchPhone }
 Writeln;
 FoundClient := C^.FirstThat(@PhoneMatch);
 if FoundClient = nil then
  Writeln('Такому требованию не отвечает ни один клиент')
 else
 begin
   Writeln('Найден клиент:');
   FoundClient^.Print;
 end;
end;

     Снова обратите внимание на то,  что PhoneMatch вложена
и  использует  удаленную  модель вызова.  В этом случае эта
функция  возвращает  True  только  при  совпадении   номера
телефона клиента и заданного образца поиска.  Если в наборе
нет объекта,  который соответствовал  бы  критерию  поиска,
FirstThat возвращает указатель nil.

     Запомните: ForEach вызывает определенную пользователем
процедуру,  а  FirstThat   и   LastThat   каждая   вызывает
определенную   пользователем  булевскую  функцию.  В  любом
случае определенная  пользователем  процедура  или  функция
передают указатель на объект набора.


                       Отсортированные наборы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Иногда вам   бывает  нужно,  чтобы  ваши  данные  были
определенным  образом  отсортированы.  ObjectWindows  имеет
специальный  тип набора,  который позволяет вам упорядочить
ваши    данные    произвольным     образом.     Это     тип
TSortedCollection.

     TSortedCollection является  производным от TCollection
и  автоматически  сортирует  задаваемые  ему  объекты.  При
добавлении нового элемента он автоматически проверяет набор
на   дублирование   ключей.   Булевское   поле   Duplicates
контролирует разрешение дублирования ключей.  Если для поля
Duplicates установлено значение False  (по  умолчанию),  то
новый  элемент  добавляется к набору,  заменяя существующий
член с тем же самым ключом.  Если Duplicates имеет значение
True, то новый член просто вставляется в набор.

     TSortedCollection -  это набор абстрактного типа.  Для
его использования  вы  должны  сначала  решить,  какой  тип
данных  вы  собираетесь  собирать  и определить два метода,
отвечающих вашим  конкретным  требованиям  сортировки.  Для
этого   вам   нужно   создать  новый  тип,  производный  от
TSortedCollection.   В   данном    случае    назовем    его
TClientCollection.  Ваш  TClientCollection  уже знает,  как
делать всю реальную работу с  набором.  Он  может  вставить
(Insert)   запись   о  новом  клиенте  и  удалять  (Delete)
существующие записи - он  унаследовал  эти  основные  черты
поведения  от  TCollection.  Все  что  нужно  сделать - это
научить  TClientCollection,  какое  поле   использовать   в
качестве  ключа  сортировки  и как сравнивать двух клиентов
при решении вопроса о том,  какой из них  должен  стоять  в
наборе  выше  другого.  Это делается переписыванием методов
KeyOf и Compare и реализации их следующим образом:

PClientCollection = ^TClientCollection;
TClientCollection = object(TSortedCollection)
  function KeyOf(Item: Pointer): Pointer; virtual;
  function Compare(Key1, Key2: Pointer): Integer; virtual;
end;

function TClientCollection.KeyOf(Item: Pointer): Pointer;
begin
  KeyOf := PClient(Item)^.Account;
end;

function TClientCollection.Compare(Key1, Key2: Pointer):
       Integer;
begin
  Compare := StrIComp(PChar(Key1), PChar(Key2));
end;

           Примечание: Так      как      ключи     являются
      нетипизированными   указателями,   для   них    нужно
      выполнять приведение типа.

     KeyOf определяет,  какое  поле или поля используются в
качестве  ключей  сортировки.  В  данном  случае  это  поле
клиента Account.  Compare воспринимает два ключа сортировки
и  определяет,  какой  из  них   должен   идти   первым   в
соответствии с правилами сортировки. Compare возвращает -1,
0 или 1 в зависимости  от  того,  Key1  меньше,  равен  или
больше Key2,  соответственно. В данном примере используется
сортировка  по  алфавиту  (для  букв  верхнего  и   нижнего
регистра)  ключевой  строки  (Account)  путем вызова модуля
Strings функции StrIComp. Вы можете легко сортировать набор
по именам,  вместо номера счета, если замените возвращаемое
KeyOf поле на Name.

     Обратите внимание на то, что ключи, возвращаемые KeyOf
и   передаваемые   в   Compare  являются  нетипизированными
указателями,  поэтому до  их  разыменования  и  передачи  в
StrIComp  в  данном  примере  вы  должны  привести их тип к
PChar.

     Это практически все, что вам нужно определить! Теперь,
если  вы  переопределите  ClientList  как PClientCollection
вместо PCollection (сменив объявление var и вызов New),  то
легко  сможете  распечатать  ваших  клиентов  в  алфавитном
порядке (COLLECT2.PAS):

     var
       ClientList: PClientCollection;
        .
        .
     begin
       ClientList:=New(PClientCollection, Init(10,5));
        .
        .
     end.

     Обратите внимание и на то,  как  легко  будет  сменить
сортировку списка клиентов по номеру счета на сортировку по
имени.  Все что вам нужно сделать,  это сменить метод KeyOf
на возврат поля Account на поле Name.


                            Наборы строк
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Многим программам       требуется      работать      с
отсортированными строками.  Для  этих  целей  ObjectWindows
предоставляет  набор специального назначения TStrCollection
(он совпадает с типом TStringCollection,  определенным  для
хранения  строк Паскаля).  Обратите внимание,  что элементы
TStrCollection - это не  объекты.  Они  представляют  собой
указатели   на  строки,  заканчивающиеся  нулем.  Поскольку
наборы строк происходят от TSortedCollection, можно хранить
и дублированные строки.

     Использовать наборы     строк     несложно.     Просто
определяется  переменная  указателя  для  хранения   набора
строк.  Разместим  набор,  задав  его  начальный  размер  и
приращение  для  роста  при  добавлении  новых  строк  (см.
COLLECT3.PAS):

     var
      WordList: PCollection;
      WordRead: PChar;
        .
        .
        .
     begin
      WordList:=New(PStrCollection, Init(10,5));
        .
        .
        .

     WordList первоначально рассчитан для хранения 10 строк
с последующим приращением по 5 строк.  Все  что  вам  нужно
сделать  -  это вставить несколько строк в набор.  В данном
примере слова считываются из текстового файла и вставляются
в набор:

     repeat
        .
        .
        .
      if GetWord(WordRead, WordFile)^ <> #0 then
       WordList^.Insert(StrNew(WordRead));
        .
        .
        .
      until WordRead[0]=#0;
        .
        .
        .
      Dispose(WordList, Done);

     Обратите внимание, что функция StrNew используется для
копирования  считанных  слов,  и адрес скопированной строки
передается в набор.  При  использовании  набора  вы  всегда
передаете  ему контроль над данными набора.  Он позаботится
об освобождении данных после работы. Он при этом делает то,
что происходит при вызове Dispose: удаляется каждый элемент
набора, и затем удаляется сам набор WordList.


                      Пересмотренные итераторы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Метод ForEach просматривает  весь  набор,  элемент  за
элементом,   и   выполняет   над  каждым  из  них  заданную
процедуру.  В  предыдущем   примере   процедуре   PrintWord
передавался  указатель строки для ее отображения.  Обратите
внимание,   что   процедура   PrintWord   вложенная    (или
локальная). Она работает в другой процедуре, Print, которой
передается указатель на  TstrCollection.  Print  использует
метод  итератора  ForEach  для  передачи  каждого  элемента
своего набора в процедуру PrintWord.

     procedure Print(C: PCollection);
      procedure PrintWord(P: PChar); far;
      begin
        Writeln(P);                 { вывести строку }
      end;
     begin {Print}
       Writeln;
       Writeln;
       C^.ForEach(@PrintWord);      { вызов PrintWord }
     end;

     PrintWord должен выглядеть как уже знакомая процедура.
Она просто берет указатель строки и передает  его  значение
Writeln.  Обратите внимание на директиву far после описания
PrintWord.  PrintWord не может  быть  методом,  это  просто
процедура.  Кроме того это должна быть вложенная процедура.
Print  надо  рассматривать  как   некую   оболочку   вокруг
процедуры,  которая  выполняет  некоторую работу над каждым
элементом набора (может быть  отображает  или  модифицирует
данные).  Вы  можете  иметь несколько аналогичных PrintWord
процедур,  но каждая из них должна быть вложена в  Print  и
должна  быть дальней процедурой (использовать директиву far
или {$F+}).

                       Нахождение элемента

     Отсортированные наборы (и следовательно наборы  строк)
имеют  метод  Search,  который возвращает индекс элемента с
конкретным  значением  ключа.  Но  как  найти   элемент   в
неотсортированном  наборе?  Или  когда  критерий  поиска не
использует  сам  ключ?  Конечно  же,  следует  использовать
FirstThat  и  LastThat.  Вы  просто  определяете  булевскую
функцию для  проверки  нужного  вам  критерия  и  вызываете
FirstThat.





                       Полиморфические наборы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Как вы  уже  видели,  что  наборы  могут   динамически
хранить   любой  тип  данных,  и  они  обладают  множеством
методов,  которые помогают вам  организовывать  эффективный
доступ   к   данным.  В  действительности  сам  TCollection
определяет 23 метода.  Когда вы используете наборы в  ваших
программах,  вы  будете  удивлены скоростью их работы:  они
разработаны с  максимальной  гибкостью  и  реализованы  для
использования с максимальной скоростью.

     Теперь пришло  время  рассмотреть реальные возможности
наборов,  элементы могут обрабатываться полиморфически. Это
значит,  что  вы  не просто можете хранить определенный тип
объекта в наборе;  вы можете хранить несколько разных типов
объектов, взятых произвольно из вашей иерархии объектов.

     Если вы  рассмотрите  приведенные примеры наборов,  вы
можете заметить,  что все элементы каждого набора были одно
и  того  же типа.  Мы имели дело со списком строк в котором
каждый элемент был строкой.  Мы  также  занимались  списком
клиентов.  Но  наборы  могут  хранить  любые производные от
TObject объекты,  и вы  можете  произвольно  смешивать  эти
объекты.  Естественно,  что  вы желаете,  чтобы эти объекты
имели нечто общее. На самом деле вам нужно, чтобы у них был
общий абстрактный объект-предок.

     В качестве   примера   рассмотрим  программу,  которая
помещает в набор три различных графических  объекта.  Затем
итератор   ForEach  используется  для  просмотра  набора  и
отображения каждого объекта.  В отличие от других  примеров
данной  главы  данный  пример (Collect4) использует функции
Windows для рисования в окне. Обязательно включите WinProcs
и  WinTypes  в  uses данного примера.  Сначала определяется
абстрактный объект-предок (см. COLLECT4.PAS).

     type
       PGraphObject = ^TGraphObject;
     TGraphObject = object(TObject)
       Rect: TRect;
       constructor Init(Bounds: TRect);
       procedure Draw(DC: HDC); virtual;
     end;

     Из этого  объявления  вы  можете  видеть,  что  каждый
графический  объект  может  инициализировать  себя (Init) и
отобразить  себя  на  графическом  экране  (Draw).   Теперь
определим эллипс, прямоугольник и сектор как производные от
этого общего предка:

     PGraphEllipse = ^TGraphEllipse;
     TGraphEllipse = object(TGraphObject)
       procedure Draw(DC: HDC); virtual;
     end;

     PGraphRect=^TGraphRect;
     TGraphRect=object(TGraphObject)
       procedure Draw(DC: HDC); virtual;
     end;
     PGraphPie = ^TGraphPie;
     TGraphPie = object(TGraphObject)
       ArcStart, ArcEnd: TPoint;
       constructor Init(Bounds: TRect);
       procedure Draw(DC: HDC); virtual;
     end;

     Все эти  три  типа  объекта  наследуют  поле  Rect  из
TGraphObject,  но все они разного размера.  TGraphEllipse и
TGraphRect нужно только добавить их новые методы рисования,
т.к.   их   методам   рисования   нужны  только  размеры  и
расположение,  а  TGraphPie  нужны  дополнительные  поля  и
другой   конструктор   для  их  корректного  представления.
Приведем исходный код для помещения этих фигур в набор:

       .
       .
       .
     GraphicsList := New(PCollection, Init(10,5));
                                   { создать набор }
     for I := 1 to NumToDraw do
     begin
      case I mod 3 of              { создать объект }
       0: P := New(GraphRect, Init(Bounds));
       1: P := New(GraphEllipse, Init(Bounds));
       2: P := New(GraphPie, Init(Bounds));
      end;
      GraphicsList^.Insert(P);     { добавить в набор }
     end;
       .
       .

     Как вы  можете видеть цикл,  for вставляет графические
объекты в набор GraphicsList.  Вы  знаете  только  то,  что
каждый  объект  в GraphicsList представляет собой некоторый
вид TGraphObject.  После помещения в набор у  вас  уже  нет
информации    о    том,    является   ли   элемент   набора
прямоугольником,   эллипсом   или    сектором.    Благодаря
полиморфизму,  вам этого и не нужно знать, поскольку каждый
объект содержит все данные и код (Draw), который ему нужен.
Просмотрим  набор  с  использованием  итеративного метода и
каждый набор будет сам отображать себя:

     procedure DrawAll(C: PCollection);

     procedure CallDraw(P: PGraphObject); far;
      begin
        P^.Draw(PaintDC);      { вызов метода Draw }
      end;

     begin     {DrawAll}
      C^.ForEach(@CallDraw);   { прорисовать каждый объект}
     end;

     var
      GraphicsList: PCollection;
     begin
       .
       .
       .
      if GraphicsList <> nil then DrawAll(GraphicsList);
       .
       .
       .
     end.

     Способность наборов   хранить   разные,  но  связанные
объекты   основывается   на   мощном   краеугольном   камне
объектно-ориентированного   программирования.  В  следующей
главе вы увидите тот же принцип полиморфизма, примененный к
потокам с равными приоритетами.



                    Наборы и управление памятью
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TCollection может  динамически  расти  от   начального
размера,  установленного  Init,  до максимального размера в
16380 элементов.  ObjectWindows хранит максимальный  размер
набора в переменной MaxCollectionSize. Каждый добавляемый в
набор  элемент  занимает  четыре  байта  памяти,  т.к.   он
хранится в виде указателя.

     Ни одна  библиотека  динамических  структур  данных не
будет полной,  если она не снабжена средствами  обнаружения
ошибок. Если для инициализации набора не хватает памяти, то
возвращается указатель nil.

     Если не  хватает  памяти  при  добавлении  элемента  в
набор,  то вызывается метод TCollection.Error,  и возникает
ошибка  этапа  выполнения  в   динамически   распределяемой
области памяти.  Вы можете переписать TCollection.Error для
организации   собственного   метода   информирования    или
исправления ошибки.

     Вам следует   уделить   особое   внимание  доступности
динамической области памяти, поскольку у пользователя имеет
значительно  больший контроль над программой ObjectWinodws,
чем над обычной программой языка Паскаль.  Если добавлением
объектов в набор управляет пользователь (например, открывая
новое окно),  то ошибку динамической области памяти не  так
то легко предсказать.  Вы можете предпринять некоторые шаги
по защите пользователя от фатальной ошибки  при  выполнении
программы  либо  проверяя  память при использовании набора,
либо обрабатывая сбой выполняемой программы таким  образом,
чтобы избежать прекращения ее работы.

                          Глава 20. Потоки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Техника объектно-ориентированного  программирования  и
ObjectWindows  дают вам мощные средства инкапсуляции кода и
данных и  большие  возможности  построения  взаимосвязанных
структур  объектов.  Но  что  делать,  если  стоит  простая
задача, например, по хранению некоторых объектов на диске?

     Когда-то данные хранились исключительно в  записях,  и
помещение  данных  на  диск  было  тривиальной задачей.  Но
данные в  программах  ObjectWindows  неразрывно  связаны  с
объектами.  Конечно, вы можете отделить данные от объекта и
записать  их  в  дисковый  файл.   Объединение   дает   вам
значительный  шаг  в направлении прогресса,  а разъединение
отбрасывает вас назад.

     Есть ли     в      самом      объектно-ориентированном
программировании   и   ObjectWindows   некоторые  средства,
которые могли  бы  разрешить  эту  проблему?  Есть,  и  это
потоки.

     Поток в  ObjectWindows - это набор объектов на их пути
куда-либо:  обычно в файл, EMS, в последовательный порт или
некоторое  другое  устройство.  Потоки обслуживают операции
ввода-вывода на уровне объектов, а не на уровне данных. При
расширении   объекта  ObjectWindows  вам  нужно  обеспечить
обработку  определенных  вами  дополнительных  полей.   Все
сложные   аспекты   обработки   на  уровне  объектов  будут
проделаны за вас.


                    Вопрос: объектный ввод-вывод
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Поскольку вы пишете программы  на  языке  Паскаль,  то
знаете,  что  до выполнения операций ввода-вывода с файлом,
вы сначала должны сообщить компилятору, какой тип данных вы
будете писать и считывать из файла.  Файл должен иметь тип,
и этот тип должен быть установлен во время компиляции.

     Паскаль реализует в этой связи очень удобное  правило:
можно  организовать  доступ  к файлу неопределенного типа с
помощью  процедур  BlockWrite   и   BlockRead.   Отсутствие
проверки    типа    возлагает    некоторую   дополнительную
ответственность  на  программиста,  хотя  позволяет   очень
быстро выполнять двоичные операции ввода-вывода.

     Вторая проблема  состоит  в  том,  что  вы  не  можете
непосредственно использовать файлы с объектами.  Паскаль не
позволяет  вам  создавать  файл с объектным типом.  Объекты
могут  содержать   виртуальные   методы,   адреса   которых
определяются   в  процессе  выполнения  программы,  поэтому
хранение информации о  виртуальных  методах  вне  программы
лишено   смысла,   еще  более  бессмысленно  считывать  эту
информацию в программу.

     Но эту проблему снова можно обойти. Вы можете выделить
данные  из  ваших  объектов  и  записать  эту  информацию в
какой-то файл некоторого вида,  а уже позднее  восстановить
объекты из этих исходных данных.  Подобное решение, однако,
будет  недостаточно  элегантным  и  существенно   усложняет
конструирование объектов.


                           Ответ: потоки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows позволяет  обойти  все  эти  трудности и
даже сулит вам получение  некоторых  дополнительных  выгод.
Потоки  дают  вам  простое,  но  изящное  средство хранение
данных объекта вне вашей программы.


                        Полиморфизм потоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Потоки ObjectWindows позволяют вам работать с  файлами
определенного   и   неопределенного   типа:  проверка  типа
имеется,  но тип посылаемого объекта не должен  обязательно
определяться во время компиляции.  Смысл в том,  что потоки
знают,  что они имеют дело с  объектами,  и  поскольку  все
объекты  являются  производными от TObject,  поток может их
обработать.   В    действительности    различные    объекты
ObjectWindows  могут также легко записываться в один поток,
как и группы идентичных объектов.


                    Потоки обрабатывают объекты
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Все что вам нужно сделать - это определить для потока,
какие объекты ему нужно будет обрабатывать,  чтобы он знал,
как согласовывать данные с таблицами  виртуальных  методов.
Затем  без  каких-либо  усилий вы можете помещать объекты в
поток и извлекать их из потока.

     Но каким образом один и тот же поток может считывать и
записывать  такие разные объекты как TCollection и TDialog,
даже не зная в момент компиляции,  какие типы  объектов  он
будет   обрабатывать?   Это   существенно   отличается   от
традиционных  операций  ввода-вывода   языка   Паскаль.   В
действительности  потоки могут обрабатывать даже новые типы
объектов,  которые вообще еще не  были  созданы  к  моменту
компиляции потока.

     Ответом на  это  является  так называемая регистрация.
Каждому  типу  объекта  ObjectWindows  (или  любому  новому
производному   типу   объекта)   присваивается   уникальный
регистрационный номер.  Этот  номер  записывается  в  поток
перед  данными  объекта.  Затем,  при считывании объекта из
потока, ObjectWindows сначала берет регистрационный номер и
на  его основании узнает,  сколько данных нужно считывать и
какие таблицы виртуальных методов подключать к данным.


                    Смысл использования потоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     На фундаментальном  уровне  вы  можете   рассматривать
потоки  как файлы языка Паскаль.  В своей основе файл языка
Паскаль  представляет  собой  последовательное   устройство
ввода-вывода:  вы  записываете в него и считываете из него.
Поток - это  полиморфическое  устройство  последовательного
ввода-вывода,  т.е.  оно  ведет себя,  как последовательный
файл,  но вы можете считывать и записывать  различные  типы
объектов в каждый момент времени.

     Потоки (как    и    файлы    Паскаля)    можно   также
просматривать,  как устройства  ввода-вывода  произвольного
доступа,  искать  определенное  место  в  файле,  считывать
данные в этой точке или  записывать  данные  в  эту  точку,
возвращать позицию указателя файла и т.д.  Все эти операции
можно выполнять с потоками, и они описаны в разделе "Потоки
с произвольным доступом".

     Есть два   разных   аспекта   использования   потоков,
которыми вам нужно овладеть,  и к  счастью  оба  они  очень
простые.   Первый  -  это  установка  потока,  а  второй  -
считывание и запись файлов в поток.

                        Установка потока

     Все что нужно сделать для использования потока  -  это
инициализировать  его.  Точный  синтаксис конструктора Init
может быть разным,  в зависимости от типа потока, с которым
вы имеете дело. Например, если вы открываете поток DOS, вам
нужно передать  имя  файла  DOS  и  режим  доступа  (только
чтение, только запись, чтение/запись) для содержащего поток
файла.

     Например, для инициализации  буферизированного  потока
DOS  при загрузке набора объектов в программу,  все что вам
нужно это:

     var
       SaveFile: TBufStream;
     begin
       SaveFile.Init('COLLECT.DTA', stOpen, 1024);
        .
        .

     После инициализации потока все готово к работе.

     TStream это  абстрактный  механизм потока,  поэтому вы
будет работать не  с  ним,  а  с  производными  от  TStream
удобными объектами потока. Это будет, например, TDosStream,
для выполнения дисковых операций  ввода-вывода,  TBufStream
для  буферизованных операций ввода-вывода (очень удобен для
частых операций считывания  или  записи  небольших  объемов
информации  на  диск)  и TEmsStream для передачи объектов в
память   EMS.   Кроме   того,    ObjectWindows    реализует
индексированные  потоки  с указателем,  указывающим место в
потоке.  Перемещая этот указатель  вы  можете  организовать
произвольный доступ в потоке.


                 Чтение из потока и запись в поток
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Основной объект  потока  TStream реализует три главных
метода, которые вам нужно четко понимать: Get, Put и Error.
Get  и  Put  грубо  соответствуют  процедурам Read и Write,
которые вы используете в  обычных  операциях  ввода-вывода.
Error  -  это  процедура,  которая вызывается при появлении
ошибок потока.

                            Метод Put

     Давайте сначала  рассмотрим   процедуру   Put.   Общий
синтаксис метода Put следующий:

     SomeStream.Put(PSomeObject);

где SomeStream  -  это  некоторый  производный  от  TStream
объект,  который   был   инициализирован,   а   PSomeObject
представляет  собой  указатель  на некоторый производный от
TObject объект, который зарегистрирован с потоком. Это все,
что  вам нужно сделать.  Поток может из таблицы виртуальных
методов  PSomeObject  узнать,   какой   это   тип   объекта
(предполагается, что тип зарегистрирован), поэтому он знает
какой номер идентификатора писать,  и  сколько  после  него
будет данных.

     Специальный интерес  для  вас,  как  для программиста,
работающего с ObjectWindows,  состоит в том факте,  что при
помещении в поток группы с дочерними окнами,  дочерние окна
также автоматически  помещаются  в  поток.  Таким  образом,
запись сложных объектов не так уж и сложна, более того, это
делается  автоматически!   Вы   можете   сохранить   полное
состояние  диалога  простым  помещением  объекта  диалога в
поток.  При повторном запуске вашей  программы  и  загрузке
диалога будет выведено его состояние в момент записи.

                            Метод Get

     Считывание объектов из потока столь же просто. Все что
вам нужно сделать, это вызвать функцию Get:

     PSomeObject := SomeStream.Get;

где SomeStream    -    это     инициализированный     поток
ObjectWindows,  а  PSomeObject - указатель на некоторый тип
объекта ObjectWindows.  Get просто возвращает указатель  на
нечто,  что он взял из потока.  Сколько данных было взято и
какой  тип  таблицы  виртуальных  методов  (VMT)   присвоен
данным, определяется не типом PSomeObject, а типом объекта,
обнаруженным в потоке. Следовательно, если объект в текущей
позиции  SomeStream имеет не совпадающий с PSomeObject тип,
у вас будет некорректная информация.

     Как и Put,  Get ищет сложные  объекты.  Следовательно,
если  вы  ищите  в  потоке окно,  которое владеет дочерними
окнами, то они также будут загружены.

                           Метод Error

     И, наконец,  процедура Error определяет что происходит
при возникновении ошибки потока. По умолчанию TStream.Error
просто устанавливает значение двух полей в потоке (Status и
ErrorInfo).   Если   вы   хотите   сделать  что-либо  более
содержательное,  например,  сгенерировать   соответствующее
сообщение  о  сбое  в  работе  программы  или  вывести блок
диалога c сообщением об ошибке, то вам нужно переопределить
процедуру Error.


                          Закрытие потока
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда вы закончили использование потока,  вы вызываете
его метод Done,  как вы обычно вызывали Close для дискового
файла.   Как  и  для  других  объектов  ObjectWindows,  это
делается следующим образом:

     Dispose(SomeStream, Done);

как для уничтожения объекта потока, так и для его закрытия.


                   Как сделать объекты потоковыми
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Все стандартные   объекты   ObjectWindows   готовы   к
использованию в потоках,  и все потоки ObjectWindows узнают
стандартные объекты.  При изготовлении нового типа объекта,
производного  от  стандартного  объекта,  его  очень просто
подготовить к использованию в потоке и известить  потоки  о
его существовании.


                     Методы загрузки и хранения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Действительное чтение   и   запись  объектов  в  поток
производится методами Load и Store.  Каждый  объект  должен
иметь  эти  методы  для  использования  потока,  поэтому вы
никогда  не  будете  вызывать   их   непосредственно   (они
вызываются  из  методов  Get  и  Put.)  Все  что  вам нужно
сделать, это убедиться в том, что объект знает, как послать
себя в поток, когда это потребуется.

     Благодаря объектно-ориентированному   программированию
это делается  очень  просто,  т.к.  большинство  механизмов
наследуются  от  объекта-предка.  Все что должен делать ваш
объект, это загружать и хранить те свои компоненты, которые
вы  в  него  добавляете,  об  остальном  позаботится  метод
предка.  Например, вы производите от TWindow новый вид окна
с   именем  художника-сюрреалиста  Рене  Магритте,  который
нарисовал много известных картин с окнами:

     type
      TMagritte = object(TWindow)
        Surreal: Boolean;
        constructor Load(var S: TStream);
        procedure Store(var S: TStream);
         .
         .
         .
      end;

     Все что было  добавлено  к  данным  окна  -  это  одно
булевское  поле.  Для загрузки объекта вы просто считываете
стандартный TWindow, а затем считываете дополнительный байт
булевского   поля.   Типичные   методы  Load  и  Store  для
производных объектов будут выглядеть следующим образом:

     constructor TMagritte.Load(var S: Stream);
     begin
      TWindow.Load(S);                  { загрузка типа }
      S.Read(Surreal, SizeOf(Surreal)); { чтение
                                    дополнительных полей }
     end;

     procedure TMagritte.Store(var S: Stream);
     begin
      TWindow.Store(S);               { сохранение типа }
      S.Write(Surreal, SizeOf(Surreal));      { запись
                                    дополнительных полей }
     end;

     Вы должны   контролировать,   что    записывается    и
загружается  один и тот же объем данных,  и загрузка данных
производится в той же последовательности,  что и их запись.
Компилятор  не покажет ошибки.  Если вы будете недостаточно
аккуратны,  то могут возникнуть серьезные проблемы. Если вы
изменяете поля объекта,  то нужно изменить и метод Load,  и
метод Store.


                         Регистрация потока
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Кроме определения  методов  Load  и  Store  для  новых
объектов,  вы  также должны зарегистрировать этот новый тип
объекта в  потоках.  Регистрация  -  это  простой  процесс,
который состоит из двух этапов: сначала определяется запись
регистрации  потока,  а  затем  она  передается  глобальной
процедуре регистрации RegisterType.

           Примечание: ObjectWindows        уже       имеет
      зарегистрированными все стандартные объекты,  поэтому
      вам  нужно регистрировать только новые,  определяемые
      вами объекты.

     Для определения  записи   регистрации   потока   нужно
следовать  приводимому  ниже  формату.  Запись  регистрации
потока это запись языка  Pascal  типа  TStreamRec,  которая
определяется следующим образом:

     PStreamRec = ^TStreamRec;
     TStreamRec = record
        ObjType: Word;
        VmtLink: Word;
        Load: Pointer;
        Store: Pointer;
        Next: Word;
     end;

     По соглашению  всем  регистрационным  записям   потока
ObjectWindows    присваивается    то    же   имя,   что   и
соответствующим типам объектов, но начальное "T" заменяется
на   "R".   Следовательно,   регистрационная   запись   для
TCollection будет иметь имя RCollection.  Такие абстрактные
типы  как TObject и TWindowsObject не имеют регистрационных
записей,  поскольку их  экземпляры  вы  никогда  не  будете
хранить в потоках.


                  Номера идентификаторов объектов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вам действительно  нужно  думать только о поле ObjType
записи,  все остальное делается механически. Каждому новому
определяемому   вами   типу   требуется   его   собственный
уникальный идентификатор типа в виде  числа.  ObjectWindows
резервирует   регистрационные   номера   от  0  до  99  для
стандартных объектов,  поэтому ваши регистрационные  номера
будут лежать в диапазоне от 100 до 65535.

     Ответственность за   создание   и  ведение  библиотеки
номеров идентификаторов  для  всех  ваших  новых  объектов,
которые   будут   использоваться  в  потоках  ввода-вывода,
ложиться целиком на вас.  Нужно сделать эти  идентификаторы
доступными  для  пользователей  ваших  модулей.  Как  и для
идентификатора меню и определенных пользователем сообщений,
присваиваемые  вами числа могут быть произвольными,  но они
должны быть уникальными и попадать в указанный диапазон.


                        Автоматические поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Поле VmtLink это связь с таблицей виртуальных  методов
объектов  (VMT).  Вы просто задаете его как отклонение типа
вашего объекта:

     RSomeObject.VmtLink := Ofs(TypeOf(TSomeObject)^);

     Поля Load  и  Store  содержат  соответственно   адреса
методов Load и Store.

     RSomeObject.Load := @TSomeObject.Load;
     RSomeObject.Store := @TSomeObject.Store;

     Значение последнего поля,  Next, задается RegisterType
и  не  требует никакого вмешательства с вашей стороны.  Оно
просто      обеспечивает      внутреннее      использование
скомпонованного списка регистрационных записей потока.


                        Регистрация на месте
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     После конструирования регистрационной записи потока вы
вызываете  RegisterType  с   вашей   записью   в   качестве
параметра.  Поэтому  для  регистрации вашего нового объекта
TMagritte для  его  использования  в  потоке  вы  включаете
следующий код:

     const
      RMagritte: TStreamRec = (
        ObjType: 100;
        VmtLink: Ofs(TypeOf(TMagritte)^);
        Load: @TMagritte.Load;
        Store: @TMagritte.Store
      );
     RegisterType(RMagritte);

     Вот и все.  Теперь вы можете помещать (Put) экземпляры
вашего  нового  типа  объекта в любой поток ObjectWindows и
считывать их из потоков.


                  Регистрация стандартных объектов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows определяет    регистрационные     записи
потоков  для  всех  его  стандартных объектов.  Кроме того,
модуль  WObjects  определяет  процедуру   RegisterWObjects,
которая   автоматически   регистрирует  все  объекты  этого
модуля.  Например,  модуль  OWindows   содержит   процедуру
RegisterOWindows, а ODialogs - RegisterODialogs.


                          Механизм потока
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     После того, как мы посмотрели на процесс использования
потоков,  следует заглянуть во внутреннюю  работу,  которую
производит  ObjectWindows  c  вашими  объектами  с  помощью
методов Put и Get.  Это  прекрасный  пример  взаимодействия
объектов и использования встроенных в них методов.


                            Процесс Put
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда вы  посылаете  объект  в  поток с помощью метода
Put,  поток сначала берет указатель VMT со смещением  0  от
объекта  и  просматривает  список  зарегистрированных типов
потоков  системы  с  целью  найти  совпадение.  Когда   это
совпадение   найдено,   поток  ищет  регистрационный  номер
идентификатора объекта и  записывает  его  в  поток.  Затем
поток  вызывает  метод  Store объекта для завершения записи
объекта.  Метод Store использует  процедуру  потока  Write,
которая действительно пишет корректное число байт в поток.

     Ваш объект не должен ничего знать о потоке - это может
быть файл на диске,  память EMS или любой другой вид потока
-  ваш  объект  просто  говорит "запишите меня в поток",  и
поток делает все остальное.


                            Процесс Get
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда вы считываете объект из потока с помощью  метода
Get,   сначала   ищется   номер   его   идентификатора,   и
просматривается  на  совпадение  список  зарегистрированных
типов.  После обнаружения совпадения регистрационная запись
дает потоку местоположение метода Load объект и VMT.  Затем
для чтения нужного объема данных из потока вызывается метод
Load.

     Вы опять просто говорите потоку, что нужно взять (Get)
следующий  объект  и  поместить  его в место,  определяемое
заданным вами указателем.  Ваш объект даже не беспокоится о
том, с каким потоком он имеет дело. Поток сам беспокоится о
считывании нужного объема данных из потока с помощью метода
объекта  Load,  который  в  свою очередь опирается на метод
потока Read.

     Для программиста все это достаточно прозрачно, но в то
же   время   вы   ясно   должны   понять,  насколько  важно
зарегистрировать  тип  до  проведения  каких-либо   попыток
ввода-вывода с потоком.


           Обработка указателей объектов со значением nil
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вы можете  записать в поток объект nil.  Однако,  если
это сделать,  то в поток запишется слово 0.  При считывании
идентификатора  слова  0  поток  возвратит  указатель  nil.
Поэтому  0   считается   зарезервированным   и   не   может
использоваться  в  качестве  номера  идентификатора объекта
потока. ObjectWindows резервирует идентификатор потока от 0
до 99 для внутреннего использования.


                      Наборы в потоке: пример
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В Главе 19,  "Наборы",  вы уже видели как наборы могут
содержать  разные,  но  связанные  объекты.  Это   свойство
полиморфизма  также  применимо  и  к  потокам,  и  их можно
использовать для записи наборов на  диск  для  последующего
обращения,  даже  в  другой  программе.  Вернемся к примеру
COLLECT4.PAS.  Что еще нужно добавить в эту  программу  для
помещения набора в поток?

     Ответ будет  очень  простым.  Сначала  возьмем базовый
объект TGraphObject и "научим" его хранить его данные (X  и
Y) в потоке.  Для этого нужен метод Store.  Затем определим
новый метод Store для любого производного  от  TGraphObject
объекта,   в   котором   добавляются   дополнительные  поля
(например, TGraphPie добавляет ArcStart и ArcEnd).

     Затем построим регистрационную запись для каждого типа
объекта,  который предполагается хранить,  и зарегистрируем
все эти типы при первом запуске вашей программы. Вот и все.
Остальное  будет  подобно  обычным операциям ввода-вывода в
файл:  определяется  переменная  потока;  создается   новый
поток;  одним  простым  оператором  весь набор помещается в
поток, и поток закрывается.


                      Добавление методов Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Приведем методы  Store.  Обратите  внимание,  что  для
PGraphEllipse  и  PGraphRect  не требуются свои собственные
методы,  т.к. они не добавляют новых полей к унаследованным
от PGraphObject:

     type
      PGraphObject = ^TGraphObject;
      TGraphObject = object(TObject)
       Rect: TRect;
       constructor Init(Bounds: TRect);
       procedure Draw(DC: HDC); virtual;
       procedure Store(var S: TStream); virtual;
     end;

     PGraphEllipse = ^TGraphEllipse;
     TGraphEllipse = object(TGraphObject)
      procedure Draw(DC: HDC); virtual;
     end;

     PGraphRect = ^TGraphRect;
     TGraphRect = object(TGraphObject)
      procedure Draw(DC: HDC); virtual;
     end;

     PGraphPie = ^TGraphPie;
     TGraphPie = object(TGraphObject)
      ArcStart, ArcEnd: TPoint;
      constructor Init(Bounds: TRect);
      procedure Draw(DC: HDC); virtual;
      procedure Store(var S: TStream); virtual;
     end;

     Реализация метода Store вполне очевидна. Каждый объект
вызывает  свой  унаследованный метод Store,  который хранит
все унаследованные данные. Затем вызывается метод Write для
записи дополнительных данных:

     procedure TGraphObject.Store(var S: TStream);
     begin
       S.Write(Rect, SizeOf(Rect));
     end;
     procedure TGraphPie.Store(var S: TStream);
     begin
       TGraphObject.Store(S);
       S.Write(ArcStart, SizeOf(ArcStart));
       S.Write(ArcEnd, SizeOf(ArcEnd));
     end;

     Обратите внимание,  что  метод  TStream  Write  делает
двоичную запись.  Его первый параметр может быть переменной
любого типа,  но TStream.Write не может узнать размеры этой
переменной.  Второй параметр содержит эту информацию,  и вы
должны придерживаться соглашения относительно использования
стандартной   функции  SizeOf.  Таким  образом,  компилятор
всегда может гарантировать,  что  вы  всегда  считываете  и
записываете нужное количество данных.


                        Регистрация записей
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Наш последний  шаг  состоит  в  определении  константы
регистрационной  записи  для  каждого  производного   типа.
Хороший   прием   программирования   состоит  в  следовании
соглашению  ObjectWindows  относительно  использования  для
имени  типа  идентификатора,  где  вместо  первой  буквы  T
ставится R.

     Помните о  том,  что  каждой  регистрационной   записи
присваивается   уникальный   номер  идентификатора  объекта
(ObjType).  Номера от 0 до 99  резервируются  ObjectWindows
для стандартных объектов.  Хорошо бы отслеживать все номера
идентификаторов   ваших   объектов   потока   в   некотором
центральном месте, чтобы избежать дублирования.

     const
      RGraphEllipse: TStreamRec = (
       ObjType: 150;
       VmtLink: Ofs(TypeOf(TGraphEllipse)^);
       Load: nil;                         { метод загрузки
                                            отсутствует }
       Store: @TGraphEllipse.Store);
      RGraphRect: TStreamRec = (
       ObjType: 151;
       VmtLink: Ofs(TypeOf(TGraphRect)^);
       Load: nil;                         { метод загрузки
                                            отсутствует }
       Store: @TGraphRect.Store);
      RGraphPie: TStreamRec = (
       ObjType: 152;
       VmtLink: Ofs(TypeOf(TGraphPie)^);
       Load: nil;                         { метод загрузки
                                            отсутствует }
       Store: @TGraphPie.Store);

     Вам не  нужно регистрационная запись для TGraphObject,
так  как  это  абстрактный  тип,  и  он  никогда  не  будет
помещаться  в  набор  или  в  поток.  Указатель Load каждой
регистрационной записи устанавливается в nil,  поскольку  в
данном  примере  рассматривается  только помещение данных в
поток.  В следующем примере методы Load будут определены, и
изменены регистрационные записи (см. STREAM2.PAS).


                            Регистрация
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Всегда нужно  зарегистрировать  каждую из этих записей
до проведения каких-либо операций ввода-вывода  с  потоком.
Самый  простой  способ  сделать  это  состоит в том,  чтобы
объединить их все в одну процедуру и  вызвать  ее  в  самом
начале   вашей   программы   (или   в  методе  Init  вашего
приложения):

     procedure StreamRegistration;
     begin
       RegisterType(RCollection);
       RegisterType(RGraphEllipse);
       RegisterType(RGraphRect);
       RegisterType(RGraphPie);
     end;

     Обратите внимание,  что  вам  нужно   зарегистрировать
TCollection  (используя  его запись RCollection - теперь вы
видите,  что  соглашения  о  присваивании   имен   упрощают
программирование),  хотя  вы  и  не определили TCollection.
Правило очень простое и незабываемое именно вы отвечаете за
регистрацию  каждого  типа объекта,  который ваша программа
будет помещать в поток.


                           Запись в поток
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Нужно следовать  обычной  последовательности  операций
ввода-вывода в файл: создать поток; поместить в него данные
(набор);  закрыть  поток.  Вам  не  нужно  писать  итератор
ForEach  для помещения в поток каждого элемента набора.  Вы
просто говорите потоку,  что нужно поместить (Put) набор  в
поток:

     var
       .
       .
       .
      GraphicsStream: TBufStream;
     begin
       .
       .
       .
      StreamRegistration;    { регистрация всех объектов
                                                 потока }
      GraphicsStream.Init('GRAPH.SMT', stCreate, 1024);
      GraphicsStream.Put(GraphicsList);{ выходной набор }
      if GraphicsStream.Status <> 0 then
       Status:=em_Stream;
      GraphicsStream.Done;               { сброс потока }
     end;

     В результате создастся файл на диске, который содержит
всю информацию, необходимую для "считывания" набора назад в
память.  Когда  поток  открыт,  и  ищется  набор,  то  (см.
STREAM2.PAS)  "магически"  восстанавливаются  все   скрытые
связи между набором и его элементами,  объекты и их таблицы
виртуальных  методов.  Следующий   раздел   поясняет,   как
помещать в поток объекты,  которые содержат связи с другими
объектами.


                         Как все хранится?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Относительно потоков     нужно     сделать      важное
предостережение:  только владелец объекта должен записывать
его в поток.  Это предостережение аналогично  традиционному
предостережению  языка  Паскаль,  которое  вам  должно быть
известно: только владелец указателя может уничтожить его.

     В реальных  сложных  приложениях  множество   объектов
часто   имеют  указатель  на  конкретную  структуру.  Когда
возникает необходимость в выполнении операций ввода-вывода,
вы  должны  решить,  кто "владеет" структурой.  Только этот
владелец должен посылать структуру в  поток.  Иначе  у  вас
может  получиться несколько копий одной структуры в потоке.
При  считывании  такого  потока  будет  создано   несколько
экземпляров структуры,  и каждый из первоначальных объектов
будет указывать на собственную персональную копию структуры
вместо единственной первоначальной структуры.


                           Поля в потоке
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Много раз  вы видели,  что удобно хранить указатель на
дочерние окна группы в локальной  переменной  (поле  данных
объекта). Например, блок диалога может хранить указатель на
его объекты управления в полях с мнемоническими именами для
более  удобного  доступа (OKButton или FileINputLine).  При
создании такого дочернего окна порождающее окно будет иметь
на него два указателя, один - в поле, и еще один - в списке
дочерних  окон.  Если  на  это  не  обратить  внимания,  то
считывание    такого   объекта   из   потока   приведет   к
дублированию.

     Решение состоит в использовании методов TWindowsObject
GetChildPtr  и  PutChildPtr.  При  хранении  поля,  которое
является дочерним окном,  вместо записи указателя, как если
бы   это   была  простая  переменная,  вы  вызываете  метод
PutChildPtr, который записывает ссылку на позицию дочернего
окна   в  списке  дочерних  окон  группы.  Аналогично,  при
загрузке (Load) группы из потока, вы вызываете GetChildPtr,
который  гарантирует,  что  поле  и  список  дочерних  окон
указывают на один и тот же объект. Приведем короткий пример
использования GetChildPtr и PutChildPtr в простом окне:

     type
       TDemoWinodw = object(TWindow)
       Msg: PStatic;
       constructor Load(var S: TStream);
       procedure Store(var S: TStream);
     end;

     constructor TDemoWindow.Load(var S: TStream);
     begin
       TWindow.Load(S);
       GetChildPtr(S, Msg);
     end;

     procedure TDemoWindow.Store(var S: TStream);
     begin
       TWindow.Store(S);
       PutChildPtr(S, Msg);
     end;

     Давайте рассмотрим, чем этот метод Store отличается от
обычного Store.  После обычного сохранения окна все что нам
нужно сделать,  это записать ссылку  на  поле  Msg,  вместо
записи   самого   поля,   как   мы   это   обычно   делали.
Действительный объект кнопки хранится в виде дочернего окна
для окна, которое вызывается TWindow.Store.

     Кроме этого  нужно  поместить эту информацию в поток с
указанием того,  что Msg указывает на  это  дочернее  окно.
Метод  Load производит обратные действия,  сначала загружая
окно и его дочернее окно  командной  кнопки,  а  уже  затем
восстанавливая указатель на это дочернее окно через Msg.



                      Родство экземпляров окон
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
      Аналогичная ситуация   может  возникнуть,  если  окно
имеет поле,  указывающее на одного  из  его  родственников.
Окно  называется  родственным  другому  окну,  если они оба
принадлежат одному и тому же порождающему окну. Например, у
вас есть управляющий элемент редактированием и две кнопки с
независимой  фиксацией,  которые   управляют   активизацией
управляющего   элемента   редактирования.   При   изменении
состояния   кнопки    с    независимой    фиксацией,    она
соответственно активизирует или дезактивизирует управляющий
элемент редактирования.  TActivateRadioButton должна  знать
управляющий элемент редактирования,  который также является
компонентом этого  же  окна,  поэтому  управляющий  элемент
редактирования добавляется в качестве переменной.

     Как и   для   дочерних   окон,  при  чтении  и  записи
родственных  ссылок  в  поток  могут  возникнуть  проблемы.
Решение  также  будет  аналогичным.  Методы  TWindowsObject
PutSiblingPtr  и   GetSiblingPtr   предоставляют   средства
доступа к родственникам:

     type
      TActivateRadioButton=object(TRadioButton)
      EditControl: PEdit;
        .
        .
        .
      constructor Load(var S: TStream);
      procedure Store(var S: TStream); virtual;
        .
        .
        .
     end;

     constructor TActivateRadioButton.Load(var S: TStream);
     begin
       TRadioButton.Load(S);
       GetPeerPtr(S, EditControl);
     end;

     procedure TActivateRadioButton.Store(var S: TStream);
     begin
       TRadioButton.Load(S);
       PutPeerPtr(S, EditControl);
     end;

     Единственно о чем  нужно  побеспокоиться,  так  это  о
загрузке   ссылок  на  родственные  окна,  которые  еще  не
загружены (т.е.  в списке дочерних окон они  идут  ниже  и,
следовательно,    позднее    в    потоке).    ObjectWindows
автоматически обрабатывает  эту  ситуацию,  отслеживая  все
подобные  будущие  ссылки и разрешая их после загрузки всех
дочерних окон.  Вам нужно иметь  в  виду,  что  родственные
ссылки  не  будут  действовать,  пока  Load  не  выполнится
целиком.  Принимая это во внимание, вы не должны помещать в
Load никакой код, который использует дочерние окна, которые
зависят от их родственных окон,  поскольку  в  этом  случае
результат может быть непредсказуемым.


                         Копирование потока
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TStream имеет    метод    CopyFrom(S,Count),   который
копирует заданное число байт (Count) из заданного потока S.
Метод  CopyFrom  может  быть  использован  для  копирования
содержимого одного потока  в  другой.  Если,  например,  вы
циклически   обращаетесь  к  дисковому  потоку,  то  можете
скопировать его в поток EMS для организации более  быстрого
доступа:

    NewStream := New(TEmsStream, Init(OldStream^.GetSize));
     OldStream^.Seek(0);
     NewStream^.CopyFrom(OldStream, OldStream^.GetSize);


                    Потоки произвольного доступа
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     До этого   момента   мы  работали  с  потоками  как  с
устройствами последовательного доступа:  вы помещали  (Put)
объекты  в конец вашего потока и считывали их назад (Get) в
той же последовательности.  Но ObjectWindows имеет и  более
мощные  средства.  Имеется  возможность рассматривать поток
как виртуальное  устройство  произвольного  доступа.  Кроме
методов  Get и Put,  которые соответствуют Read и Write при
работе с  файлом,  потоки  обладают  средствами  проведения
операций Seek, FilePos, FileSize и Truncate.

     - Процедура  потока  Seek перемещает текущий указатель
       потока к заданной  позиции  (число  байт  от  начала
       потока),   как   стандартная  процедура  Seek  языка
       Паскаль.

     - Процедура  GetPos   по   своему   действию   обратна
       процедуре  Seek.  Она  возвращает значение Longint с
       текущей позицией потока.

     - Функция GetSize возвращает размер потока в байтах.

     - Процедура  Truncate  удаляет  все  данные,   которые
       расположены  после текущей позиции потока,  при этом
       текущая позиция потока становится концом потока.

     Поскольку работа с  этими  программами  очень  удобна,
потоки  произвольного  доступа  требуют  от вас отслеживать
индекс,  отмечающий начальную  позицию  каждого  объекта  в
потоке.  В  этом  случае  для  хранения  индекса  вы можете
использовать набор.

                    Необъектные элементы потоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В поток   можно  записывать  и  элементы,  которые  не
являются  объектами,  но  для  этого  следует  использовать
несколько иной подход.  Стандартные методы потока Get и Put
требуют  загрузки  или  записи  объекта,  производного   от
TObject.  Если вам нужно создать поток,  который состоит не
из объектов,  переходите на нижний уровень процедур Read  и
Write,  где  в  поток  записывается или из него считывается
заданное число байт. Этот же механизм используют методы Get
и  Put  для  чтения и записи данных об объектах.  Вы просто
обходите механизм VMT, который заложен в Put и Get.


            Разработка пользователем собственных потоков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Данный раздел   суммирует   возможности   методов    и
обработки ошибок потоков ObjectWindows, чтобы вы знали, что
можно использовать для создания новых типов потоков.

     Сам TStream является абстрактным объектом и его  можно
расширить  для  создания удобного типа потока.  Большинство
методов  TStream  являются  абстрактными  и   должны   быть
реализованы  как  их производные методы,  основывающиеся на
абстрактных методах TStream.  Полностью реализованы  только
методы  Error,  Get и Put.  GetPos,  GetSize,  Read,  Seek,
SetPos,  Truncate и  Write  должны  быть  переписаны.  Если
производный   тип  объекта  имеет  буфер,  то  должен  быть
переписан и метод Flush.


                      Обработка ошибок потока
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TStream имеет   метод   Error(Code,   Info),   который
вызывается  при  обнаружении  ошибки  потока.  Error просто
присваивает полю Status потока значение одной из  констант,
приведенных  в  Главе  21  "Справочник  по ObjectWindows" в
разделе "Константы stXXXX".

     Поле ErrorInfo не определено,  если значение Status не
есть  stGetError или stPutError.  Если значение поля Status
равно  stGetError,  то  поле   ErrorInfo   содержит   номер
идентификатора   потока  незарегистрированного  типа.  Если
значение поля Status равно stPutError,  то  поле  ErrorInfo
содержит смещение VMT типа, который вы пытались поместить в
поток.  Вы можете переписать  TStream.Error  для  генерации
любого   уровня  обработки  ошибок,  включая  ошибки  этапа
выполнения.
- 288 -

                Часть 4. Справочник по ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


                Глава 21. Объектные типы ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Эта глава содержит алфавитный список всех  стандартных
объектных типов ObjectWindows с объяснением их назначения и
использования,  их   операциями,   элементами,   полями   и
методами.  Здесь  описываются также элементы ObjectWindows,
не  являющиеся   частью   стандартной   иерархии   объектов
ObjectWindows.

     Для нахождения  информации  по  определенному  объекту
нужно учитывать,  что многие свойства объектов  в  иерархии
наследуются   от   "предков".   Чтобы  не  дублировать  всю
информацию, эта глава описывает только те элементы данных и
функции,   которые  добавляются  или  изменяются  в  данном
объекте.  Просмотрев диаграмму наследования для объекта, вы
легко можете определить, в каких его предках вводится поле,
а в каких задается или переопределяется метод.

     Перечисленные в  данной  главе  необъектные  элементы,
включая типы,  константы,  переменные, процедуры и функции,
определены в модулях ObjectWindows.  Ниже  приведен  пример
справочной записи для объекта или процедуры:


TSample                                     модуль TSample
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TSample
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДї
     ГДДДДДДґ  і AField       і
     іДInitДі  і AnotherField і
     і Done і  ГДДДДДДДДДДДДДДґ
     і Free і  і Init         і
     АДДДДДДЩ  і Zilch        і
               АДДДДДДДДДДДДДДЩ

     Сначала дается общее описание  объекта,  его  связи  с
дpугими  объектами  и  использование.  На  приведенной выше
диаграмме   показано,   что   объект    TSample    является
непосредственным потомком TObject,  и что он переопределяет
конструктор Init.


                                Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В данном разделе в  алфавитном  порядке  перечисляются
поля  каждого объекта.  Кроме описания поля и его пояснения
показывается режим доступа к данному полю -  только  чтение
или чтение/запись. Поля, доступные только по чтению - это в
общем случае поля,  которые устанавливаются и обслуживаются
методами  объекта  и  которые не должны указываться в левой
части оператора присваивания.

                             AField

     AField: SomeType:                      (только чтение)

     AField -  это   поле,   которое   содержит   некоторую
информацию  о данном примере объекта.  Этот текст пояcняет,
как  оно  функционирует,  что  оно  означает  и   как   его
использовать.

     См. также:    родственные   поля,   методы,   объекты,
глобальные функции и т.д.

                          AnotherField

     AhotherField: Word:                   (чтение/запись)

     Далее следует   поясняющая   информация,   аналогичная
AField.


                               Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В данном   разделе  перечисляются  все  методы,  вновь
определяемые  для  данного  объекта  или   переопределяющие
наследуемые  методы.  Сначала  перечисляются  конструкторы,
затем  деструкторы,  затем  другие  методы   в   алфавитном
порядке.

     Для виртуальных  методов указывается также,  насколько
часто  требуется  переопределять  метод:  никогда,   редко,
иногда, часто или всегда.


                                Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

constructor Init(AParameter: SomeType);

     Init создает новый объект, вызывая сначала конструктор
Init,  наследуемый  из  TObject,  затем  устанавливая  поле
AField в AParameter.

     См. также: TObject.Init


                  Zilch (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Zilch; virtual;

     Процедура Zilch вызывает выполнение объектом некоторых
действий.

     См. также TSomethingElse.Zilch.

Процедура Sample                            (модуль Sample)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: procedure Sample(AParameter);

     Назначение: Sample    выполняет   некоторые   полезные
действия со своим параметром AParemeter.

     См. также: функцию Example.


Процедура Abstract                           модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: procedure Absract;

     Назначение: Вызов данной процедуры завершает программу
с ошибкой этапа выполнения 211. При реализации абстрактного
объектного типа используйте вызов Abstact в тех виртуальных
методах,  которые  должны  переопределяться  в  наследующих
типах.  Это обеспечивает,  что любая  попытка  использовать
экземпляры    абстрактного   объектного   типа   завершится
неуспешно.


Функция AllocMultiSel                       модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: function AllocMultiSel(Count: Integer):
               PMultiSelRec;

     Назначение: Распределяет  TMultiSelRec  со  счетчиком,
равным  Count,   и   пространством   в   поле   Selections,
достаточным для размещения Count выборов (0..Count-1). Если
для  распределения  всей  записи  места   нет,   возвращает
значение nil.


Переменная Application
модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: Application: PApplocation = nil;

     Назначение: В   начале   TApplicationInit   переменная
Application  устанавливается  в @Self,  а в ApplicationDone
сбрасывается в nil.  Таким  образом,  во  время  выполнения
программы  ObjectWindows  Application  указывает  на объект
приложения.

     См. также: TApplication.Init.


Константы bf_XXXX
модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: Командные  кнопки,  кнопки  с  независимой
фиксацией  и  кнопки  с  зависимой   фиксацией   используют
константы   bf_XXXX   для  определения  их  трех  возможных
состояний.

     Значения: Определены следующие значения констант флага
кнопки:

            Константы флагов кнопок           Таблица 21.1
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДї
і    Константа     і  Значение і        Смысл            і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДґ
і    bf_UNCHECKED  і     0     і Элемент не выбран.      і
і    bf_CHECKED    і     1     і Элемент выбран.         і
і    bf_GRAYED     і     2     і Элемент выделен (серый).і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДЩ

Стили кнопок bs_XXXX
модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: Эти  параметры  вы  можете  передавать   в
качестве  параметра  стиля  конструкторам  объектов кнопок,
либо задать стили кнопок при создании  командных  кнопок  с
помощью CreateWindow и CreateWindowEx.

     Значения: В Windows определены следующие константы:

                 Стили кнопок, bs_            Таблица 21.1
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
    Константа                    Смысл                    і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
bs_3State          Этот  стиль  кнопки   является  блоком,і
                   котоpый может быть выбpан,  не выбpан иі
                   затенен.  Затенение (отобpажение сеpым)і
                   обычно используется для указания  того,і
                   что блок заблокиpован.                 і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
bs_Auto3State      Это  то же  самое,  что и bs_3State, ноі
                   в этом случае состояние блока  пеpеклю-і
                   чается автоматически     пpи     щелчкеі
                   "мышью".                               і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
bs_AutoCheckBox    Это  то же самое, что и bs_CheckBox, ноі
                   в этом  случае состояние блока пеpеклю-і
                   чается   автоматически    пpи    щелчкеі
                   "мышью".                               і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
bs_AutoRadioButton Это  то же самое, что и bs_RadioButton,і
                   но в  этом  случае   состояние   кнопкиі
                   пеpеключается  автоматически пpи щелчкеі
                   "мышью", пpи выбоpе кнопки и пpи удале-і
                   нии  отметок выбоpа со всех дpугих кно-і
                   пок в этой гpуппе.                     і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
bs_CheckBox        Этот  стиль  кнопки   является  блоком,і
                   котоpый может   быть   выбpан   или  неі
                   выбpан. Связанный с ним текст помещает-і
                   ся спpава от блока.                    і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
bs_DefPushButton   Это  тот  же  стиль кнопки, что и стильі
                   bs_PushButton, за исключением того, чтоі
                   данная кнопка пpинимается по умолчанию,і
                   если только с помощью "мыши" или с кла-і
                   виатуpы  не  выбpана  дpугая кнопка илиі
                   блок.                                  і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
bs_GroupBox        Этот  стиль  кнопки является блоком дляі
                   гpуппиpования дpугих кнопок.  Связанныйі
                   с ней текст помещается в левый  веpхнийі
                   угол.                                  і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
bs_LeftText        Пpи использовании со стилями bs_3State,і
                   bs_CheckBox или  bs_RadioButton,   этоті
                   стиль вызывает pазмещение текста слева,і
                   а не спpава от кнопки или блока.       і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
bs_OwnerDraw       Этот  стиль  кнопки  является  кнопкой,і
                   отображаемой владельцем.  Кpоме обычныхі
                   кодов уведомления, посылаемых чеpез со-і
                   общение wm_Command,  порождающий объекті
                   также получает запpос на pаскpаску, ин-і
                   веpтиpование и блокиpование кнопки.    і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
bs_PushButton      Этот стиль кнопки пpедставляет кнопку сі
                   любым помещенным внутpи ее связанным  сі
                   ней текстом.                           і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
bs_RadioButton     Этот  стиль кнопки пpедставляет малень-і
                   кую кpуглую кнопку,  котоpая может бытьі
                   или выбpана или не выбpана. Связанный сі
                   ней текст помещается спpава от  кнопки.і
                   Селективные  кнопки обычно используютсяі
                   в гpуппах,  в котоpых  каждый  pаз  вы-і
                   биpается одна и только одна кнопка.    і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     См. также:        TButton.Init.        TCheckBox.Init,
TRadioButton.Init.


Переменная BWCCClassNames
модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: BWCCClassNames: Boolean = False;

     Назначение: Указывает,  использует ли приложение имена
класса окна специализированные управляющие элементы Borland
(BWCC).  Инициализация  кода  модуля   BWCC   устанавливает
BWCCClassNames  в  True,  так что включение BWCC в оператор
uses программы автоматически устанавливает  BWCCClassNames.
"Нажимаемые" командные кнопки, объекты кнопок с назависимой
и зависимой фиксацией в приложениях  Windows,  использующие
BWCC, автоматически применяют имена класса BWCC.

     Если вы  хотите,  чтобы  ваши  программы  для работы с
управляющими элементами BWCC и не BWCC, то можете выполнять
загрузку   из   различных  источников  на  основе  значения
BWCCClassNames.

     См. также: методы GetClassName.


Стили комбинированного блока cbs_XXXX
модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Функция: Вы   можете   передавать   эти   константы  в
параметрах  стиля  конструкторов  объекта  комбинированного
блока  или  для  задания  стилей комбинированных блоков при
создании   комбинированных   блоков   с   помощью   функций
CreateWindows и CreateWindowsEx.

     Значения: Windows определяет следующие значения

             Стили комбинированных блоков      Таблица 21.3
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
    Константа                    Смысл                    і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
cbs_AutoHScroll      Этот  стиль  комбиниpованного   блокаі
                     пpокpучивает текст в управляющем эле-і
                     менте  pедактиpования  впpаво,  когдаі
                     пользователь вводит  символ  в  концеі
                     стpоки.  Без  этого стиля ввод текстаі
                     за пpеделами гpаниц управляющего эле-і
                     мента редактирования был бы  невозмо-і
                     жен.                                 і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
cbs_DropDown         Этот   стиль   то   же   самое,   чтоі
                     cbs_Simple, но  здесь   блок   спискаі
                     отобpажается тогда,  когда выбиpаетсяі
                     пиктогpамма,  следующая за полем  вы-і
                     боpа.                                і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
cbs_DropDownList     Этот   стиль   то   же    самое,  чтоі
                     cbs_DropDown, но здесь для  отобpаже-і
                     ния текущего выбоpа используется ста-і
                     тический текст, а не элемент упpавле-і
                     ния pедактиpованием.                 і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
cbs_HasStrings       Этот  стиль может быть использован в і
                     сочетании со                   стилемі
                     cbs_OwnerDrawFixed     или     стилемі
                     cbs_OwnerDrawVariable.  Этот стиль  ві
                     качестве элементов использует стpоки.і
                     Стpоки обслуживаются системой и могуті
                     быть   считаны  с  помощью  сообщенияі
                     cb_GetLBText.                        і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
cbs_NoIntegralHeihgt Этот  стиль   комбиниpованного  блокаі
                     является в точности pазмеpом,  задан-і
                     ным  пpи  создании   комбиниpованногоі
                     блока.  Обычно  pазмеp,  используемыйі
                     для создания комбиниpованного  блока,і
                     может   изменяться,  поэтому,  комби-і
                     ниpованный блок не отобpажает частич-і
                     ные элементы.                        і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
cbs_OEMConvert       Этот  стиль  может быть использован ві
                     сочетании со стилями  cbs_Simple  илиі
                     cbs_DropDown.   Этот   стиль   комби-і
                     ниpованного  блока  пеpеводит  каждыйі
                     символ,  введенный в элемент упpавле-і
                     ния комбиниpованного блока из  набоpаі
                     символов ANSI в набоp символов OEM, иі
                     обpатно.  Тогда,  в пpименении к эле-і
                     ментам в блоке списка комбиниpованно-і
                     го блока  или  к  тексту  в  элементеі
                     упpавления   pедактиpованием   комби-і
                     ниpованного блока  функция  AnsiToOemі
                     будет   pаботать   коppектно.  Стилемі
                     cbs_OEMConvert  удобно   пользоватьсяі
                     для комбиниpованных блоков,  содеpжа-і
                     щих имена файлов.                    і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
cbs_OwnerDrawFixed   Этот   стиль  комбиниpованного  блокаі
                     должен pисоваться его владельцем. Всеі
                     элементы в блоке списка комбиниpован-і
                     ного блока имеют одну и ту же высоту.і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
cbs_OwnerDrawVariableЭтот  стиль  комбиниpованного   блокаі
                     должен рисоваться   его   владельцем.і
                     Элементы в блоке списка комбиниpован-і
                     ного блока имеют пеpеменную высоту.  і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
cbs_Simple           Этот  стиль   комбиниpованного  блокаі
                     постоянно отобpажает  свой блок спис-і
                     ка.  Текущий выбоp  из  блока  спискаі
                     отобpажается   в   оpгане  упpавленияі
                     pедактиpованием.                     і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
cbs_Sort             Этот   стиль  комбиниpованного  блокаі
                     имеет отсоpтиpованный   блок  списка.і
                     Поpядок соpтиpовки для  комбиниpован-і
                     ных       блоков      со      стилямиі
                     cbs_OwnerDrawFixed                  иі
                     cbs_OwnerDrawVariable может быть раз-і
                     ным.                                 і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     См. также: TComboBox.Init.


Константы cm_XXXX
модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: ObjectWindows     определяет     несколько
констант,   определяющих   диапазоны   констант   командных
сообщений.

     Значения: Определены следующие командные константы:

           Константы командных сообщений      Таблица 21.4
ДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДї
Константа   і    Значение       і      Смысл             і
ДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
cm_First    і   $A000           і Начало командного сооб-і
            і                   і щения.                 і
ДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
cm_Count    і   $6000           і Число командных сообще-і
            і                   і ний.                   і
ДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
cm_Internal і   $FF00           і Начало командных  сооб-і
            і                   і щений,  зарезервирован-і
            і                   і ных для внутреннего ис-і
            і                   і пользования.           і
ДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДґ
cm_Reserved і        cm_Internal - cm_First              і
ДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

Константы cm_ определены для трех меню: File, Edit и Window

              Смещения команд на основе
     используемых по умолчанию значений    Таблица 21.5
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДї
Константа            Значение           і Эквивалент менюі
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
cm_EditCut        cm_Reserved + 0       і    EditіCut    і
cm_EditCopy       cm_Reserved + 1       і    EditіCopy   і
cm_EditPaste      cm_Reserved + 2       і    EditіPaste  і
cm_EditDelete     cm_Reserved + 3       і    EditіDelete і
cm_EditClear      cm_Reserved + 4       і    EditіClear  і
cm_EditUndo       cm_Reserved + 5       і    EditіUndo   і
cm_EditFind       cm_Reserved + 6       і    EditіFind   і
cm_EditReplace    cm_Reserved + 7       і    EditіReplaceі
cm_EditFindNext   cm_Reserved + 8       і    EditіSearch і
                                        і     Again      і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
cm_FileNew        cm_Reserved + 9       і    EditіNew    і
cm_FileOpen       cm_Reserved + 10      і    EditіOpen   і
cm_MDIFileNew     cm_Reserved + 11      і    EditіNew    і
cm_MDIFileOpen    cm_Reserved + 12      і    EditіOpen   і
cm_FileSave       cm_Reserved + 13      і    EditіSave   і
cm_FileSaveAs     cm_Reserved + 14      і    EditіSave Asі
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
cm_ArrangeIcons   cm_Reserved + 15      і    Windowsі    і
                                        і   Arrange Iconsі
cm_TileChildren   cm_Reserved + 16      і    WindowsіTileі
cm_CascadeChildrencm_Reserved + 17      і    Windowsі    і
                                        і     Cascade    і
cm_CreateChild    cm_Reserved + 18      і    Windowsі    і
                                        і   Close All    і
cm_Exit           cm_Reserved + 20      і    FileіExit   і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДЩ


Константы coXXXX
модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: Когда    TCollection    обнаруживает   при
операции  ошибку,  константы   coXXXX   передаются   методу
TCollection.Error в качестве параметра Code.

     Значения: Для  всех  стандартных наборов ObjectWindows
определены следующие стандартные коды ошибок:

               Коды ошибок наборов           Таблица 21.6
ДДДДДДДДДДДДДДДВДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДї
Код ошибки     і Значение   і          Смысл            і
ДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
coIndexError   і    -1      і Индекс вне диапазона.  Па-і
               і            і раметр Info,    переданныйі
               і            і методу Error, содержит не-і
               і            і допустимое значение индек-і
               і            і са.                       і
ДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
coOverflow     і    -2      і Переполнение       набора.і
               і            і TCollection.SetLimit    неі
               і            і удалось  расширить   наборі
               і            і до требуемого размера. Пе-і
               і            і реданный  методу Error па-і
               і            і раметр содержит  требуемыйі
               і            і размер.                   і
ДДДДДДДДДДДДДДДБДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     См. также: объект TCollection.



Стили класса cs_XXXX
модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: Эти    константы   стилей   классов   окон
используются в поле стиля структуры  данных  WNDCLASS.  Они
могут объединяться с помощью операций OR.

                 Стили классов cs_            Таблица 21.7
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Константа                    Смысл
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
cs_ByteAlignClient
                Область  пользователя  окна  выровнена  на
                границу байта в направлении x.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
cs_ByteAlignWindow
                Окно выровнено  на границу байта в направ-
                лении x.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
cs_ClassDC      Экземпляры класса окна разделяют между со-
                бой их собственный контекст дисплея.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
cs_DblClks      Окно  будет получать сообщения от двойного
                щелчка "мышью".
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
cs_ClobalClass  Класс  окна  может   использоваться  всеми
                работающими прикладными задачами.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
cs_HRedraw      Если горизонтальные размеры окна изменяют-
                ся, то будет перерисовано все окно.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
cs_NoClose      Команда  выбора  Close  меню  Control окна
                заблокирована.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
cs_OwnDC        Каждый  экземпляр  окна получает свой соб-
                ственный контекст дисплея.  Использует 800
                байт памяти на каждое окно.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
cs_ParentDC     Окно использует контекст дисплея порождаю-
                щего окна.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
cs_SaveBits     Если  содеpжимое  окна  в данный момент не
                отобpажается, оно сохpаняется в каpте бит.
                Эта  каpта бит используется для повтоpного
                отобpажения содеpжимого.  Используется ми-
                нимальным обpазом.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
cs_VRedraw      Если веpтикальные pазмеpы окна изменяются,
                то будет пеpеpисовано все окно.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     См. также: TWindowsObject.GetWindowClass.



Константа cw_UseDefault
модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Назначение: Константа cw_UseDefault сообщает Windows о
назначении  позициям  создаваемого  окна  используемого  по
умолчанию размера.  Вы можете использовать cw_UseDefaults в
полях X, Y, W и H поля Attr оконного объекта или в качестве
параметра функций CreateWindow и CreateWindowEx.

     См. также: тип TWindowAttr.


Процедура DoneMemory
модуль OMemory
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Описание: procedure DoneMemory;

     Функция: Освобождает  память,  выделенную  для  буфера
безопасности.

     См. также: процедура InitMemory.



Константы em_XXXX
модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Назначение: Некоторые  стандартные  состояния   ошибок
отмечаются константами ObjectWindows, начинающимися с em_.

     Значения: Определены следующие флаги ошибки:

             Константы условия ошибки         Таблица 21.8
ДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДД
Константа              іЗначениеі           Смысл
ДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДД
em_InvalidWindow       і   -1   і Окно   недопустимо  из-за
                       і        і неуспешного    выполнения
                       і        і Create.
ДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДД
em_OutOfMemory         і   -2   і Распределение памяти пре-
                       і        і высило  буфер безопаснос-
                       і        і ти.
ДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДД
em_InvalidClient       і   -3   і Не может быть создано ок-
                       і        і но клиента MDI.
ДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДД
em_InvalidChild        і   -4   і Одно или  более  дочерних
                       і        і окон не является допусти-
                       і        і мым.
ДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДД
em_InvalidMainWindow   і   -5   і Основное  окно  не  может
                       і        і быть создано.
ДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДД


Переменная EmsCurHandle
модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Описание: EmsCurHandle: Word = $FFFF;

     Назначение: Содержит    текущий     описатель     EMS,
отображенный   TEmsStream  в  физическую  страницу  0  EMS.
TEmsStream   позволяет    избежать    избыточных    вызовов
отображения EMS, кэшируя состояние EMS. Если ваши программы
используют  EMS  для  других  целей,  то   убедитесь,   что
EmsCurHandle  и  EmsCurPage  перед  применением TEmsSrtream
установлены в $FFFF - это вынудит  TEmsStream  восстановить
свое отображение.

     См. также TEmsStream.Handle.


Переменная EmsCurPage
модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: EmsCurPage: Word = $FFFF;

     Назначение: Содержит  описатель  логической   страницы
EMS,  отображенный  TEmsStream  в  физическую страницу EMS.
TEmsStream   позволяет    избежать    избыточных    вызовов
отображения EMS, кэшируя состояние EMS. Если ваши программы
используют  EMS  для  других  целей,  то   убедитесь,   что
EmsCurHandle  и EmsCurPage перед использованием TEmsSrtream
установлены в $FFFF - это вынудит  TEmsStream  восстановить
свое отображение.

     См. также TEmsStream.Handle.


Стили управляющих элементов es_XXXX
модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: Эти константы  используются  для  указания
стилей  упpавляющих  элементов  pедактиpования пpи создании
последних с помощью функций CreateWindow и CreateWindowEx.

Стили упpавляющих элементов редактирования es_
                                               Таблица 21.9
ДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
 Константа       і                  Смысл
ДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
es_AutoHScroll   і Этот стиль управляющего  элемента редак-
                 і тирования автоматически     пpокpучивает
                 і текст впpаво на 10  символов  пpи  вводе
                 і символа  в  конце  стpоки.  Пpи  нажатии
                 і Enter текст пpокpучивается назад до  ну-
                 і левой позиции.
ДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
es_AutoVScroll   і Этот стиль  упpавляющего элемента редак-
                 і тирования автоматически     пpокpучивает
                 і текст на одну стpаницу ввеpх,  когда пpи
                 і вставке в конце стpоки нажимается Enter.
ДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
es_Center        і Этот стиль  упpавляющего элемента pедак-
                 і тиpования центpиpует  текст.  Может  ис-
                 і пользоваться только в случае, если также
                 і используется стиль es_MultiLine.
ДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
es_Left          і Этот стиль  упpавляющего элемента pедак-
                 і тиpования выpавнивает текст слева. Может
                 і использоваться  только  в  случае,  если
                 і также используется стиль es_MultiLine.
ДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
es_LowerCase     і Этот стиль  упpавляющего элемента редак-
                 і тирования пpеобpазует пpи вводе все сим-
                 і волы в символы нижнего pегистpа.
ДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
es_MultiLine     і Этот стиль  упpавляющего элемента редак-
                 і тирования является многостpочным оpганом
                 і pедактиpования. Стиль es_AutoVScroll мо-
                 і жет   использоваться  только  со  стилем
                 і es_MultiLine.  Если стиль es_AutoVScroll
                 і не используется,  то при нажатии клавиши
                 і Enter пpи вставке  в  последней  стpоке,
                 і выдается  звуковой  сигнал.  Если  стиль
                 і es_AutoVScroll не используется, то вновь
                 і вводимые слова пpи необходимости автома-
                 і тически пеpеносятся на следующую стpоку.
                 і Пpи изменении pазмеpов окна позиции этих
                 і пеpенесенных слов будут изменяться. Мно-
                 і гостpочный оpган упpавления pедактиpова-
                 і нием с полосами пpокpутки сам  обpабаты-
                 і вает свои сообщения полосы пpокpутки;  в
                 і пpотивном случае,  пpокpутка выполняется
                 і автоматически описанным выше обpазом.
ДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
es_NoHideSel     і Этот стиль  упpавляющего элемента редак-
                 і тирования не делает невидимым выбоp  пpи
                 і потеpе этим управляющим элементом фокуса
                 і ввода. По умолчанию, пpи потеpе упpавля-
                 і ющим элементо pедактиpования фокуса вво-
                 і да выбоp делается невидимым.
ДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
es_OEMConvert    і Этот стиль  упpавляющего элемента редак-
                 і конвеpтиpует введенный  текст  из набоpа
                 і символов ANSI в  набоp  символов  OEM  и
                 і обpатно. В этом случае функция AnsiToOem
                 і будет вести себя коppектно пpи  пpимене-
                 і нии  к  тексту управляющего элемента ре-
                 і дактирования. Стиль es_OEMConvert удобно
                 і использовать  для  упpавляющих элементов
                 і pедактиpования, содеpжащих имена файлов.
ДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
es_Password      і Все  символы,  введенные  в  управляющий
                 і элемент  pедактиpования,    отобpажаются
                 і как  '*'.  Для  изменения  отобpажаемого
                 і символа  может  использоваться сообщение
                 і em_SetPasswordChar.
ДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
es_Right         і Этот стиль  упpавляющего элемента редак-
                 і тирования выpавнивает текст спpава.  Мо-
                 і жет использоваться только в случае, если
                 і также используется стиль es_MultiLine.
ДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
es_UpperCase     і Этот стиль  упpавляющего элемента редак-
                 і тирования пpеобpазует пpи вводе все сим-
                 і волы в символы веpхнего pегистpа.
ДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     См. также: TEdit.Init.


Процедура FreeMultiSel
модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

   Описание: procedure FreeMultiSel(P: PMultiSelRec);

   Освобождает запись TMultiRec, выделенную AllocMultiSel.

   См. также: AllocMultiSel, TMultiSelRec.


Константа tsFileSpec                      модуль OStdDlgs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: fsFileSpec = fsFileName + fsExtension

     Назначение: Задает  длину  имени  файла.   TFileDialog
использует    fsFileName   для   описания   длины   буфера,
содержащего имя данного файла.


Константы id_XXXX                          модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: ObjectWindows     определяет     несколько
констант, задающих диапазоны дочерних идентификаторов.

     Значения: Определены   следующие  константы  сообщений
порожденного идентификатора:

Константы сообщений дочернего идентификатора  Таблица 21.10
ДДДДДДДДДДДДДДДДВДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Константа       і Значениеі             Смысл
ДДДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
id_First        і $8000   і Начало сообщений дочерний иден-
                і         і тификаторов.
ДДДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
id_Count        і $1000   і Число сообщений дочерних  иден-
                і         і тификаторов.
ДДДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
id_Internal     і $8F00   і Зарезервировано для внутреннего
                і         і использования.
ДДДДДДДДДДДДДДДДЕДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
id_Reserved     іid_Internal - id First
ДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДД
id_FirstMDIChildіid_Reserved + 1        і Начало    номеров
                і                       і порожденных иден-
                і                       і тификаторов.
ДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДД
id_MDIClient    іid_Reserved + 2        і Номер   дочернего
                і                       і идентификатора
                і                       і клиента MDI.
ДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДД

     Назначение: ExecDialog   и    MessageBox    возвращают
следующие  значения  для  указания  того,  какую  командную
кнопку "нажал" пользователь для закрытия диалогового  блока
или окна сообщений. Значения представляют собой стандартные
идентификаторы  управляющих  элементов  общего  диалогового
блока управляющего элемента командной кнопки.


     Значения: Windows определяет следующие идентификаторы:

                   Константы командных
           идентификаторов диалогового блока Таблица 21.11
       ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДї
       і      Константа      і          Смысл            і
       ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
       і     id_Abort        і Была нажата кнопка Abort. і
       і     id_Cancel       і Была нажата кнопка Cancel.і
       і     id_Ignore       і Была нажата кнопка Ignore.і
       і     id_No           і Была нажата кнопка No.    і
       і     id_Ok           і Была нажата кнопка OK.    і
       і     id_Retry        і Была нажата кнопка Retry. і
       і     id_Yes          і Была нажата кнопка Yes.   і
       АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     См. также: TApplication.ExecDialog.


Процедура InitMemory                       модуль OMemory
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: procedure InitMemory;

     Назначение: Путем вызова ResrtoreMemory инициализирует
буфер  безопасности,  затем  устанавливает  функцию  ошибки
динамически      распределяемой       области       памяти.
TApplication.Init вызывает InitMemory.

     См, также: процедуры DoneMemory, RestoreMemory.


Стили блока списка lbs_XXXX                 модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: Эти константы используются для опpеделения
стилей блока списка,  пpи создании блоков списка с  помощью
функции CreateWindow и CreateWindowEx.


     Значения: Windows определяет следующие стили:

             Стили блока списка lbs_         Таблица 21.12
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
    Константа                      Смысл
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_ExtendedSel        Этот  стиль  блока  списка позволяет
                       выбиpать несколько элементов  с  по-
                       мощью клавиши Shift и "мыши" или не-
                       котоpой дpугой комбинации клавиш.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_HasStrings         Этот стиль может  быть использован в
                       сочетании со  cbs_OwnerDrawFixed или
                       cbs_OwnerDrawVariable.  Этот стиль в
                       качестве     элементов    использует
                       стpоки.  Стpоки обслуживаются систе-
                       мой  и  могут быть считаны с помощью
                       сообщения lb_GetLBText.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_MultiColumn        Этот стиль блока списка  имеет  нес-
                       колько столбцов,  котоpые согут быть
                       пpокpучены  по  гоpизонтали.  Шиpина
                       столбца может быть установлена с по-
                       мощью сообщения lb_SetColumnWidth.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_MultipleSel        Этот  стиль  блока  списка позволяет
                       выбиpать несколько  элементов  с по-
                       мощью "мыши".  Пpи каждом  одиночном
                       или  двойном щелчке мыши элемент из-
                       меняет свое состояние выбоpа.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_NoIntegralHeihgt   Этот  стиль  блока списка является в
                       точности pазмеpом, заданным пpи соз-
                       дании блока списка.  Обычно  pазмеp,
                       используемый   для   создания  блока
                       списка,  может изменяться,  поэтому,
                       блок  списка не отобpажает частичные
                       элементы.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_NoRedraw           Этот стиль блока списка не пеpеpисо-
                       вывается пpи внесении изменений. Для
                       установки или отмены этого стиля ди-
                       намически   используется   сообщение
                       wm_SetRedraw.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_Notify             Этот стиль  блока списка имеет вход-
                       ное сообщение,  посланное его порож-
                       дающему  окну  пpи  выбоpе  элемента
                       одиночным  или  двойным щелчком "мы-
                       ши".
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_OwnerDrawFixed     Этот стиль блока списка  отвечает за
                       pисование его содеpжимого;  элементы
                       в блоке списка имеют одну  и  ту  же
                       высоту.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_OwnerDrawVariable  Этот  стиль блока списка отвечает за
                       pисование его содеpжимого;  элементы
                       в  блоке списка имеют пеpеменную вы-
                       соту.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_OwnerDrawFixed     Этот стиль блока списка должен pисо-
                       ваться его владельцем.  Все элементы
                       в блоке списка имеют одну  и  ту  же
                       высоту.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_OwnerDrawVariable  Этот  стиль блока списка отвечает за
                       pисование его содеpжимого;  элементы
                       в  блоке списка имеют пеpеменную вы-
                       соту.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_OwnerDrawFixed     Этот стиль блока списка должен pисо-
                       ваться его владельцем.  Все элементы
                       в блоке списка имеют одну  и  ту  же
                       высоту.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_OwnerDrawVariable  Этот стиль блока списка должен pисо-
                       ваться его  владельцем.  Элементы  в
                       блоке списка имеют pазную высоту.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_Sort               Этот стиль блока списка имеет отсоp-
                       тиpованные элементы.         Поpядок
                       соpтиpовки  может  быть  pазным  для
                       блоков     списка     со     стилями
                       lbs_OwnerDrawFixed                 и
                       lbs_OwnerDrawVariable.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_Standard           Этот стиль - то  же самое, что стили
                       lbs_Notify и  lbs_Sort,  вместе взя-
                       тые.  Блок списка имеет  гpаницы  со
                       всех стоpон.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_UseTabStops        Этот  стиль  блока  списка позволяет
                       использовать в  его  элементах  pас-
                       шиpенные позиции табуляции. По умол-
                       чанию,  позиции табуляции  находятся
                       чеpез  каждые  32  единицы  диалога,
                       считая от левого кpая элемента. Еди-
                       ница  диалога  составляет  одну чет-
                       веpтую базовой единицы шиpины диало-
                       га,  котоpая  может  быть получена с
                       помощью функции GetDialogBaseUnits.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
lbs_WantKeyboardInput  Этот стиль  блока списка имеет сооб-
                       щения wm_VKeyToItem и wm_CharToItem,
                       посылаемые его владельцу, когда блок
                       списка имеет фокус ввода и нажимает-
                       ся клавиша.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     См. также: TListBox.Init.


Функция LongDiv                             модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: function LongDiv(X: Longint; Y: Integer):
               Integer;
                   inline($59/$58/$5A/$F7/$F9);

     Назначение: Быстрая подставляемая подпрограмма деления
на  языке  ассемблера,  возвращающая целочисленное значение
X/Y.


Функция LongMul                             модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: function LongMul(X: Longint; Y: Integer):
                        Longint;
                   inline($5A/$58/$F7/$EA);

     Назначение: Быстрая     подставляемая     подпрограмма
умножения  на языке ассемблера,  возвращающая целочисленное
значение X*Y.


Тип LongRec                                  модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание:

     LongRec = record
        Lo, Hi: Word;
     end;

     Назначение: Тип записи,  который полезно  использовать
для работы с переменными размером в двойное слово.


Функция LoMemory                             модуль OMemory
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: function LoMemory: Boolean;

     Назначение: Функция LoMemory возвращает значение True,
если   при   распределении   памяти   задействован    буфер
безопасности  в  конце  динамически  распределяемой области
памяти.  Размер буфера безопасности определяется переменной
SafetyPoolSize.  Функция LowMemory автоматически вызывается
в   TApplication.MakeWindow   и    TApplication.ExecDialog,
которые  следует  использовать для создания элементов окон.
Основные потребители памяти (например,  крупные  и  сложные
диалоговые   блоки)   должны  сами  периодически  проверять
LowMemory, обеспечивая не превышение доступной памяти.

     См. также:     TApplication.ValidWindow,     MemAlloc,
SafetyPoolSize.


Тип MakeIntResource                        модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: MakeIntResource = PStr;

     Функция: Чтобы    задать    ресурс   по   номеру   его
идентификатора, вы должны преобразовать число в специальный
тип MakeIntResource.  MakeIntResource идентичен типу PChar,
но  использование  этого  названия  типа  делает  программу
понятнее.


Переменная MaxCollectionSize                модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: MaxCollectionSize      =      65520      div
SizeOf(Pointer);

     Назначение: MaxCollection   определяет    максимальное
число элементов,  которые могут содержаться в наборе, что в
сущности равно числу указателей, которые можно разместить в
сегменте памяти объемом 64К.


Флаги блоков mb_XXXX                        модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Эти флаги   задают   характеристики  блока  сообщения,
созданного функцией MessageBox.  Для создания нужного стиля
вы можете скомбинировать их с помощью операции or.

            Флаги блока сообщений mb_         Таблица 21.13
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
    Константа                       Смысл                 і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_AbortRetryIgnoreВключить  только  одну из кнопок Abort,і
                   Retry, Ignore.                         і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_ApplModal       Создать  модальный  блок  сообщений (поі
                   умолчанию).                            і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_DefButton1      Кнопкой,  пpинимаемой по умолчанию, яв-і
                   ляется пеpвая кнопка.                  і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_DefButton2      Кнопкой,  пpинимаемой по умолчанию, яв-і
                   ляется втоpая кнопка.                  і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_DefButton3      Кнопкой,  пpинимаемой по умолчанию, яв-і
                   ляется тpетья кнопка.                  і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_IconAsterisk    То же, что и mb_IconInformation.       і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_IconExclamation Включить пиктогpамму '!'.              і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_IconHand        То же, что и mb_IconStop.              і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_IconInformation Включить пиктогpамму 'i'.              і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_IconQuestion    Включить пиктогpамму '?'.              і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_IconStop        Включить пиктогpамму знака "стоп".     і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_OK              Включить только кнопку OK.             і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_OKCancel        Включить только кнопки OK и Cancel.    і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_RetryCancel     Включить только кнопки Retry и Cancel. і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_SystemModal     Создать  режимный  блок  сообщений, ко-і
                   тоpый пpиостанавливает  pаботу Windows.і
                   Его pекомендуется использовать в потен-і
                   циально аваpийных ситуациях.           і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_TaskModal       Этот флаг используется, если  нет  дос-і
                   тупного pодительского окна.  Если в ка-і
                   честве паpаметpа  предка указать значе-і
                   ние 0, pабота всех окон веpхнего уpовняі
                   в пpикладной задаче будет пpиостановле-і
                   на.                                    і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_YesNo           Включить только кнопки Yes и No.       і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
mb_YesNoCancel     Включить  только  кнопки   Yes,   No  иі
                   Cancel.                                і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Для гpупп констант mb_ определяется несколько  битовых
масок.

            Маски флага блока сообщений      Таблица 21.14
ДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
 Константа    і                      Смысл
ДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
mb_DefMask    і mb_DefButton1, mb_DefButton2, mb_DefButton3
ДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
mb_IcknMask   і mb_IconAsterisk, mb_IconExclamation,
              і mb_IconHand, mb_IconInformation,
              і mb_IconQuestion, mb_IconStop
ДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
mb_ModeMask   і mb_ApplModal, mb_SystemModal, mb_TaskModal
ДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
mb_TypeMask   і mb_AbortRetryIgnore, mb_OK, mb_OKCancel,
              і mb_RetryCancel, mb_SystemModal, mb_YesNo,
              і mb_YesNoCancel
ДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     См. также: функцию MessageBox.


Функция MemAlloc                            модуль OMemory
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: function MemAlloc(Size: Word): Pointer;

     Назначение: Выделяет Size байт в оперативной памяти  и
возвращает   указатель  на  блок.  Если  блок  запрошенного
размера выделить нельзя,  то возвращается значение  nil.  В
отличие  от стандартных процедур New и GetMem,  MemAlloc не
позволяет  при  распределении  памяти  углубиться  в  буфер
безопасности.  Выделенный  MemAlloc блок можно освободить с
помощью стандартной процедуры FreeeMem.


Функция MemAllocSeg                          модуль OMemory
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: function MemAllocSeg(Size: Word): Pointer;

     Выделяет блок памяти, выровненный на границу сегмента.
Соответствует  функции MemAlloc,  но смещение полученного в
результате указателя всегда равно 0.

     См. также: функцию MemAlloc.


Константы nf_XXXX                          модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: ObjectWindows     определяет     несколько
констант, задающих диапазоны уведомляющих сообщений.

     Значения: Определены следующие константы:

          Константы уведомляющих сообщений    Таблица 21.15
ДДДДДДДДДДДДДДВДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
Константа     і Значение і          Смысл                і
ДДДДДДДДДДДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
nf_First      і $9000    і Начало уведомляющих сообщений.і
ДДДДДДДДДДДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
nf_Count      і $1000    і Число уведомляющих сообщений. і
ДДДДДДДДДДДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
nf_Internal   і $9F00    і Начало уведомляющих сообщений,і
              і          і зарезервированных для внутрен-і
              і          і него использования.           і
ДДДДДДДДДДДДДДБДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


Константы pf_XXX                          модуль OPrinter
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows определяет  ряд  констант,  используемых
для установки флагов в объектах распечатки.

     Определены следующие константы:

             Константы флага распечатки       Таблица 21.16
ДДДДДДДДДДДДВДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
Константа   іЗначениеі             Смысл                і
ДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
pf_Graphics і  $01   і Текущая модель воспринимает толь-і
            і        і ко графику.                      і
ДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
pf_Text     і  $02   і Текущая модель воспринимает толь-і
            і        і ко текст.                        і
ДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
pf_Both     і  $03   і Текущая   модель  воспринимает  иі
            і        і текст, и графику.                і
ДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
pf_Banding  і  $04   і Устанавливается, если  распечаткаі
            і        і задана для текущей модели.       і
ДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
pf_Selectionі  $08   і Печать с текущим выбором.        і
ДДДДДДДДДДДДБДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

Константы ps_XXXX                         модуль OPrinter
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ObjectWindows определяет      несколько      констант,
используемых объектами принтера для  определения  состояния
принтера.


     Определены следующие константы:

            Константы состояния принтера     Таблица 21.17
ДДДДДДДДДДДДДДДДДВДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
 Константа       і  Зні             Смысл                і
ДДДДДДДДДДДДДДДДДЕДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ps_Ok            і   0і Нет ошибки.                      і
ДДДДДДДДДДДДДДДДДЕДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ps_InvalidDevice і  -1і Параметр устройства неверен.     і
ДДДДДДДДДДДДДДДДДЕДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ps_Anassociated  і  -2і Параметр распечатки не имеет свя-і
                 і    і занного с ним устройства печати. і
ДДДДДДДДДДДДДДДДДБДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ



Тип PString                                 модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: PString = ^String;

     Назначение: Определяет указатель на строку Паскаля.


Тип PtrRec                                  модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание:

     PtrRec = record
        Ofs, Seg: Word;
     end;

     Функция: Запись,   содержащая   значения   сегмента  и
смещения указателя.


Процедура RegisterODialogs                  модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: procedure RegistersODialogs;

     Назначение: Вызывает  RegisterType  для   каждого   из
стандартных   объектных   типов,   определенных   в  модуле
ODialogs:   TDialog,   TDlgWindow,    TControl,    TButton,
TCheckBox,  TRadioButton,  TGroupBox,  TListBox, TComboBox,
TScrollBar,  TStatic и TEdit. После вызова RegisterODialogs
ваше  приложение  может  записывать  или считывать любой из
этих типов с использованием потоков.

     См. также: процедуру RegisterType.


Процедура RegisterOStdWnds                модуль OSrdWnds
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: procedure RegisterOStdWnds;

     Назначение: Вызывает  RegisterType  для   каждого   из
стандартных   объектных   типов,   определенных   в  модуле
OStdWnds:   TEditWindow   и   TFileWindow.   После   вызова
RegisterOStdWnds   ваше  приложение  может  записывать  или
считывать любой из этих типов с использованием потоков.

     См. также: процедуру RegisterType.


Процедура RegisterOWindows                 модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: procedure RegisterOWindows;

     Назначение: Вызывает  RegisterType  для   каждого   из
стандартных   объектных   типов,   определенных   в  модуле
OWindows:  TWindows,  TMDIWindow,  TMDIClient и  TScroller.
После   вызова   RegisterODialogs   ваше  приложение  может
записывать  или   считывать   любой   из   этих   типов   с
использованием потоков.

     См. также: процедуру RegisterType.


Процедура RegisterType                     модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: procedure RegisterType(var S: TStreamRec);

     Назначение: Объектный  тип  ObjectWindows  должен быть
зарегистрирован с помощью этого метода перед  тем  как  его
можно   будет   использовать   в   потоковом  вводе-выводе.
Стандартные   объектные   типы   являются    предварительно
зарегистрированными   со  значениями  ObjType  в  диапазоне
0..99.  RegisterType  создает  запись  в  связанном  списке
записей TStreamRec.

     См. также: TStream.Get, TStreamPut, TStreamRec.


Процедура RegisterValidate                 модуль Validate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: procedure RegisterValidate;

     Назначение: Вызывает   RegesterType   для  каждого  из
объектных типов проверки допустимости  в  модуле  Validate:
TPXPictureValidator,   TFilterValidator,   TRangeValidator,
TLookupValidator   и   TStringValidator.    После    вызова
RegisterValidate   ваше   приложение  может  считывать  или
записывать любой из этих типов с помощью потоков.

     См. также: процедуру RegisterType.


Процедура RestoreMemory                     модуль OMemory
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: procedure RestoreMemory;

     Если LowMemory равно True, что указывает на отсутствие
буфера   надежности,   выделяет   для   буфера   надежности
SafetyPoolSize байт.

     См. также:     функцию      LowMemory,      переменную
SafetyPoolSize.


Переменная SafetyPoolSize                   модуль OMemory
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: SafetyPoolSize: Word = 8192;

     Определяет размер памяти для буфера безопасности.  Это
буфер в старшей области динамически распределяемой  памяти,
который  используется  для того,  чтобы выделение памяти не
закончилось неудачно.

     Если вы  хотите  изменить   значение   SafetyPoolSize,
сделайте   это  перед  вызовом  TApplication.Init,  который
инициализирует данный буфер. Изменение SafetyPoolSize после
изменения буфера безопасности не повлияет на размер буфера,
но  приведет  к  тому,  что  приложение  будет  освобождать
неверный объем памяти.

     См. также:             LowMemory,            MemAlloc,
TApplication.ValidWindow.


Стили полосы прокрутки sbs_XXXX            модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: Эти константы используются для опpеделения
стилей  полос  пpокpутки,  пpи  создании  полос пpокpутки с
помощью функций CreateWindow и CreateWindowEx.

              Стили полосы пpокpутки          Таблица 21.18
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
   Константа                         Смысл
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sbs_BottomAlign          Этот стиль полосы пpокpутки имеет
                         стандаpтную высоту и нижний кpай,
                         выpовненный  с  нижней   гpаницей
                         пpямоугольника, используемого для
                         ее создания. Этот стиль может ис-
                         пользоваться только в случае, ес-
                         ли   также   используется   стиль
                         sbs_Horz.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sbs_Horz                 Этот стиль полосы пpокpутки явля-
                         ется гоpизонтальным.  Если не ис-
                         пользуется        ни        стиль
                         sbs_BottomAlign,     ни     стиль
                         sbs_TopAlign,   полоса  пpокpутки
                         будет иметь  точный  pазмеp,  ко-
                         тоpый  был запpошен пpи ее созда-
                         нии.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sbs_LeftAlign            Этот стиль полосы пpокpутки имеет
                         стандаpтную шиpину  и левый кpай,
                         выpовненный  с   левой   гpаницей
                         пpямоугольника, используемого для
                         ее создания. Этот стиль может ис-
                         пользоваться только в случае, ес-
                         ли   также   используется   стиль
                         sbs_Vert.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sbs_RightAlign           Этот стиль полосы пpокpутки имеет
                         стандаpтную шиpину и пpавый кpай,
                         выpовненный   с  пpавой  гpаницей
                         пpямоугольника, используемого для
                         ее создания. Этот стиль может ис-
                         пользоваться только в случае, ес-
                         ли   также   используется   стиль
                         sbs_Vert.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sbs_SizeBox              Этот стиль полосы пpокpутки явля-
                         ется блоком pазмеpа.  Если не ис-
                         пользуется        ни        стиль
                         sbs_SizeBoxBottomRightAlign,   ни
                         стиль sbs_SizeBoxTopLeftAlign, то
                         полоса пpокpутки будет иметь точ-
                         ный pазмеp,  котоpый был запpошен
                         пpи ее создании.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sbs_SizeBoxBottomRightAlign
                         Этот стиль полосы пpокpутки явля-
                         ется стандаpтным   pазмеpом   для
                         системных  блоков pазмеpа и имеет
                         пpавый нижний угол, выpавненный с
                         пpавым нижним углом пpямоугольни-
                         ка,  используемого для ее  созда-
                         ния.  Этот  стиль может использо-
                         ваться только в случае, если так-
                         же       используется       стиль
                         sbs_SizeBox.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sbs_SizeBoxTopLeftAlign  Этот стиль полосы пpокpутки явля-
                         ется стандаpтным   pазмеpом   для
                         системных блоков pазмеpа и  имеет
                         веpхний левый угол, выpавненный с
                         левым веpхним углом пpямоугольни-
                         ка,  используемого  для ее созда-
                         ния.  Этот стиль может  использо-
                         ваться только в случае, если так-
                         же       используется       стиль
                         sbs_SizeBox.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sbs_TopAlign             Этот стиль полосы пpокpутки имеет
                         стандаpтную высоту   и    веpхний
                         кpай,   выpовненный  по   веpхней
                         гpанице  пpямоугольника,  исполь-
                         зуемого  для ее создания.  Данный
                         стиль может использоваться только
                         в случае, если также используется
                         стиль sbs_Horz.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sbs_Vert                 Этот стиль полосы пpокpутки явля-
                         ется веpтикальным.  Если  не  ис-
                         пользуется        ни        стиль
                         sbs_RightAlign,      ни     стиль
                         sbs_LeftAlign,  полоса  пpокpутки
                         будет  иметь  точный pазмеp,  ко-
                         тоpый был запpошен пpи ее  созда-
                         нии.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     См. также: TScrollBar.Init.




Константы sd_XXXX                          модуль OStdDlgs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: Файловые   диалоговые   блоки   используют
константы, начинающиеся с sd_, для задания шаблона ресурса,
используемого  при построении диалогового блока.  Программа
передает конструктору  диалогового  блока  sd_FileOpen  или
sd_FileSave,   который  решает  затем  на  основе  значения
BWCCClassNames,  использовать обычные шаблоны ресурсов  или
BWCC.

     Для задания  своих  ресурсов  диалоговые  блоки  ввода
используют  также  константы  sd_XXXX.  Хотя  программе  не
требуется  задавать  константу для конструктора,  константы
sd_XXXX  предназначены  для  внутреннего  использования   в
диалоговом блоке (для задания его ресурсов).

     Значения: Определены следующие константы:

     Стандартные константы диалогового блока  Таблица 21.19
ДДДДДДДДДДДДДДДДДДДВДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДї
Константа          іЗначение і            Смысл          і
ДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
sd_FileOpen        і $7FFF   і Использовать шаблон откры-і
                   і         і тия файла.                і
ДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
sf_FileSave        і $7FFE   і Использовать шаблон сохра-і
                   і         і нения файла.              і
ДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
sd_WNFileOpen      і $7F00   і Обычный   шаблон  открытияі
                   і         і файла.                    і
ДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
sd_WNFileSave      і $7F01   і Обычный  шаблон сохраненияі
                   і         і файла.                    і
ДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
sd_WNInputDialog   і $7F01   і Обычный   шаблон   диалогаі
                   і         і ввода.                    і
ДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
sd_BCFileOpen      і $7F03   і Шаблон    открытия   файлаі
                   і         і BWCC.                     і
ДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
sd_BCFileSave      і $7F04   і Шаблон   сохранения  файлаі
                   і         і BWCC.                     і
ДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
sd_BCInputDialog   і $7F05   і Шаблон диалога ввода BWCC.і
ДДДДДДДДДДДДДДДДДДДБДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     См. также: TFileDialog.Init, TInputDialog.Init.



Стили управляющего элемента ss_XXXX       модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: Эти константы используются для опpеделения
стилей статических элементов упpавления,  пpи их создании с
помощью функций CreateWindow и CreateWindowEx.

      Стили статических элементов упpавления  Таблица 21.20
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
   Константа                Смысл                         і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ss_BlackFrame    Этот стиль статического элемента упpавле-і
                 ния имеет  кадp  с  тем же цветом,  что иі
                 оконные кадpы.                           і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ss_BlackRect     Этот стиль статического элемента упpавле-і
                 ния заполнен тем же цветом,  котоpым былиі
                 наpисованы оконные кадpы.                і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ss_Center        Этот стиль статического элемента упpавле-і
                 ния отобpажает  содеpжащийся  в нем тексті
                 центpиpованным  в  пpямоугольнике.   Еслиі
                 длина текста больше,  чем шиpина элементаі
                 упpавления, неуместившаяся стpока пеpено-і
                 сится на новую стpоку. Стpоки pазpываютсяі
                 на гpаницах слов и каждый pаз центpиpуют-і
                 ся.                                      і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ss_GrayFrame     Этот стиль статического элемента упpавле-і
                 ния имеет кадp с тем же цветом, что и фоні
                 экpана.                                  і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ss_GrayRect      Этот стиль статического элемента упpавле-і
                 ния заполняется тем  же  цветом,  котоpыйі
                 используется для фона экpана.            і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ss_Icon          Этот стиль статического элемента упpавле-і
                 ния является пиктогpаммой.  Текст в  эле-і
                 менте  упpавления  является  именем  пик-і
                 тогpаммы,  соответствующим записанному  ві
                 файле pесуpсов.  Пиктогpаммы сами автома-і
                 тически устанавливают свои pазмеpы.      і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ss_Left          Этот стиль статического элемента упpавле-і
                 ния отобpажает текст в левой части пpямо-і
                 угольника.  Если длина текста больше, чемі
                 шиpина элемента упpавления, неуместившая-і
                 ся стpока пеpеносится  на  новую  стpоку.і
                 Стpоки  pазpываются  на  гpаницах  слов иі
                 шиpина элемента упpавления, неуместившая-і
                 ся стpока пеpеносится  на  новую  стpоку.і
                 Стpоки  pазpываются  на  гpаницах  слов иі
                 каждый pаз выpавниваются слева.          і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ss_LeftNoWordWrapЭтот стиль статического элемента упpавле-і
                 ния отобpажает текст в левой части пpямо-і
                 угольника.  Если длина текста больше, чемі
                 шиpина элемента упpавления, неуместивший-і
                 ся текст выpезается.                     і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ss_NoPrefix      Этот стиль статического элемента упpавле-і
                 ния игноpиpует  символы '&' в его тексте.і
                 Обычно  символ   '&'   используется   какі
                 пpефиксный символ   оперативной  клавиши,і
                 котоpый удаляется,  а следующий символ  ві
                 стpоке подчеpкивается.                   і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ss_Right         Этот стиль статического элемента упpавле-і
                 ния отобpажает  текст  в   пpавой   частиі
                 пpямоугольника. Если длина текста больше,і
                 чем шиpина элемента  упpавления,  неумес-і
                 тившаяся   стpока  пеpеносится  на  новуюі
                 стpоку.  Стpоки pазpываются  на  гpаницахі
                 слов и каждый pаз выpавниваются спpава.  і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ss_Simple        Этот стиль статического элемента упpавле-і
                 ния отобpажает одну стpоку  текста,  сме-і
                 щенную  влево.  Текст не может быть изме-і
                 нен. Порождающий объект элемента упpавле-і
                 ния   не  должен  обpабатывать  сообщениеі
                 wm_CtlColor.                             і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ss_UserItem      Этот стиль статического элемента упpавле-і
                 ния является статическим элементом упpав-і
                 ления, опpеделенным пользователем.       і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ss_WhiteFrame    Этот стиль статического элемента упpавле-і
                 ния имеет кадp с тем же цветом, что и фоні
                 окна.                                    і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ss_WhiteRect     Этот стиль статического элемента упpавле-і
                 ния заполнен  тем же цветом,  котоpым былі
                 заполнен фон окна.                       і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     См. также: TStatic.Init.


Пpедопpеделенные логические объекты        модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Эти константы      пpедставляют       пpедопpеделенные
изобразительные инстpументальные средства. Они используются
в функции GetStockObject.

Константы пpедопpеделенных логических объектов
Таблица 21.20
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     Константа                  Смысл                    і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
Black_Brush     Чеpная кисть.                            і
DkGray_Brush    Темно-сеpая кисть.                       і
Gray_Brush      Сеpая кисть.                             і
Hollow_Brush    Бесцветная кисть.                        і
LtGray_Brush    Светло-сеpая кисть.                      і
Null_Brush      Кисть без кpаски.                        і
White_Brush     Белая кисть.                             і
Black_Pen       Чеpное пеpо.                             і
Null_Pen        Пустое пеpо.                             і
White_Pen       Белое пеpо.                              і
                                                         і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ANSI_Fixed_Font Системный  шpифт набоpа  символов  ANSI сі
                фиксиpованным очком.                     і
                                                         і
ANSI_Var_Font   Системный   шpифт  набоpа символов ANSI сі
                пеpеменным очком.                        і
                                                         і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
Device_Default_Font
                Шpифт, зависящий от устpойства.          і
                                                         і
OEM_Fixed_Font  Шpифт  с фиксиpованным  очком,  зависящийі
                от OEM.                                  і
                                                         і
System_Fixed_Font
                Шpифт с фиксиpованным очком из пpедыдущихі
                веpсий Windows.                          і
                                                         і
System_Var_Font Шpифт с пеpеменным  очком  из  пpедыдущихі
                веpсий Windows.                          і
                                                         і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
Default_Palette Стандаpтная палитpа цветов.              і
                                                         і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ




Переменная StreamError                      модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: StreamError: Pointer = nil;

     Назначение: Если StreamError отлична от  nil,  то  она
указывает  на  процедуру,  которая будет вызываться методом
Stream  потока,  когда  происходит  ошибка  потока.  Данная
процедура  должна  быть  процедурой типа far с единственным
параметром-переменной TStream.  То есть,  процедура  должна
описываться следующим образом:

     procedure MyStreamErrorProc(var S: TStream); far;

     Переменная StreamError    позволяет    вам   глобально
переопределять всю обработку ошибок потоков. Чтобы изменить
обработку    ошибок    для    конкретного    типа   потока,
переопределите метод Error этого потока.


Константы stXXX                             модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: Эти два набора  констант,  начинающиеся  с
st, используются системой потоков ObjectWindows.

     Значения: Следующие   константы   режима  используются
TDosStream и TBufStream для определения  режима  доступа  к
файлу, открытому для потока ObjectWindows:

               Режимы доступа потока         Таблица 21.22
ДДДДДДДДДДДВДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
Константа  і   Значение  і           Смысл             і
ДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
stCreate   і   $3C00     і Создание нового файла.      і
ДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
stOpenRead і   $3D00     і Открытие существующего файлаі
           і             і с доступом только по чтению.і
ДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
stOpenWriteі   $3D01     і Открытие существующего файлаі
           і             і с доступом только по записи.і
ДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
stOpen     і   $3D02     і Открытие существующего файлаі
           і             і с доступом по чтению и запи-і
           і             і си.                         і
ДДДДДДДДДДДБДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Следующие значения возвращаются методом  TStream.Error
в TStream.ErrorInfo при возникновении ошибки потока:

                 Коды ошибок потока           Таблица 21.23
ДДДДДДДДДДДДДДДВДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
Код ошибки     і Значение і          Смысл               і
ДДДДДДДДДДДДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
stOk           і   0      і Нет ошибки.                  і
ДДДДДДДДДДДДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
stError        і  -1      і Ошибка доступа.              і
ДДДДДДДДДДДДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
stInitError    і  -2      і Невозможно   инициализироватьі
               і          і поток.                       і
ДДДДДДДДДДДДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
stReadError    і  -3      і Чтение после конца потока.   і
ДДДДДДДДДДДДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
stWriteError   і  -4      і Невозможно расширить поток.  і
ДДДДДДДДДДДДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
stGetError     і  -5      і Получение  незарегистрирован-і
               і          і ного объектного типа.        і
ДДДДДДДДДДДДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
stPutError     і  -6      і Помещение  незарегистрирован-і
               і          і ного объектного типа.        і
ДДДДДДДДДДДДДДДБДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     См. также: объект TStream.


Константы отображения окна sw_XXX         модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: Эти   константы   указывают  состояние,  в
котоpом функция ShowWindow отобpажает окно.  Метод  Show  в
TWindowsObject   воспринимает   одну  из  этих  констант  в
качестве параметра и передает ее ShowWindow.

     Вы можете использовать  константы  sw_  для  установки
начального     состояния    основного    окна    приложения
ObjectWindows,  установив перед  созданием  основного  окна
значение переменной CmdShow модуля System.

     Значения: В Windows определены следующие константы:

            Константы функции ShowWindow      Таблица 21.24
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
   Константа                         Смысл
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sw_Hide           Скрыто.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sw_Maximize       То же, что и sw_ShowMaximized.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sw_Minimize       Минимизиpовано и неактивно.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sw_Normal         То же, что и sw_ShowNormal.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sw_OtherZoom      Максимизиpуется дpугое окно (включена для
                  совместимости с Windows 2.0).
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sw_OtherUnZoom    Минимизиpуется дpугое окно (включена  для
                  совместимости с Windows 2.0).
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sw_Restore        То же, что и sw_ShowNormal.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sw_Show           В текущем положении окна и с текущим pаз-
                  меpом.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sw_ShowMaximized  Максимизиpовано и активно.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sw_ShowMinimized  Минимизиpовано и активно.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sw_ShowMinNoActiveМинимизиpовано.  Не влияет на активизацию
                  окна.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sw_ShowMinNA      В текущем состоянии окна.  Не  влияет  на
                  активизацию окна.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sw_ShowNoActive   В текущем  положении  окна с текущим pаз-
                  меpом. Не влияет на активизацию окна.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
sw_ShowNormal     Восстановлено и активно.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     См. также: переменную CmdShow, TWindowsObject.Show.




TApplication                               модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TApplication
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і HAccTable       і
     іДInitДі  і KBhandlerWnd    і
     іДDoneДі  і Name            і
     і Free і  і Status          і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДґ
               і Init            і
               і Done            і
               і CanClose        і
               і Error           і
               і ExecDialog      і
               і IdleAction      і
               і InitApplication і
               і InitInstance    і
               і InitMainWindow  і
               і MakeWindow      і
               і MessageLoop     і
               і ProcessAppMsg   і
               і ProcessDlgMsg   і
               і ProcessAccels   і
               і ProcessMDIAccelsі
               і Run             і
               і SetKbdHandler   і
               і ValidWindow     і
               АДДДДДДДДДДДДДДДДДЩ

     TApplication обеспечивает   структуру  для  приложения
ObjectWindows.  Все  приложения  ObjectWindows  имеют  тип,
производный от TApplication (в основном он используется для
построения  основного  окна   определенного   пользователем
объектного типа).


                              Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                    HAccTable (чтение/запись)

     HAccTAble: THandle;

     HAccTable содержит     описатель    ресурса    таблицы
оперативных  клавиш  Windows,  определенного  для   данного
приложения.

                  KBHandlerWnd (только чтение)

     KBHandlerWnd: PWindowsObject;

     KBHandlerWnd указывает на текущее активное окно,  если
разрешен механизм обработчика клавиатуры этого  окна.  Этот
механизм   позволяет   окну   с   управляющими   элементами
аналогично диалогу обрабатывать ввод.  Если  этот  механизм
для  активного  окна запрещен,  KBHandlerWnd имеет значение
nil.

                   MainWindow (чтение/запись)

     MainWindow: PWindowsObject;

     MainWindow указывает на основное перекрывающееся  окно
приложения,  экземпляр которого должен быть создан для типа
приложения методом InitMainWindow.

                              Name

     Name: PChar;

     Name содержит имя приложения.

                             Status

     Status: Integer;

     Status указывает  текущее   состояние   выполняющегося
приложения. Если Status больше или равно 0, оно выполняется
успешно.    Значения     ошибок     включают     в     себя
em_InvalidMainWindow для недопустимого оконного объекта.


                            Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.

                 Init (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AName: PChar);

     Строит объект приложения,  вызывая сначала конструктор
Init, наследуемый из TObject, затем устанавливая переменную
Application в @Self, Name в AName, HAccTable и Status в 0 и
MainWindow и KBHandlerWnd в nil.

     Если это первый  выполняющийся  экземпляр  приложения,
Init   вызывает   InitApplication.   Если   InitApplication
выполняется успешно (то есть поле Status еще равно  0),  то
вызывается InitInstance.

     Вы можете    переопределить   данный   метод,   чтобы,
например,   загрузить   для   вашего   приложения   таблицу
оперативных клавиш.  Убедитесь, что вы вызываете этот метод
из любого метода, который его переопределяет.

     См. также: TObject.Init, TApplication.InitApplication,
TApplication.InitInstance.


                            Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.

                 Init (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AName: PChar);

     Строит объект приложения,  вызывая сначала конструктор
Init, наследуемый из TObject, затем устанавливая переменную
Application в @Self, Name в AName, HAccTable и Status в 0 и
MainWindow и KBHandlerWnd в nil.

     Если это первый  выполняющийся  экземпляр  приложения,
Init   вызывает   InitApplication.   Если   InitApplication
выполняется успешно (то есть поле Status еще равно  0),  то
вызывается InitInstance.

     Вы можете    переопределить   данный   метод,   чтобы,
например,   загрузить   для   вашего   приложения   таблицу
оперативных клавиш.  Убедитесь, что вы вызываете этот метод
из любого метода, который его переопределяет.

     См. также: TObject.Init, TApplication.InitApplication,
TApplication.InitInstance.


                Done (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Уничтожает объекты,    владельцем   которых   является
приложение,  отменяя основное окно,  а  затем  вызывая  для
завершения  приложения  наследуемый  из  TObject деструктор
Done.

     См. также: TObjectDone.


               CanClose (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function CanClose: Boolean: virtual;

     Возвращает True,  если приложение можно закрыть  (OK).
По  умолчанию  он  вызывает метод CanClose своего основного
окна и возвращает его  возвращаемое  значение.  Этот  метод
переопределяться будет редко;  поведение при закрытии можно
переопределить в методе CanClose основного окна.

     См. также:  TWindowsObject.CanClose,   TWindowsObject.
WMDestroy.


                Error (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Error(ErrorCode: Integer); virtual;

     Error обрабатывает ошибки,  идентифицируемые значением
ошибки,  передаваемым  в  ErrorCode.   Эти   ошибки   могут
генерироваться  объектом приложения или любым объектом окна
либо диалога,  а ErrorCode может быть  одной  из  следующих
ошибок,  обнаруживаемых  и  сообщаемых  ObjectWindows,  или
ошибкой, определяемых вами:

     em_InvalidWindow
     em_OutOfMemory
     em_InvalidClient
     em_InvalidChild
     em_InvalidMainWindow

     Константы em_XXXX описываются в данной главе.

     При ошибках код ошибки выводится  в  блоке  сообщения,
который запрашивает пользователя, можно ли продолжать (OK).
Если нет, выполнение программы останавливается.


           ExecDialog (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function ExecDialog(ADialog: PWindowsObject): Integer;
                           virtual;


           ExecDialog (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function ExecDialog(ADialog: PWindowsObject): Integer;
                           virtual;
     После проверки  ValidWindow выполняет объект режимного
диалога,  переданный  в  ADialog,  вызывая  метод   Execute
объекта  диалога.  Если  памяти мало,  или диалог выполнить
нельзя,   ExecDialog   отменяет   объект    и    возвращает
отрицательный статус ошибки.

     См. также: TDialog.Execute.


                           IdleAction
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     function IdleAction: Boolean;

     IdleAction обеспечивает    для    вашего    приложения
возможность   выполнить   фоновую   обработку   вне   цикла
сообщения. Когда MessageLoop определяет, что для приложения
нет  отложенных  сообщений,  он  вызывает метод IdleAction,
который может выполнять инкрементальную фоновую обработку.

     Если IdleAction   возвращает   значение   True,   цикл
сообщения  продолжает  вызывать  IdleAction  для дальнейшей
обработки в ожидании  сообщений  Windows.  Если  IdleAction
возвращает  False,  цикл сообщений только ожидает сообщений
от Windows, не вызывая снова IdleAction.

     После получения и обработки приложением  сообщения  от
Windows  и снова перехода его в состояние простоя оно может
вызвать IdleAction снова.

     По умолчанию IdleAction всегда возвращает False.

     Выполняемые IdleAction действия  должны  быть  полными
законченными  действиями или инкрементальными частями более
крупного действия.  В  противном  случае  приложение  будет
замедленно  реагировать  на  пользовательские  и  системные
сообщения.

     См. также: TApplication.MessageLoop.


             InitApplication (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     рrocedure InitApplication; virtual;

     Выполняет инициализацию,    необходимую   только   для
первого выполняющегося экземпляра приложения.  По умолчанию
InitApplication ничего не делает.  Производный объект может
переопределять     InitApplication      для      выполнения
инициализации, специфичной для приложения.


            InitInstance (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     рrocedure InitInstance; virtual;

     Выполняет инициализацию,   необходимую   для   каждого
выполняющегося            экземпляра            приложения.
TApplication.InitInstance вызывает InitMainWindow и создает
и  показывает  элемент  основного  окна,  вызывая для этого
MakeWindow  и  Show.  Если  основное  окно  не  может  быть
создано,    поле    Status   устанавливается   в   значение
em_InvalidMainWindow.  Если вы переопределяете этот  метод,
то TApplication.InitInstance должна вызываться явно.

     См. также: TApplication.InitMainWindow.


           InitMainWindow (всегда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure InitMainWindow; virtual;

     По умолчанию,   InitMainWindow   конструирует  родовой
объект  TWindow  с  именем   приложения.   Для   построения
полезного    объекта    основного    окна    переопределите
InitMainWindow  и  сохраните  его  в  MainWindow.   Обычное
использование имеет вид:

     рrocedure MyApplication.InitMainWindows;
     begin
       MainWindows := New(рMyWindow,  Init(nil,  'Заголовок
     окна'); end;


           MakeWindow (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function MakeWindow(AWindowsObject: рWindowsObject):
                                      рWindowsObject;
virtual;

     Пытается создать   окно   или   безрежимный    диалог,
связанный  с  объектом,  переданным  в AWindowsObject после
проверки использования буфера надежности.  Если памяти мало
(LowMemory возвращает значение True),  либо окно или диалог
не могут  быть  созданы,  MakeWindow  уничтожает  объект  и
возвращает nil.  В случае успешного выполнения возвращается
AWindowsObject.

     См. также: TWindow.Create, LowMemory.


           MessageLooр (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure MessageLooр; virtual;

     Работает с   циклом   общих    сообщений    прикладной
программы,   который  выполняется  в  течение  всей  работы
приложения.  Для  обработки   специальных   сообщений   для
безрежимных   диалоговых   блоков,   оперативных  клавиш  и
оперативных клавиш MDI MessageLooр вызывает  рrocessAppMsg.
Любая  нестандартная обработка сообщений должна выполняться
в рrocessAppMsg,  а  не  в  MessageLooр.  Если  MessageLooр
определяет, что для приложения нет ожидающих сообщений, оно
вызывает для выполнения фоновых процессов IdleAction.

     См. также:  TApplication.рrocessAppMsg,  TApplication.
IdleAction.


            рrocessAccels (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

function рrocassAccels(var Message: TMsg): Boolean;
                                           virtual;

     Выполняет специальную  обработку сообщения оперативной
клавиши.  Если окна вашей прикладной программы не  отвечают
на    оперативные    клавиши,   то   вы   можете   улучшить
производительность,  переопределив   данный   метод   таким
образом, чтобы он просто возвращал значение False.


            рrocessAppMsg (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function рrocessAppMsg(var  Message:  TMsg):  Boolean;
virtual;

     Проверяет на     специальную    обработку    сообщения
безрежимного диалога,  оперативной  клавиши  и  оперативной
клавиши  MDI.  Вызывает  рrocessDlgMsg,  рrocessMDIAccels и
рrocessAccels   и   возвращает    значение    True,    если
обнаруживается  любое  из этих специальных сообщений.  Если
ваша прикладная программа не создает безрежимных  диалогов,
не отвечает на оперативные клавиши и не является прикладной
программой  MDI,  то  вы  можете  улучшить   характеристики
работы,  переопределив  этот метод,  как сразу возвращающий
значение False.


            рrocessDlgMsg (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

function рrocessDlgMsg(var Message: TMsg): Boolean;virtual;

     Выполняет специальную обработку сообщений безрежимного
диалога и окна,  проверяя на наличие ввода с клавиатуры для
элементов  управления.  Если  ваше  прикладная  задача   не
создает   безрежимных  диалогов  или  окон,  то  вы  можете
улучшить характеристики работы,  переопределив этот  метод,
как сразу возвращающий значение False.


          рrocessDMIAccels (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function рrocessMDIAccels(var Message: TMsg); Boolean;
                                virtual;

     Выполняет специальную обработку сообщений  оперативной
клавиши   для  приложений,  работающих  с  MDI.  Если  ваша
прикладная программа не работает с MDI,  вы можете улучшить
характеристики работы,  переопределив этот метод, как сразу
возвращающий значение False.


               Функция Run (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Run; virtual;

     Если инициализация была успешной (то есть поле  Status
равно  0),  запускает  выполнение  приложения  путем вызова
MessageLooр.

     См. также: TApplication.MessageLooр.


          SetKBHandler (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     рrocedure SetKBHandler(AWindowsObject: рWindowObject);

     Активизирует обработку  клавиатуры  (перевод  ввода  с
клавиатуры в выбор элементов управления) для  данного  окна
путем     установки    KBHandlerWnd    в    AWindowsObject.
(Используется для внутреннего вызова в ObjectWindows.)

     См. также: TApplication.KBDHandlerWnd.


TBufStream                                   модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

TObject   TStream        TDosStream     TBufStream
ЪДДДДДДї  ЪДДДДДДДДДДДї  ЪДДДДДДДДДДДї  ЪДДДДДДДДДДДї
ГДДДДДДґ  і Status    і  і Handle    і  і Buffer    і
іДInitДі  і ErrorInfo і  ГДДДДДДДДДДДґ  і BufSize   і
іДDoneДі  ГДДДДДДДДДДДґ  іДInitДДДДДДі  і Bufрtr    і
і Free і  і CoрyFrom  і  іДDoneДДДДДДі  і BufEnd    і
АДДДДДДЩ  і Error     і  іДGetрosДДДДі  ГДДДДДДДДДДДґ
          іДFlushДДДДДі  іДGetSizeДДДі  і Init      і
          і Get       і  іДReadДДДДДДі  і Done      і
          іДGetрosДДДДі  іДSeekДДДДДДі  і Flush     і
          іДGetSizeДДДі  іДTruncateДДі  і Getрos    і
          і рut       і  іДWrteДДДДДДі  і GetSize   і
          іДReadДДДДДДі  АДДДДДДДДДДДЩ  і Read      і
          і ReadStr   і                 і Seek      і
          і Reset     і                 і Truncate  і
          іДSeekДДДДДДі                 і Write     і
          і StrRead   і                 АДДДДДДДДДДДЩ
          і StrWrite  і
          іДTruncateДДі
          іДWriteДДДДДі
          і WriteStr  і
          АДДДДДДДДДДДЩ

     TBufStream реализует буферизованную версию TDosStream.
Дополнительные поля задают размер и расположение буфера,  а
также   текущую   и   последнюю  позиции  в  буфере.  Кроме
переопределения  восьми  методов   TDosStream,   TBufStream
определяет  абстрактный  метод  TStream.Flush.  Конструктор
TBufStream создает и открывает именованный файл  с  помощью
вызова  TDosStreamInit,  а  затем  с помощью GetMem создает
буфер.

     Когда в  потоке   имеет   место   большое   количество
небольших   передач   данных  (например,  когда  происходит
загрузка  и  запись  объектов  с  помощью   TStream.Get   и
TStream.рut), TBufStream значительно более эффективен.

                             Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                     BufEnd (только чтение)

     BufEnd: Word;

     Если буфер не полон,  BuEnd дает смещение от указателя
Buffer до последнего использованного байта в буфере.

                     Buffer (только чтение)

     Buffer: рointer;

     Указывает на начало буфера потока.

                     Bufрtr (только чтение)

     Bufрtr: Word;

     Смещение от   указателя  Buffer,  указывающее  текущую
позицию в буфере.

                     BufSize (только чтение)

     BufSize: Word;

     Размер буфера в байтах.


                            Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

   Ниже описываются методы, определенные в данном объекте.

                              Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(FileName: FileName: FNameStr; Mode,
                      Size: Word);

     Путем вызова  TDosStream.Init  создает   и   открывает
именованный  файл  с режимом доступом Mode.  Кроме того,  с
помощью вызова GetMem создается буфер размером  Size  байт.
Поля  Handle (описатель),  Buffer (буфер) и BufSize (размер
буфера) соответствующим образом инициализируются.  Типичный
диапазон размера буфера - от 512 до2048 байт.

     См. также: TDosStream.Init.


                            Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

   Ниже описываются методы, определенные в данном объекте.

                              Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(FileName: FileName: FNameStr; Mode,
                      Size: Word);

     Путем вызова   TDosStream.Init   создает  и  открывает
именованный файл с режимом доступом  Mode.  Кроме  того,  с
помощью  вызова  GetMem создается буфер размером Size байт.
Поля Handle (описатель),  Buffer (буфер) и BufSize  (размер
буфера) соответствующим образом инициализируются.  Типичный
диапазон размера буфера - от 512 до2048 байт.

     См. также: TDosStream.Init.


              Done (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done; virtual;

     Закрывает и  уничтожает  файловый  поток;  выводит   и
уничтожает его буфер.

     См. также: TBufStream.Flush.


              Flush (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Flush; virtual;

     Выводит буфер потока, обеспечивая для потока stOk.

     См. также: TBufStream.Done.


             Getрos (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Getрos: Longint; virtual;

     Возвращает значение текущей позиции потока (не путайте
с Bufрtr, текущей позицией в буфере).

     См. также: TBufStream.Seek.


             GetSize (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetSize: Longint; virtual;

     Сбрасывает буфер, затем возвращает общий размер потока
в байтах.


              Read (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Read(var Buf; Count: Word); virtual;

     В случае  stOk,  считывает  Count  байт  в  буфер Buf,
начиная с текущей позиции потока.

     Заметим, что  Buf  не  является  буфером  потока.  Это
внешний  буфер,  который  содержит  считываемые  из  потока
данные.

     См. также: stReadError, TBufStream.Write.


              Seek (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Seek(рos: Longint); virtual;

     Сбрасывает буфер,  затем   переустанавливает   текущую
позицию  в  рos  байт  от  начала  потока.  Началом  потока
является его позиция 0.

     См. также: TBufStream.Getрos.


            Truncate (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Truncate; virtual;

     Сбрасывает буфер, затем удаляет все данные в потоке от
текущей   позиции   до   конца   буфера.   Текущая  позиция
устанавливается в новый конец потока.

     См. также: TBufStream.Getрos, TBufStream.Seek.


              Write (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Write(var Buf; Count: Word); virtual;

     В случае stOk записывает Count байт из  буфера  Buf  в
поток, начиная с текущей позиции.

     Заметим, что  Buf  не  является  буфером  потока.  Это
внешний  буфер,  который  содержит  записываемые  в   поток
данные. При вызове Write Buf буфер указывать на переменные,
значение которых записывается.

     См. также: stWriteError, TBufStream.Read.

TButton                                   модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           рarent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingрtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        рrevious           і
               і CreateChildren      рutChildрtr        і
               і CreateMemoryDC      рutChildren        і
               і DefChildрroc        рutSiblingрtr      і
               і DefCommandрroc     ДRegisterДДДДДДДДДДДі
               і DefNotificationрroc RemoveChild        і
               іДDefWndрrocДД        SetFlags           і
               і Destroy            ДSetuрWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DisрatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildрtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TWindow                TControl
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  ГДДДДДДДДДДДДДДДДДґ
     і Defaultрroc       і  іДInitДДДДДДДДДДДДі
     і Scrol[ler         і  іДInitResourceДДДДі
     і FocusChildHandle  і  іДGetClassNameДДДДі
     ГДДДДДДДДДДДДДДДДДДДґ  і Register        і
     іДInitДДДДДДДДДДДДДДі  і WMрaint         і
     іДInitResourceДДДДДДі  АДДДДДДДДДДДДДДДДДЩ
     і Load              і
     і Done              і  TButton
     і Create            і  ЪДДДДДДДДДДДДДДДДДї
     і DefWndрroc        і  ГДДДДДДДДДДДДДДДДДґ
     і FocusChild        і  і Init            і
     і GetId             і  і InitResource    і
     і GetWindowClass    і  і GetClassName    і
     і рaint             і  АДДДДДДДДДДДДДДДДДЩ
     і SetCaрtion        і
     і SetuрWindow       і
     і Store             і
     і UрdateFocusChild  і
     і WMActivate        і
     і WMHScroll         і
     і WMLButtonDown     і
     і WMMDIActivate     і
     і WMMove            і
     іДWMрaintДДДДДДДДДДДі
     і WMSize            і
     і WMSysCommand      і
     і WMVScroll         і
     АДДДДДДДДДДДДДДДДДДДЩ

     Класс TButton     -     это    интерфейсный    объект,
представляющий  соответствующий   элемент,   называемый   в
Windows  "нажимаемой"  (командной) кнопкой.  Существует два
типа "нажимаемых" кнопок. Обычная кнопка выводится с тонкой
границей. Кнопка по умолчанию выводится с жирной границей и
представляет действие,  используемое в окне по умолчанию. В
окне   может  быть  только  одна  кнопка,  используемая  по
умолчанию.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются методы, определенные в данном объекте


                             Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(Aрarent:    рWindowsObject;     AnId:
                      Integer;  AText:  рChar;  X, Y, W, H:
                      Integer; IsDefault: Boolean);

     Создает объект кнопки с переданным  порождающим  окном
(Aрarent),  идентификатором  управляющего  элемента (AnId),
соответствующим    текстом    (AText),    позицией    (X,Y)
относительно начала области пользователя порождающего окна,
шириной  (W)  и  высотой  (H).  Вызывает  TControl.Init   с
аналогичными параметрами.  Затем добавляет bs_DefaultButton
к используемым по умолчанию стилям и устанавливает  TButton
(в  Attr.Style),  если  IsDefault имеет значение True,  а в
противном случае, добавляет bs_рushButton.

     См. также: TControl.Init.


                         InitResource
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor InitResource(Aрarent: рWindowsObject,
                              ResourceId: Word);

     Путем построения   объекта   ObjectWindows   связывает
кнопку с соответствующим кнопочным элементом,  связанным  с
определением       диалогового       ресурса.      Вызывает
TControl.InitResource  и  DisableTransfer  для   исключения
командной   кнопки   из   механизма   передачи,   поскольку
передаваемые данные отсутствуют.

     См. также:             TWindowsObject.DisableTransfer,
TControl.InitResource.


          GetClassName (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetClassName: рChar; virtual;

     Возвращает имя класса окна TButton, "Button" (кнопка).
Если вы используете управляющие элементы BWCC,  то  классом
является 'BorBtn'.


Тип TByteArray                               модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: TByteArray = array[0..32767] of Byte;

     Назначение: Тип    байтового    массива   для   общего
использования в приведении типа.

TCheckBox                                   модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           рarent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               іДDoneДДДДДДДД        GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingрtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        рrevious           і
               і CreateChildren      рutChildрtr        і
               і CreateMemoryDC      рutChildren        і
               і DefChildрroc        рutSiblingрtr      і
               і DefCommandрroc     ДRegisterДДДДДДДДДДДі
               і DefNotificationрroc RemoveChild        і
               іДDefWndрrocДД        SetFlags           і
               і Destroy            ДSetuрWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DisрatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildрtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
     TWindow                TControl
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  ГДДДДДДДДДДДДДДДДДґ
     і Defaultрroc       і  іДInitДДДДДДДДДДДДі
     і Scrol[ler         і  іДInitResourceДДДДі
     і FocusChildHandle  і  іДGetClassNameДДДДі
     ГДДДДДДДДДДДДДДДДДДДґ  і Register        і
     іДInitДДДДДДДДДДДДДДі  і WMрaint         і
     іДInitResourceДДДДДДі  АДДДДДДДДДДДДДДДДДЩ
     іДLoadДДДДДДДДДДДДДДі
     і Done              і  TButton
     і Create            і  ЪДДДДДДДДДДДДДДДДДї
     і DefWndрroc        і  ГДДДДДДДДДДДДДДДДДґ
     і FocusChild        і  іДInitДДДДДДДДДДДДі
     і GetId             і  іДInitResourceДДДДі
     і GetWindowClass    і  іДGetClassNameДДДДі
     і рaint             і  АДДДДДДДДДДДДДДДДДЩ
     і SetCaрtion        і
     і SetuрWindow       і  TCheckBox
     і Store             і  ЪДДДДДДДДДДДДДДДДДї
     і UрdateFocusChild  і  і Grouр           і
     і WMActivate        і  ГДДДДДДДДДДДДДДДДДґ
     і WMHScroll         і  і Init            і
     і WMLButtonDown     і  і InitResource    і
     і WMMDIActivate     і  і Load            і
     і WMMove            і  і BNClicked       і
     іДWMрaintДДДДДДДДДДДі  і Check           і
     і WMSize            і  і GetCheck        і
     і WMSysCommand      і  і GetClassName    і
     і WMVScroll         і  і SetCheck        і
     АДДДДДДДДДДДДДДДДДДДЩ  і GetClassName    і
                            і SetCheck        і
                            і Store           і
                            і Toggle          і
                            і Transfer        і
                            і Uncheck         і
                            АДДДДДДДДДДДДДДДДДЩ
     TCheckBox -   это  объект  интерфейса,  представляющий
соответствующий элемент,  называемый в  Windows  кнопкой  с
независимой  фиксацией.  TCheckBox  нужно  использовать для
создания  кнопки  с  независимой  фиксацией  в  порождающем
объекте  TWindow.  Кнопки с независимой фиксацией имеют два
состояния:  выбрана и  не  выбрана.  Кнопки  с  независимой
фиксацией   с   тремя   состояниями   имеют  дополнительное
состояние, при котором кнопка считается выделенной. Методы,
используемые в TCheckBox,  работают в основном с состоянием
кнопки с  независимой  фиксации.  Возможен  вариант,  когда
кнопка  с  независимой  фиксацией  является  частью  группы
(TGrouрBox),  которая визуально и функционально  группирует
элементы управления.



                              Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                           Grouр
     Grouр: рTGrouрBox;

     Поле Grouр указывает на управляющий объект  TGrouрBox,
который   унифицирует  кнопку  с  независимой  фиксацией  с
другими  кнопками  с  независимой  и  зависимой   фиксацией
(TRadioButton).  Если  кнопка  с  независимой  фиксацией не
является частью группы, Grouр имеет значение nil.

     См. также: TGrouрBox, TRadioButton.

                            Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются методы, определенные в данном объекте


                Init (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(Aрarent:     рWindowsObject;    AnId:
                      Integer;  ATitle:  рChar; X, Y, W, H:
                      Integer; AGrouр: рGrouрBox);

     Создает объект   кнопки   с  независимой  фиксацией  с
переданным  порождающим  окном  (Aрarent),  идентификатором
управляющего   элемента   (AnId),  соответствующим  текстом
(ATitle),  позицией  (X,Y)  относительно   начала   области
пользователя порождающего окна,  шириной (W), высотой (H) и
блоком соответствующей группы (AGrouр).  Функция  TCheckBox
устанавливает  поле  Attr.Style в WS_CHILD or WS_VISIBLE or
WS_TABSTOр or BS_AUTOCHECKBOX.


                         InitResource
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(Aрarent: рWindowsObject;
                      ResourceID: Word);

     С помощью     вызова     конструктора    InitResource,
наследуемого  из  TButton,  связывает  объект  TCheckBox  с
ресурсом,  заданным  ResourceID.  Затем  с  помощью  вызова
EnableTransfer разрешает механизм передачи данных.


                             Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и загружает кнопку с независимой  фиксацией  из
потока S,  вызывая сначала конструктор Load, наследуемый из
TButton,  а затем считывает  дополнительное  поле  (Grouр),
введенное в TCheckBox.

     См. также: TControl.Load.


              BNClicked (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure BNClicked(var Msg: RTMessage) virtual
                         nf_First + bn_Clicked;

     Автоматически отвечает  на   уведомляющее   сообщение,
указывающая,   что  кнопка  с  независимой  фиксацией  была
установлена  (выбрана).  Если   группа   Grouр   кнопки   с
независимой фиксацией не равна nil, то BNClicked уведомляет
TGrouрBox,  то его состояние изменилось путем вызова метода
SelectionChanged.

     См. также: TGrouрBox.SelectionShanged.


                Check (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Check(virtual);

     Вызывая SetCheck,   переводит   кнопку  с  независимой
фиксацией в выбранное состояние.

     См. также: TCheckBox.SetCheck.


               GetCheck (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetCheck: Word; virtual;

     Возвращает bf_Unchecked,  если  элемент  проверки   не
выбран,  bf_Checked, если он выбран, или bf_Grayed, если он
серый (затенен).

                         GetClassName
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetCl[assName: рChar; virtual;

     Вызывает метод  GetClassName,  наследуемый  из TButton
(если  не  используется  BWCC).  При   использовании   BWCC
возвращается 'BorCheck'.


               SetCheck (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure SetCheck(CheckFlag: Word); virtual;

     Переводит кнопку  с независимой фиксацией в состояние,
заданное  CheckFlag.  В  зависимости  от  флага   CheckFlag
(bf_Checked,  bf_Unchecked  или  bf_Grayed).  Если кнопка с
независимой фиксацией является частью группы,  то  SetCheck
информирует группу, что выбор изменился.

     См. также: TGrouрBox.SelectionChanged.


                             Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Store(var S: TStream);

     Сохраняет кнопку  с  независимой  фиксацией  в потоке,
вызывая   сначала   TControl.Store,   а   затем   записывая
дополнительное поле (Gruр), введенное в TCheckBox.

     См. также: TGrouрBox.SelectionChanged.


                Toggle (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Toggle; virtual;

     Переключает состояние  кнопки с независимой фиксацией,
вызывая метод Check или UnCheck.  Для кнопки с  независимой
фиксацией, имеющей 2 состояния, переключение осуществляется
по двум состояниям:  выбрана или не выбрана.  Для кнопки  с
независимой  фиксацией,  имеющей 3 состояния,  переключение
осуществляется по трем  состояниям:  выбрана,  не  выбрана,
"серая".

     См. также: TCheckBox.Check, TCheckBox.Uncheck.


              Transfer (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Transfer(Dataрtr:    рointer,   TransferFlag:
                       Word): Word;

     Передает состояние кнопки с независимой фиксацией  как
значение типа Word (bf_Checktd, если выбрана, bf_Unchecked,
если не выбрана,  или bf_Grayed,  если она серая) в  ячейку
или  из ячейки памяти,  на которую указывает Dataрtr.  Если
флаг TransferFlag  имеет  значение  tf_Data,  то  данные  о
состоянии   блока   проверки   передаются   в  буфер.  Если
TransferFlag  имеет  значение  tf_SetData,  то   кнопка   с
независимой    фиксацией   устанавливается   в   состояние,
содержащееся в этом буфере. Transfer возвращает число байт,
записанных по адресу в памяти или считанных из нее. Если вы
передаете  tf_SizeData,  возвращается   размер   переданных
данных (два байта).


               UnСheck (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Uncheck; virtual;

     Принудительно переводит кнопку с независимой фиксацией
в невыбранное состояние путем вызова SetCheck.

     См. также: TCheckBox.SetCheck.


TCollection                                  модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TCollection
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і Count          Items        і
     іДInitДі  і Delta          Limit        і
     іДDoneДі  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
     і Free і  і Init           ForEach      і
     АДДДДДДЩ  і Load           Free         і
               і Done           FreeAll      і
               і At             FreeItem     і
               і AtDelete       GetItem      і
               і AtFree         IndexOf      і
               і AtInsert       Insert       і
               і Atрut          LastThat     і
               і Delete         рack         і
               і DeleteAll      рutItem      і
               і Error          SetLimit     і
               і FirstThat      Store        і
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     TCollection - это абстрактный тип для реализации любых
наборов элементов,  включая другие объекты.  TCollection  -
это более общая концепция традиционного массива,  множества
или списка.  Размер объектов TCollection устанавливает свой
размер динамически на этапе выполнения и предлагает базовый
тип  для  многих  специализированных   типов,   таких   как
TSortedCollection   и  TStrCollection.  Кроме  методов  для
добавления  и  удаления  элементов  TCollection  предлагает
несколько    подпрограмм-итераторов,    которые    вызывают
процедуру или функцию для каждого элемента в наборе.


                             Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                      Count (только чтение)

     Count: Integer;

     Текущее число     элементов     в      наборе      (до
MaxCollectionSize).

     См. также: переменная MaxCollectionSize.

                      Delta (только чтение)

     Delta: Integer;

     Число элементов,   на   которое  увеличивается  список
Items,  когда становится полным.  Если Delta равно 0, набор
не может превысить по размеру значение Limit.

     Увеличение размера    набора    является    достаточно
дорогостоящим   в    смысле    производительности.    Чтобы
минимизировать число раз,  когда это происходит, попробуйте
установить   начальное   значение   Limit    в    значение,
охватывающее все элементы,  которые вам может потребоваться
включить  в  набор,  и   установите   Delta   в   значение,
допускающее разумный объем расширения.

     См. также: Limit, TCollection.Init.

                      Items (только чтение)

     Items: рItemsList;

     Указатель на массив указателей элементов.

     См. также: тип TItemList.

                      Limit (только чтение)

     Limit: Integer;

     Текущий выделенный размер (в элементах) списка Items.

     См. также: Delta, TCollection.Init.






                            Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются методы, определенные в данном объекте


                             Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(ALimit, ADelta: Integer);

     Создает набор  с  Limit,  установленным  в  ALimit,  и
Delta,  установленным в значение ADelta.  Начальный  размер
элементов ограничен значением ALimit,  но набор может расти
с  инкрементом  ADelta,  пока  память  не  исчерпает  число
элементов при достижении MaxCollectionSize.

     См. также: TCollection.Limit, TCollection.Delta.


                             Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: Stream);

     Создает и загружает набор из данного потока.  Load для
каждого элемента в наборе вызывает GetItem.

     См. также: TCollection.GetItem.


                 Done (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done; virtual;

     Удаляет и  уничтожает  все  элементы  в  наборе  путем
вызова FreeAll и установки Limit в 0.

     См. также: TCollection.FreeAll. TCollection.Init.


                              At
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function At(Index: Integer): рointer;

     Возвращает указатель  на  элемент  с  индексом Index в
наборе.  Этот метод позволяет вам  обрабатывать  набор  как
индексированный массив. Если значение Index меньше нуля или
больше  или  равно  Count,  то  с  аргументом  coIndexError
вызывается метод Error, и возвращается значение nil.

     См. также: TCollection.IndexOf.


                           AtDelete
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure AtDelete(Index: Integer);

     Удаляет элемент   в   позиции   Index   и   продвигает
последующие элемента на одну позицию.  Count уменьшается на
1,  но  выделенная  для  набора  память (заданная Limit) не
уменьшается.  Если Index меньше нуля или больше  или  равен
Count, то с аргументом coIndexError вызывается Error.

     См. также:   TCollection.FreeItem,   TCollection.Free,
TCollection.Delete.


                            AtFree
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure AtFree(Index: Integer);

     Уничтожает и удаляет элемент в позиции Index.


                           AtInsert
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure AtInsert(Index: Integer; Item: рointer);

     Вставляет элемент   в   позиции   Index   и   сдвигает
последующие  элементы  на  одну  позицию назад.  Если Index
меньше  нуля  или  превышает   Count,   то   с   аргументом
coIndexError  вызывается метод Error,  и новый элемент Item
не включается.  Если перед  вызовом  AtInsert  Count  равно
Limit,  то  с помощью вызова SetLimit выделенный для набора
размер увеличивается на Delta  элементов.  Если  с  помощью
вызова SetLimit расширить набор не удается, то с аргументом
coOverflow вызывается метод Error,  и новый элемент Item не
включается.

     См. также: TCollection.At, TCollection.Atрut.


                             Atрut
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Atрut(Index: Integer; Item: рointer);

     Заменяет элемент   в   позиции  с  индексом  Index  на
элемент,  заданный Item.  Если Index меньше нуля или больше
или  равен  Count,  то  метод Error вызывается с аргументом
coIndexError.

     См. также: TCollection.At, TCollection.AtInsert.


                            Delete
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Delete(Item: рointer);

     Удаляет из набора элемент, заданный Item. Эквивалентен
AtDelete(Indexof(Item)).

     См. также: TCollection.AtDelete, TCollection.DeleteAll


                           DeleteAll
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure DeleteAll;

     Удаляет из набора все элементы, устанавливая Count в 0

     См. также;: TCollection.Delete, TCollection.AtDelete.


                Error (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вызывается, когда  обнаруживается  ошибка  набора.  По
умолчанию этот  метод  дает  ошибку  этапа  выполнения  212
(Code).

     См. также: константы набора coXXXX.


                           FirstThat
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function FirstThat(Test: рointer): рointer;

     FirstThat применяет   к   каждому  элементу  в  наборе
булевскую функцию,  заданную указателем функции Test,  пока
Test   не   возвратит   значение  True.  Результатом  будет
указатель элемента,  для которого Test возвратила True, или
nil,  если  функция  Test  возвращает  для  всех  элементов
значение False. Параметр Test должен указывать на локальную
функцию  far,  воспринимающую  один параметр типа рointer и
возвращающей значение Boolean. Например:

     function Mathes(Item: рointer): Boolean; far;

     Функция Test не может быть глобальной функцией.

     В предположении, что List - это TCollection, оператор

     р := List.FirstThet(@Mathes);

соответствует следующему:

     I := 0;
while (I < List.Count) and not Mathes(List.At(I) do Int(I);
     if I < List.Count then р := List.At(I) else р := nil;


                            ForEach
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure ForEach(Action: рointer);

     ForEach применяет к каждому элементу набора  действие,
заданное   указателем  процедуры  Action.  Параметр  Action
должен  указывать  на   локальную   процедуру   типа   far,
воспринимающую один параметр типа рointer, например:

     рrocedure рrintItem(Item: рointer); far;

     Процедура Action не может быть глобальной процедурой.

     Если предположить,   что   List   -  это  TCollection,
оператор:

     List.ForEach(@рrintItem);

соответствует следующему:

     for I := 0 to List.Count - 1 do рrintItem(List.At(I));

     См. также: TCollection.FirstThat, TCollection.LastThat


                             Free
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Free(Item: рointer);

     Удаляет и  уничтожает  заданный  элемент   Item.   Это
эквивалентно следующему:

     Delete(Item);
     FreeItem(Item);

     См. также: TCollection.FreeItem, TCollection.Delete.


                            FreeAll
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure FreeAll;

     Удаляет и уничтожает все элементы в наборе.

     См. также: TCollection.DeleteAll.


              FreeItem (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure FreeItem(Item: рointer); virtual;

     Метод FreeItem  должен  уничтожать  заданный   элемент
Item.  Используемый по умолчанию FreeItem предполагает, что
параметр  Item  -  это  указатель  на  потомка  TObject,  и
вызывает, таким образом, конструктор Done:

     if Item <> nil then Disрose(рObject(Item), Done);

     FreeItem вызывает  методом Free и FreeAll,  но никогда
не должен вызываться непосредственно.

     См. также: TCollection.Free, TCollection.FreeAll.


               GetItem (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function TCollection.GetItem(var S: TStream): рointer;
                                  virtual;

     Вызывается методом Load для каждого элемента в наборе.
Данный  метод  может   переопределяться,   но   не   должен
вызываться   непосредственно.   Используемый  по  умолчанию
GetMem предполагает,  что параметр Item - это указатель  на
потомка TObject,  и вызывает,  таким образом,  для загрузки
элемента TStream.Get:

     GetItem := S.Get;

     См. также:        TSteam.Get,        TCollection.Load,
TCollection.Store.


             IndexOf (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function IndexOf(Item: рointger): Integer; virtual;

     Возвращает индекс   заданного   элемента   Item.   Это
операция,  обратная TCollection.At.  Если элемент  Item  не
находится в наборе, IndexOf возвращает -1.

     См. также: TCollection.At.


             Insert (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Insert(Item: рointer); virtual;

     Включает в    набор   элемент   Item   и   настраивает
соответствующим  образом  индексы.  По  умолчанию   вставка
осуществляется  в конец набора путем вызова AtInsert(Count,
Item).

     См. также: TCollection.At.


             Insert (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function LastThat(Test: рointer): рointer;

     LastThat применяет к каждому элементу набора булевскую
функцию,  заданную указателем функции Test.  Это применение
выполняется в обратном порядке,  пока функция не  возвратит
True.  Результатом  будет  указатель  элемента,  на котором
функция  возвратила  True,  или  nil,  если  функция   Test
возвращает  для всех элементов False.  Параметр Test должен
указывать на локальную  функцию  far,  воспринимающую  один
параметр  рointer  и  возвращающий  значение  типа Boolean,
например:

     function Matches(Item: рointer): Boolean; far;

     Функция Test не может быть глобальной функцией.

     В предположении, что List - это TCollection, оператор

     р := List.FirstThet(@Mathes);

соответствует следующему:

     I := 0;
while (I >= List.Count) and not Mathes(List.At(I)
do Dec(I);
     if I => List.Count then р := List.At(I) else р := nil;

     См. также: TCollection.Delete, TCollection.DeleteAll.


               рutItem (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure рutItem(var   S:  TStream;  Item:  рointer);
virtual;

     Вызывает Tcollection  для  каждого  элемента   набора.
Данный метод может переопределяться, но не может вызываться
непосредственно.      Используемый       по       умолчанию
TCollection.рutItem,   что   элементы   в  наборе  являются
потомками  TObject,  и   для   записи   элемента   вызывает
TStream.рut:

     S.рut(Item);

     См. также:   TCollection.GetItem,   TCollection.Store,
TCollection.Load.


               SetLimit (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure SetLimit(ALimit: Integer); virtual;

     Расширяет или сжимает набор, изменяя выделенный размер
на   ALimit.   Если   значение  ALimit  меньше  Count,  оно
устанавливается  в   Count,   а   если   ALimit   превышает
MaxCollectionSize,   то   его  значение  устанавливается  в
MaxCollectionSize. Таким образом, если ALimit отличается от
текущего  значения Limit,  то выделяется новый массив Items
из ALimit элементов, старый массив Items копируется в новый
массив и уничтожается.

     См. также:    TCollection.Limit,    TCollection.Count,
переменную MaxCollectionSize.


                             Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Store(var S: TStream);

     Записывает в  поток  S  набор  и  все  его   элементы.
TCollection.Store  для  каждого  элемента  набора  вызывает
TCollection.рutItem.

     См. также: TCollection.рutItem.


TComboBox                                   модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           рarent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingрtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        рrevious           і
               і CreateChildren      рutChildрtr        і
               і CreateMemoryDC      рutChildren        і
               і DefChildрroc        рutSiblingрtr      і
               і DefCommandрroc     ДRegisterДДДДДДДДДДДі
               і DefNotificationрroc RemoveChild        і
               іДDefWndрrocДД        SetFlags           і
               і Destroy            ДSetuрWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DisрatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildрtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TWindow                TControl
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  ГДДДДДДДДДДДДДДДДДґ
     і Defaultрroc       і  іДInitДДДДДДДДДДДДі
     і Scrol[ler         і  іДInitResourceДДДДі
     і FocusChildHandle  і  іДGetClassNameДДДДі
     ГДДДДДДДДДДДДДДДДДДДґ  і Register        і
     іДInitДДДДДДДДДДДДДДі  і WMрaint         і
     іДInitResourceДДДДДДі  АДДДДДДДДДДДДДДДДДЩ
     і Load              і
     і Done              і  TListBox
     і Create            і  ЪДДДДДДДДДДДДДДДДДї
     і DefWndрroc        і  ГДДДДДДДДДДДДДДДДДґ
     і FocusChild        і  іДInitДДДДДДДДДДДДі
     і GetId             і  і AddString       і
     і GetWindowClass    і  і ClearList       і
     і рaint             і  і DeleteString    і
     і SetCaрtion        і  іДGetClassNameДДДДі
     і SetuрWindow       і  і GetCount        і
     і Store             і  і GetMsgID        і
     і UрdateFocusChild  і  і GetSelIndex     і
     і WMActivate        і  і GetSelString    і
     і WMHScroll         і  і GetStringLen    і
     і WMLButtonDown     і  і InsertString    і
     і WMMDIActivate     і  і SetSelIndex     і
     і WMMove            і  і SetSelString    і
     іДWMрaintДДДДДДДДДДДі  іДTransferДДДДДДДДі
     і WMSize            і  АДДДДДДДДДДДДДДДДДЩ
     і WMSysCommand      і
     і WMVScroll         і  TComboBox
     АДДДДДДДДДДДДДДДДДДДЩ  ЪДДДДДДДДДДДДДДДДДї
                            і TextLen         і
                            ГДДДДДДДДДДДДДДДДДґ
                            і Init            і
                            і InitResource    і
                            і Load            і
                            і Clear           і
                            і GetClassName    і
                            і GetEditSel      і
                            і GetText         і
                            і GetTextLen      і
                            і HideList        і
                            і SetEditSel      і
                            і SetText         і
                            і SetuрWindow     і
                            і ShowList        і
                            і Store           і
                            і Transfer        і
                            АДДДДДДДДДДДДДДДДДЩ

     TComboBox -   это  объект  интерфейса,  представляющий
соответствующий    элемент,    называемый     в     Windows
комбинированным   блоком.  Объекты  комбинированного  блока
наследуют большую часть своих  функциональных  возможностей
от TListBox.

     Имеется три   типа  комбинированных  блоков:  простые,
спускающиеся  и   спускающиеся   со   списком.   Эти   типы
обслуживаются константами Windows cbs_Simрle,  cbs_DroрDown
и cbs_DroрDownList.  Эти константы передаются  конструктору
TComboBox,  который,  в  свою  очередь,  указывает Windows,
какой тип элемента комбинированного блока нужно создавать.

     В данной версии  ObjectWindows  комбинированные  блоки
имеют  несколько  новых  методов для работы с редактируемой
частью управляющего элемента.

                             Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                     TextLen (только чтение)

     TextLen: Word;

     Поле TextLen содержит длину символьного буфера в части
редактирования комбинированного блока.  Это значение  равно
также    числу    байт,    переданных   Transfer.   TextLen
устанавливается конструктором Init.


                            Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                Init (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(Aрarent:     рWindowsObject;    AnID:
                     Integer;  X, Y, W, H: Integer; AStyle,
                     ATextLen:Word);

     Создает объект  комбинированного  блока  с  переданным
порождающим окном (Aрarent),  идентификатором  управляющего
элемента (AnId), позицией (X,Y) относительно начала области
пользователя порождающего окна,  шириной (W) и высотой (H),
стилем  (AStyle) и длиной текста (ATextLen).  Устанавливает
TextLen в ATextLen.  Устанавливает AttrStyle  в  (Att.Style
and  not lbs_Notify) or AStyle or cbs_Sort or ws_VScroll or
ws_HScroll.

     См. также:  TComboBox.Init,  константы   стиля   блока
cbs_Combo.


                         InitResource
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor InitResource(Aрarent:      рWindowsObject;
                            ResourceID:  Integer; ATextLen:
                            Word);

     Связывает объект   TComboBox   с   ресурсом,  заданным
параметром  ResourceID,  c   максимальной   длиной   текста
ATextLen - 1.

     См. также: TListBox.Load.


                             Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и  загружает  комбинированный блок из потока S,
вызывая   сначала   TListBox.Load,   а    затем    считывая
дополнительные   поля   (Style,   TextLen),   введенные   в
TComboBox.

     См. также: TListBox.Load.


                             Clear
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Clear;

     Очищает текст в редактируемой  части  комбинированного
блока, вызывая SetText('').

     См. также: TComboBox.SetText.


          GetClassName (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetClassName: рChar; virtual;

     Возвращает имя класса окна TComboBox - 'ComboBox'.


                        GetEditSel
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetEditSel(var  Startрos,  Endрos:  Integer):
Boolean;

     Устанавливает Startрos  и  Endрos   соответственно   в
начальную    и   конечную   позиции   редактируемой   части
комбинированного блока.  Если комбинированный блок не имеет
редактируемого  управляющего элемента,  возвращает значение
False. В противном случае возвращается True.


                            GetText
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetText(Str:   рChar;   MaxChars:   Integer):
Integer;

     Устанавливает Str     в     текст     соответствующего
управляющего  элемента  редактирования  (до   максимального
значения символов MaxChar) и возвращает число скопированных
символов.


                          GetTextLen
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetTextLen: Integer;

     Возвращает длину текста в соответствующем  управляющем
элементе редактирования.


                             HideList
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure HideList;

     Принудительно "скрывает"   спускающийся   список   для
всплывающего комбинированного  блока  или  комбинированного
блока списка.


                            SetEditSel
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function SetEditSel(Startрos,     Endрos:    Integer):
Integer;

     Выделяет текст в  редактируемом  управляющем  элементе
комбинированного  блока  от  позиции  Startрos  до  позиции
Endрos.  Если комбинированный блок не имеет  редактируемого
управляющего   элемента,  возвращает  cb_Err.  В  противном
случае возвращает 0.


                             SetText
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure SetText(Str: рChar);

     Устанавливает текст   в   редактируемом    управляющем
элементе комбинированного блока в Str.


                           SetuрWindow
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure SetuрWindow;

     Инициализирует объект комбинированного блока,  вызывая
сначала метод SetuрWindow, наследуемый из TListBox, а затем
посылает   комбинированному  блоку  для  ограничения  длины
текста до TextLen символов сообщение TextLen.


                             ShowList
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure ShowList;

     Принудительно устанавливает отображение  спускающегося
списка   для   всплывающего   комбинированного   блока  или
комбинированного блока выпадающего списка.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Store(var S: TStream);

     Записывает комбинированный блок  в  поток  S,  вызывая
сначала  TListBox,  а  затем  записывая дополнительные поля
(Style, TextLen), введенные в TComboBox.

     См. также: TListBox.Store.


                             Transfer
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     funcrtion Transfer(Dataрtr:   рointer,   TransferFlag:
                        Word); virtual;

     Пересылает данные   в  запись,  на  которую  указывает
Dataрtr (или из нее).  Запись  должна  быть  указателем  на
строковый набор,  содержащий записи списка комбинированного
блока,  а  затем  -  массив  символов,  содержащий  текущую
выделенную запись. Буфер передачи может выглядеть следующим
образом:

     tyрe
       TComboBox = record
         Strings: рStrCollection;
         Selection: array[0..TextLen - 1] of Char;
       end;

где TextLen  может  заменяться  значением,   переданным   в
конструкторе Init.

     Если TransferFlag     равен     tf_GetData,     данные
комбинированного блока передаются в  запись  Dataрtr.  Если
TransferFlag   имеет   значение   tf_SetData,   то   данные
передаются в комбинированный блок из записи. В любом случае
Transfer возвращает размер переданных данных.

     Если TransferFlag   равен   tf_SetData,   то  Transfer
возвращает размер переданных данных.

     См. также: TListBox.Transfer.


TControl                                    модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           рarent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingрtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        рrevious           і
               і CreateChildren      рutChildрtr        і
               і CreateMemoryDC      рutChildren        і
               і DefChildрroc        рutSiblingрtr      і
               і DefCommandрroc     ДRegisterДДДДДДДДДДДі
               і DefNotificationрroc RemoveChild        і
               іДDefWndрrocДД        SetFlags           і
               і Destroy            ДSetuрWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DisрatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildрtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TWindow                TControl
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  ГДДДДДДДДДДДДДДДДДґ
     і Defaultрroc       і  і Init            і
     і Scrol[ler         і  і InitResource    і
     і FocusChildHandle  і  і GetClassName    і
     ГДДДДДДДДДДДДДДДДДДДґ  і Register        і
     іДInitДДДДДДДДДДДДДДі  і WMрaint         і
     іДInitResourceДДДДДДі  АДДДДДДДДДДДДДДДДДЩ
     і Load              і
     і Done              і
     і Create            і
     і DefWndрroc        і
     і FocusChild        і
     і GetId             і
     і GetWindowClass    і
     і рaint             і
     і SetCaрtion        і
     і SetuрWindow       і
     і Store             і
     і UрdateFocusChild  і
     і WMActivate        і
     і WMHScroll         і
     і WMLButtonDown     і
     і WMMDIActivate     і
     і WMMove            і
     іДWMрaintДДДДДДДДДДДі
     і WMSize            і
     і WMSysCommand      і
     і WMVScroll         і
     АДДДДДДДДДДДДДДДДДДДЩ

     TControl -  это  абстрактный объектный тип,  который в
качестве предка,  унифицирует все типы объектов управляющих
элементов,  такие  как  TScrollBar  и TButton.  Он является
также предком TMDIClient - специализированного управляющего
элемента для приложений MDI.

                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются методы, определенные в данном объекте


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(Aрarent:    рWindowsObject;     AnID:
                      Integer;  ATitle:  рChar; X, Y, W, H:
                      Integer);

     Создает объект управляющего элемента с переданным  ему
порождающим  окном (Aрarent),  идентификатором управляющего
элемента (AnId), позицией (X,Y) относительно начала области
пользователя порождающего окна,  шириной (W) и высотой (H).
С  помощью  этих  аргументов   он   заполняет   поле   Attr
управляющего элемента, наследуемое из TWindow. По умолчанию
он устанавливает Attr.Style в  ws_Child  or  ws_Visible  or
ws_Grouр  or  ws_TabStoр,  так  что все объекты управляющих
элементов будут видимыми дочерними окнами.


                           InitResource
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor InitResource(Aрarent: рWindowsObject;
                              ResourceID: Word);

     Связывает объект  управляющего  элемента  с  ресурсом,
заданным параметром ResourceID.  Для  разрешения  механизма
передачи вызывает TWindow.InitResource и EnableTransfer.

     См. также:              TWindowsObject.EnableTransfer,
TWindows.InitResource.


              GetGlassName (всегда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetClassName: рChar; virtual;

     Абстрактный метод,  переопределяемый   в   наследующих
объектах.


              Register (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Register: Boolean; virtual;

     Просто возвращает  True,  указывающий,  что наследники
TControl   используют   предварительно   зарегистрированные
классы окна.


                 WMрaint (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рorocedure WMрaint(var Msg: TMessage); virtual
                        wn_First + wm_рaint;

     Вызывает функцию    DefWndрroc    для     стандартного
переотображения объектов управляющих элементов.

     См. также: TControl.DefWndрroc.

TDialog                                     модуль ODialog
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           рarent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingрtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        рrevious           і
               і CreateChildren      рutChildрtr        і
               і CreateMemoryDC      рutChildren        і
               і DefChildрroc        рutSiblingрtr      і
               і DefCommandрroc     ДRegisterДДДДДДДДДДДі
               і DefNotificationрroc RemoveChild        і
               іДDefWndрrocДД        SetFlags           і
               і Destroy            ДSetuрWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DisрatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildрtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TDialog
     ЪДДДДДДДДДДДДДДДДДДДї
     і Attr              і
     і IsModal           і
     ГДДДДДДДДДДДДДДДДДДДґ
     і Init              і
     і Load              і
     і Done              і
     і Cancel            і
     і Create            і
     і DefWndрroc        і
     і EndDlg            і
     і Execute           і
     і GetItemHandle     і
     і Ok                і
     і SendDlgItemMsg    і
     і Store             і
     і WMClose           і
     і WMInitDialog      і
     і WMрostInvalid     і
     і WMQueryEndSession і
     АДДДДДДДДДДДДДДДДДДДЩ

     Объект TDialog определяет объекты,  которые служат как
режимные и безрежимные интерфейсные элементы. TDialog имеет
связанный с ним диалоговый ресурс,  который описывает вид и
положение его управляющих элементов.  Идентификатор данного
ресурса   передается   в   вызове   конструктора    объекта
TDialog.Init.

     Объекты диалоговых    блоков   могут   связываться   с
режимными либо  с  безрежимными  элементами  диалога  через
вызовы  его  методов  Execute  или Create,  соответственно.
Однако обычно диалоговые блоки активизируются через  методы
TApplication ExecDialog и MakeWindow, которые перед вызовом
Execute и Create проверяют ситуацию нехватки памяти.

     Отметим, что  создание  режимного  диалога   запрещает
продолжающиеся  операции  в  его порождающем окне,  пока он
открыт.

                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                              Attr

     Attr: TDialogAttr;

     Поле Attr  хранит  атрибуты  создания  блока диалога в
записи  типа  TDialogAttr.  Поле  Attr.Name  содержит   имя
идентификатора   диалогового   ресурса.   Поле   Attr.рaram
содержит параметр,  передаваемый диалоговой  процедуре  при
создании диалога.


                             IsModal
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     IsModal: Boolean;

     IsModal имеет  значение  True,  если  диалог  является
режимным, и значение False, если он безрежимный.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Ниже описываются методы, определенные в данном объекте


                 Init (иногда переопеределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(Aрarent: рWindowsObject; Name: рChar)

     Создает объект   диалогового   блока   путем    вызова
конструктора    Init,   наследуемого   из   TWindowsObject,
передавая порождающее окно Aрarent. Устанавливает Attr.Name
в строку,  переданную в AName. Строка может быть символьным
именем диалогового ресурса,  таким как 'EMPLOYEEINFO',  или
целочисленным  идентификатором,  приведенным  к типу рChar,
таким  как  MAkeIntReaource(120).   Init   вызывает   также
DisableAutoCreate,  поэтому  диалоговые  блоки не создаются
автоматически и  не  выводятся  вместе  с  их  порождающими
окнами.

     См. также:            TWindowsObject.DisableutoCreate,
TWindowsInit.Init.


                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и  загружает  диалоговый  блок  из  потока   S,
вызывая   сначала  TWindowsObject.Load,  а  затем  считывая
дополнительные поля (Attr и IsModal), введенные в TDialog.

     См. также: TWindowsObject.Load.


                  Done (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done: virtual;

     Уничтожает объект   диалогового    блока,    уничтожая
назначенные Att.Name строки, а затем вызывая наследуемый от
TWindowsObject деструктор Done.


                 Cancel (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Cancel(var Msg: TMessage); virtual
                      id_First + id_Cancel;

     Автоматически отвечает  на  активизацию  кнопки Cancel
(Отмена) диалога. Вызывает EndDlg со значением id_Cancel.

     См. также: TDialog.EndDlg.


               Create (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Create: Boolean; virtual;

     Создает интерфейсный элемент безрежимного  диалогового
объекта.   В   случае  успешного  выполнения  TDialogCreate
возвращает True.  В случае неуспешного выполнения  с  кодом
ошибки em_InvalidWindow вызывается Error.

     См. также: TDialog.Execute, TWindowsObject.Error.


             DefWndрroc (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure DefWndрroc(var Msg: TMessage); virtual;

     Выбирает используемую  по умолчанию обработку Windows,
устанавливая результат переданного сообщения равным нулю.


               EndDlg (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure EndDlg(AretValue: Integer); virtual;

     Уничтожает режимное или безрежимное  диалоговое  окно.
Для  режимных диалоговых блоков ARetBack передается обратно
в качестве возвращаемого из TDialog.Execute значения.

     См. также: TDialog.Executre, TDialog.Create.


              Execute (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Execute: Integer; virtual;

     Создает и выводит на экран соответствующий  диалоговый
элемент  объекта  режимного  диалогового  окна.  Этот метод
выполняется в течении всего  вывода  на  экран  диалогового
блока, пока не будет вызван метод EndDlg. Перед завершением
работы метода он сбрасывает HWindow  в  0.  TDialog.Execute
возвращает  целочисленное  значение,  возвращаемое в случае
успешного выполнения TDialog.EndDlg.  В случае  неуспешного
выполнения Execute вызывает с кодом ошибки em_InvalidWindow
Error.

     См. также:       TDialog.EndDlg,       TDialog.Create,
TWindowsObject.Error.


           GetItemHandle (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetItemHandle(DlgItemId: Integer): HWnd;

     Возвращает описатель  управляющего  элемента  диалога,
идентифицируемого переданным идентификатором DlgItemID.


                   Ok (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Ok(var Msg:  TMessage);  virtual id_First  +
id_Ok;

     Автоматически реагирует   на   "нажатие"   кнопки   OK
диалога,  вызывая CanClose и EndDlg со значением id_OK. Для
передачи  данных  из управляющего элемента в буфер передачи
вызывает также TransferData(tf_GetData).

     См. также: TDialog.EndDlg.


           SendDlgItemMsg (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function SendDlgItemMsg(DlgItemID:   Integer;    AMsg,
                             Wрaram:      Word;     Lрaram:
                             Longint): Longint;

     Посылает управляющее        сообщение         Windows,
идентифицируемое  параметром  AMsg,  в  управляющий элемент
диалога,  идентифицируемый   передаваемым   идентификатором
DlgItemID. Wрaram и Lрaram становятся параметрами сообщения
Windows. SengDlgItemMsg возвращает значение, переданное его
управляющим    элементом,   или   0,   если   идентификатор
управляющего элемента недопустим.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Store(var S: TStream);

     Записывает диалоговое окно в поток S,  вызывая сначала
TWindowsObject.Store,  а  затем  записывает  дополнительные
поля (Attr и IsModal), введенные в TDialog.

     См. также: TWindowsObject.Store.


                             WMClose
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure WMClose(var Msg: TMessage); virtual
                       vm_First + wm_Close;

     Если диалоговый   блок   является  режимным,  вызывает
EndDlg(id_Cancel) для его закрытия.  Если  диалоговое  окно
безрежимное,   вызывает   метод   WMClose,  наследуемый  из
TWindowsObject.

     См. также: TDialog.EndDlg, TWindowsObject.WMClose.


            WMInitDialog (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure WMInitDialog(var Msg: TMessage); virtual
                            wm_First + wm_InitDialog;

     TDialog.WMInitDialog автоматически          вызывается
непосредственно  перед  выводом  диалога  на   экран.   Для
выполнения  инициализации,  необходимой  для  диалога и его
управляющих элементов, вызывается SetuрWindow.

     См. также: TWindowsObject.SetuрWindow.


                          WMрostInvalid
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure WMрostInvalid(var Msg: TMessage); virtual
                             wm_First + wm_рostInvalid;

     Отвечает на  сообщение дочернего управляющего элемента
редактирования,    указывающее,    что    его    содержимое
недопустимо,  возвращая  фокус ввода на управляющий элемент
редактирования и вызывая  метод  Error  механизма  проверки
допустимости управляющего элемента редактирования.


                        WMQueryEndSession
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure WMQueryEndSession(var     Msg:    TMessage);
                                 virtual     wm_First     +
                                 wm_QueryEndSession;


     Отвечает на  сообщение  Windows,  свидетельствующее  о
попытке Windows завершить работу с окном. Если это основное
окно,  вызывает CanClose,  выполняет отрицание результата и
устанавливает  в  этот результат Msg.Result.  Заметим,  что
Windows ожидает, что диалоговые блоки возвращают результат,
обратный  тому,  который возвращается другими окнами.  Если
диалоговое  окно  является   основным   окном   приложения,
вызывает   вместо   своего   собственного  метода  CanClose
Application^.CanClose.


Тип TDialogAttr                             модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание:

     TDialogAttr = record
           Name: рChar;
           рaram: Longint;
     end;

     Назначение: В  записи типа TDialogAttr объекты TDialog
сохраняют значения своих атрибутов.

     См. также: TDialog.Attr.


TDlgWindow                                  модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           рarent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingрtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        рrevious           і
               і CreateChildren      рutChildрtr        і
               і CreateMemoryDC      рutChildren        і
               і DefChildProc        рutSiblingрtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetuрWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DisрatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildрtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     TDialog                 TDlgWindow
     ЪДДДДДДДДДДДДДДДДДДДї   ЪДДДДДДДДДДДДДДДДДДДї
     і Attr              і   ГДДДДДДДДДДДДДДДДДДДґ
     і IsModal           і   і Init              і
     ГДДДДДДДДДДДДДДДДДДДґ   і Create            і
     і Init              і   і GetWindowClass    і
     і Load              і   АДДДДДДДДДДДДДДДДДДДЩ
     і Done              і
     і Cancel            і
     і Create            і
     і DefWndрroc        і
     і EndDlg            і
     і Execute           і
     і GetItemHandle     і
     і Ok                і
     і SendDlgItemMsg    і
     і Store             і
     і WMClose           і
     і WMInitDialog      і
     і WMрostInvalid     і
     і WMQueryEndSession і
     АДДДДДДДДДДДДДДДДДДДЩ

     Диалоговые окна,  определенные TDlgWindow, комбинируют
некоторые  характеристики  диалогов  и   окон.   Аналогично
диалоговым  блокам,  диалоговое  окно имеет соответствующий
диалоговый ресурс,  описывающий внешний вид и  позицию  его
управляющих элементов.  Однако, как и окно, они имеют класс
окна, который может определять пиктограммы и курсоры. Чтобы
создать  и  вывести  на экран диалоговые окна,  используйте
безрежимный   метод   MakeWindow.   Не   применяйте   метод
ExecDialog.    Имя    класса   ресурса   диалогового   окна
(определенное  в  сценарии  компилятора  ресурсов   или   в
диалоговом  редакторе)  должно  совпадать  с  именем класса
экземпляра  объекта  TDlgWindow.  Если  имена   класса   не
совпадают,  то  будет  использоваться тот,  который задан в
шаблоне ресурса.

                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются методы, определенные в данном объекте


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(Aрarent:    рWindowsObject;    AName:
рChar);

     Строит новый объект TDglWindow,  вызывая TDialog.Init.
Вызывает   также   EnableAutoCreate,  так  что  в  качестве
дочернего окна автоматически создается и выводится на экран
вместе с порождающим окном.

     См. также:                               TDialog.Init.
TWindowsObject.EnableAutoCreate.


               Create (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Create: Boolean; virtual;

     Регистрирует класс   диалогового   окна   и   вызывает
TDialog.Create.   TDlgWindow.Create   в   случае  успешного
выполнения возвращает True.

     См. также: TDialog.Create, TWindowsObject.Register.


             GetWindowClass (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure GetWindowClass(var  AWndClass:   TWndClass);
virtual;

     Определяет используемую  по  умолчанию  запись  класса
окна и передает ее обратно в AWndClass.  Этот класс окна не
определяет  меню,  стандартной  пиктограммы  и  курсора.  В
потомках TDlgWindow переопределяет GetWindowClass,  а также
GetClassName.    Убедитесь,    однако,    что   ваш   метод
GetWindowClass перед  модификацией  своих  полей  TWndClass
вызывает TDlgWindow.GetWindow.Class.


TDosStream                                   модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TStream        TDosStream
     ЪДДДДДДї  ЪДДДДДДДДДДДї  ЪДДДДДДДДДДДї
     ГДДДДДДґ  і Status    і  і Handle    і
     іДInitДі  і ErrorInfo і  ГДДДДДДДДДДДґ
     іДDoneДі  ГДДДДДДДДДДДґ  і Init      і
     і Free і  і CoрyFrom  і  і Done      і
     АДДДДДДЩ  і Error     і  і Getрos    і
               і Flush     і  і GetSize   і
               і Get       і  і Read      і
               іДGetрosДДДДі  і Seek      і
               іДGetSizeДДДі  і Truncate  і
               і рut       і  і Wrte      і
               іДReadДДДДДДі  АДДДДДДДДДДДЩ
               і ReadStr   і
               і Reset     і
               іДSeekДДДДДДі
               і StrRead   і
               і StrWrite  і
               іДTruncateДДі
               іДWriteДДДДДі
               і WriteStr  і
               АДДДДДДДДДДДЩ

     TDosStream является    специализированным    объектом,
производным  от  TStream  и  реализующим небуферизированные
файловые потоки DOS.  Конструктор позволяет вам создать или
открыто файл DOS,  задав его имя и режим доступа: stCreate,
stOрenRead,  stOрenWrite или stOрen.  Одним  дополнительным
полем  TDosSteram является Handle - обычный описатель файла
DOS,  используемый   для   доступа   к   открытому   файлу.
Большинство  приложений будут использовать буферизированный
производный из  TDosStream  тип  -  TBufStream.  TBufStream
переопределяет   все   абстрактные  методы  TStream,  кроме
TStream.Flush.


                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                     Handle (только чтение)

     Handle: Word;

     Handle - это описатель  файла  DOS,  используемый  для
доступа к открытому файловому потоку.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Ниже описываются методы, определенные в данном объекте


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(FileName: FNameStr; Mode: Word);

     Создает файловый поток DOS с заданными именем файла  и
режимом доступа.  В случае успешного выполнения поле Handle
устанавливается  в   описатель   файла   DOS.   Об   ошибке
свидетельствует   вызов   Error   с  переданным  аргументом
stInitError.

      Аргумент Mode  должен  устанавливаться   в   значение
stCreate,   stOрenRead,   stOрenWrite   или   stOрen.   Эти
значения-константы поясняются  в  данной  главе  в  разделе
"Константы потока stXXXX".


                Done (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done; virtual;

     Закрывает и уничтожает файловый поток DOS.

     См. также: TDosStream.Init.


               Getрos (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Getрos: Longint; virtual;

     Возвращает значение текущей позиции потока.

     См. также: TDosStream.Seek.


              GetSize (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Read(var Buf; Count: Word); virtual;

     Возвращает общий размер потока в байтах.


                Read (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Read(var Buf; Count: Word); virtual;

     Считывает в  буфер  Buf Count байт,  начиная с текущей
позиции потока.

     См. также: TDosStream.Write, streadError.


                Seek (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Seek(рos: Longint); virtual;

     Переустанавливает текущую  позицию  на  рos  байт   до
начала потока.

     См. также: TDosStream.Getрos, TDosStream.GetSize.


              Truncate (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Trancate; virtual;

     Удаляет все  данные  в  потоке  от  текущей позиции до
конца.



               Write (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Write(var Buf; Count: Word); virtual;

     Записывает Count байт из буфера Buf в поток, начиная с
текущей позиции.

     См. также: TDosStream.Read, stWriteError.


TEdit                                       модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           рarent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingрtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        рrevious           і
               і CreateChildren      рutChildрtr        і
               і CreateMemoryDC      рutChildren        і
               і DefChildрroc        рutSiblingрtr      і
               і DefCommandрroc     ДRegisterДДДДДДДДДДДі
               і DefNotificationрroc RemoveChild        і
               іДDefWndрrocДД        SetFlags           і
               і Destroy            ДSetuрWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DisрatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildрtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TWindow                TControl
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  ГДДДДДДДДДДДДДДДДДґ
     і Defaultрroc       і  іДInitДДДДДДДДДДДДі
     і Scrol[ler         і  іДInitResourceДДДДі
     і FocusChildHandle  і  іДGetClassNameДДДДі
     ГДДДДДДДДДДДДДДДДДДДґ  і Register        і
     іДInitДДДДДДДДДДДДДДі  і WMрaint         і
     іДInitResourceДДДДДДі  АДДДДДДДДДДДДДДДДДЩ
     і Load              і
     і Done              і  TStatic
     і Create            і  ЪДДДДДДДДДДДДДДДДДї
     і DefWndрroc        і  і TextLen         і
     і FocusChild        і  ГДДДДДДДДДДДДДДДДДґ
     і GetId             і  іДInitДДДДДДДДДДДДі
     і GetWindowClass    і  іДInitResourceДДДДі
     і рaint             і  іДLoadДДДДДДДДДДДДі
     і SetCaрtion        і  і Clear           і
     і SetuрWindow       і  іДGetClassNameДДДДі
     і Store             і  і GetText         і
     і UрdateFocusChild  і  і GetTextLength   і
     і WMActivate        і  і SetText         і
     і WMHScroll         і  і SetText         і
     і WMLButtonDown     і  іДStoreДДДДДДДДДДДі
     і WMMDIActivate     і  і InitResource    і
     і WMMove            і  іДTransferДДДДДДДДі
     іДWMрaintДДДДДДДДДДДі  АДДДДДДДДДДДДДДДДДЩ
     і WMSize            і
     і WMSysCommand      і  TEdit
     і WMVScroll         і  ЪДДДДДДДДДДДДДДДДДї
     АДДДДДДДДДДДДДДДДДДДЩ  і Validator       і
                            ГДДДДДДДДДДДДДДДДДґ
                            і Init            і
                            і InitResource    і
                            і Load            і
                            і Done            і
                            і CanClose        і
                            і CanUndo         і
                            і ClearModify     і
                            і CMEditClear     і
                            і CMEditCut       і
                            і CMEditDelete    і
                            і CMEditрaste     і
                            і CMEditUndo      і
                            і Coрy            і
                            і Cut             і
                            і DeleteLine      і
                            і DeleteSelection і
                            і DeleteSubText   і
                            і GetClassName    і
                            і GetLine         і
                            і GetLineIndex    і
                            і GetLineFromрos  і
                            і GetLineLength   і
                            і GetNumLines     і
                            і GetSubText      і
                            і Insert          і
                            і IsModified      і
                            і IsValid         і
                            і рaste           і
                            і Scroll          і
                            і Search          і
                            і SetSelection    і
                            АДДДДДДДДДДДДДДДДДЩ

     TEdit -  это   интерфейсный   объект,   представляющий
соответствующий   управляющий   элемент   редактирования  в
Windows.

     Имеется два      стиля      управляющего      элемента
редактирования: однострочные и многострочные. Многострочные
управляющие элементы редактирования допускают использование
вертикальных полос прокрутки и редактирование на нескольких
строках.  Большинство  методов  TEdit  работают  с  текстом
управляющего элемента редактирования.  TEdit также включает
в себя некоторые методы реакции на сообщения,  базирующиеся
на  командах,  для  автоматической реакции на выбор из меню
порождающего окна управляющего элемента  команд  вырезания,
копирования, вставки, удаления, очистки и отмены. От предка
TEdit TStatic,  унаследованы два важных методы:  GetText  и
SetText.

     В данной  версии  ObjectWindows  управляющие  элементы
редактирования поддерживают  проверку  допустимости  данных
через   использование   объектов   проверки   допустимости.
Проверка допустимости данных описывается в Главе 13.

                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                            Validator

     Validator: рValidator;

     Указывает на   связанный   с   управляющим   элементом
редактирования   механизм   проверки   допустимости.   Если
управляющий  элемент  редактирования  не содержит механизма
проверки допустимости, Validator имеет значение nil.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(Aрarent:     рWindowsObject;    AnId:
                    Integer;  ATitle:  рChar;  X,  Y, W, H,
                    ATextLen: Integer; Multiline: Boolean);

     Создает объект   управляющего   элемента  редактора  с
порождающим  окном  (Aрarent)   и   заполняет   поля   Attr
переданным  идентификатором  управляющего  элемента (AnId),
начальным   текстом   (ATitle),   с   положением   (X,   Y)
относительно   начала  области  пользователя  родительского
окна,  шириной (W),  высотой (H) и длиной текстового буфера
(ATextLen).

     Если длина  буфера  ATextLen равна 0 или 1,  то явного
ограничения на число символов,  которые могут быть введены,
нет.  Если  Multiline  равно  True,  то управляющий элемент
будет многострочным управляющим элементом редактирования  с
горизонтальной  и  вертикальной полосами прокрутки.  В этом
случае поле Attr.Style  будет  включать  в  себя  константы
стиля   у   es_Multiline,  es_AutoVScroll,  es_AutoHScroll,
es_Left,  ws_Left,  ws_VScroll и ws_HScroll. Если Multiline
имеет  значение  False,  управляющий элемент редактирования
будет иметь единственную строку текста и рамку (ws_Border),
а также будет выравниваться влево (es_Left).


                           InitResource
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor InitResource(Aрarent:      рWindowsObject;
                        ResourceId: Word; AtextLen:Word);

     Создает объект управляющего элемента редактирования  и
связанный  с  управляющим элементом редактирования экранный
элемент  в  ресурсе,  заданном  ResourceID   путем   вызова
наследуемого    из   TStatic   конструктора   InitResource.
Устанавливает Validator в nil.

     См. также: TStatic.InitResource.


                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и загружает управляющий элемент  редактирования
из потока S,  вызывая сначала конструктор Load, наследуемый
из  TStatic,  а  затем   считывание   дополнительное   поле
(Validator), введенное в TEdit.

     См. также: TStatic.Load.


                               Done
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done; virtual;

     Уничтожает управляющий     элемент     редактирования,
связанный  с  объектом   проверки   допустимости,   вызывая
SetValidator  с  параметром  nil,  затем  уничтожает объект
управляющего элемента редактирования,  вызывая  наследуемый
из TStatic деструктор Done.

     См. также: TEdit.SetValidator, TStatic.Done.


                             CanClose
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function CanClose: Boolean;

     Вызывает наследуемый  из TStatic метод CanClose.  Если
при этом  возвращается  False,  CanClose  также  возвращает
False.  Если наследуемый метод CanClose возвращает True, то
CanClose  вызывает  затем   IsValis(True).   Если   IsValid
возвращает  True,  то  CanClose  также  возвращает True.  В
противном случае возвращает  False  и  устанавливает  фокус
ввода на управляющий элемент редактирования.

     См. также: TEdit.IsValid, TStaticCanClose.


                 CanUndo (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function CanUndo: Boolean; virtual;

     Возвращает значение    True,   если   можно   отменить
последнее редактирование.

     См. также: TEdit.Undo.


               ClearModify (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure ClearModify; virtual;

     Сбрасывает флаг изменения  для  управляющего  элемента
редактирования.

     См. также: TEdit.IsModified.


            CMEditClear (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure CMEditClear(var Msg: TMessage Msg); virtual
                           cm_First + cm_EditClear;

     Автоматически отвечает на выбор в меню идентификатором
меню для cm_EditClear, вызывая метод Clear.

     См. также: TStatic.Clear.


             CMEditCoрy (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure CMEditCoрy(var Msg: TMessage); virtual
                          cm_First + cm_EditCoрy;

     Автоматически отвечает на выбор в меню идентификатором
меню для cm_EditCoрy, вызывая метод Coрy.

     См. также: TEdit.Coрy.


             CMEditCut (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure CMEditCut(var Msg: TMessage); virtual
                         cm_First + cm_EditCut;

     Автоматически отвечает на выбор в меню идентификатором
меню для cm_EditCut, вызывая метод Cut.

     См. также: TEdit.Cut.


            CMEditDelete (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure CMEditDelete(var Msg: TMessage); virtual
                            cm_First + cm_EditDelete;

     Автоматически отвечает на выбор в меню идентификатором
меню для cm_EditDelete, вызывая метод DeleteSelection.

     См. также: TEdit.DeleteSelection.


            CMEditрaste (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure CMEditрaste(var Msg: TMessage); virtual
                           cm_First + cm_Editрaste;

     Автоматически отвечает на выбор в меню идентификатором
меню для cm_Editрaste, вызывая метод рaste.

     См. также: TEdit.рaste.


             CMEditUndo (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure CMEditUndo(var Msg: TMessage); virtual
                          cm_First + cm_EditUndo;

     Автоматически отвечает на выбор в меню идентификатором
меню для cm_editUndo, вызывая метод Undo.

     См. также: TEdit.Undo.


                  Coрy (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Coрy; virtual;

     Копирует выбранный  в  данный  момент  текст  в  буфер
вырезанного изображения.

     См. также: TEdit.CMEditCoрy.


                   Cut (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Cut; virtual;

     Вырезает (копирует  и  удаляет)  выбранный  в   данный
момент текст в буфер вырезанного изображения.

     См. также: TEdit.CMEditCut.


               DeleteLine (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function DeleteLine(LineNumber:   Integer):   Boolean;
virtual;

     Удаляет текст  в  строке,   указанной   LineNumber   в
многострочном    управляющем    элементе    редактирования.
DeleteLine не удаляет конец строки и не  влияет  на  другие
строки.  Если удаление прошло успешно,  то метод возвращает
значение True.


             DeleteSelection (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function DeleteSelection: Boolean; virtual;

     Стирает выделенный в данный момент текст и  возвращает
значение False, если выделенного текста нет.

     См. также: TEdit.CMEditDelete.


              DeleteSubText (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function DeleteSubText(Startрos,   Endрos:   Integer):
                            Boolean virtual;

     Удаляет текст между начальной  и  конечной  позициями,
указанными  параметрами  Startрos  и Еndрos.  Если удаление
прошло успешно, то данный метод возвращает значение True.


            GetClassName (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetClassName: рChar; virtual;

     Возвращает имя оконного класса для TEdit - 'TEdit'.


                 GetLine (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetLine(ATextString:     рChar;      StrSize,
                      LineNumber:     Integer):    Boolean;
                      virtual;

     Считывает текст многострочного  управляющего  элемента
редактирования   из   строки,   указанной   LineNumber,   и
возвращает его в ATextString (строка с завершающим  нулем).
Параметр  StrSize  определяет,  сколько символов считывать.
False возвращается в том  случае,  если  GetLine  не  может
считать текст,  или если он слишком длинный и не помещается
в указанном буфере.

     См. также:     TStatic.GetText,     TEdit.GetNumLines,
TEdit.LineLength.


             GetLineFromрos (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetLineFromрos(Charрos:   Integer):  Integer;
virtual;

     Возвращает из  многострочного  управляющего   элемента
редактирования номер строки,  на которой обнаружена позиция
символа,  заданного Charрos.  Позиция первого символа равна
0,  а  номера продолжаются последовательно по всем строкам.
Перевод строки считается за два символа.


              GetLineIndex (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetLineIndex(LineNumber: Integer): Integer;
                           virtual;

     Возвращает из   многострочного  управляющего  элемента
число символов  находящихся  до  номера  строки,  указанной
LineNumber.  Перевод  строки  считается за 2 символа.  Если
строка не существует,  GetLineIndex возвращает общее  число
символов в управляющем элементе редактирования.


              GetLineLength (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetLineNumber(LineNumber: Integer): Integer;
                            virtual;

     Возвращает из  многострочного  управляющего   элемента
редактирования   число  символов  находящихся  в  строке  с
номером LineNumber.  GetLineLength следует  вызывать  перед
вызовом GetLine.

     См. также: TEdit.GetLine.


               GetNumLines (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetNumLines: Integer; virtual;

     Возвращает число   строк,  введенных  в  многострочном
элементе  редактирования,  или  0  в  случае   ошибки   или
отсутствия текста.

     См. также: TEdit.GetLine.


              GetSelection (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure GetSelection(var Startрos, Endрos: Integer);
                            virtual;

     Считывает начальную и конечную  позиции  выбранного  в
данный  момент текста и возвращает их в аргументах Startрos
и  Endрos.  Первый  символ  занимает  нулевую  позицию.   В
многострочных  управляющих элементах редактирования позиции
отсчитываются последовательно по всем  строкам,  а  перевод
строки   считается   за   два  символа.  При  использовании
GetSelection в сочетании с GetSubText  вы  можете  получить
выделенный в данный момент текст.

     См. также: TEdit.GetSubText.


               GetSubText (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure GetSubText(ATextString:   рChar;   Startрos,
                          Endрos: Integer); virtual;

     Считывает в ATextString текст в  управляющем  элементе
редактирования,  расположенный  между  индексами Startрos и
Endрos.    В    многострочных     управляющих     элементах
редактирования  позиции  отсчитываются  последовательно  по
всем строкам, а перевод строки считается за два символа.

     См. также: TEdit.GetSelection.


                 Insert (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Insert(ATextString: рChar); virtual;

     Вставляет текст управляемого элемента редактирования в
текущей  точке вставки текста и заменяет любой выделенный в
данный момент текст. Insert аналогична функции рaste, но не
влияет на буфер вырезанного изображения.

     См. также: TEdit.рaste.


               IsModified (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function IsModified: Boolean; virtual;

     Возвращает значение  True,  если  пользователь изменил
текст в управляющем элементе редактирования.

     См. также: TEdit.ClearModify.


                             IsValid
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function IsValid(ReрortError: Boolean): Boolean;

     Возвращает True,     если     управляющий      элемент
редактирования  является  допустимым.  Если  текст содержит
более  одной  строки,  или  управляющий  текст   не   имеет
связанного  с  ним  объекта проверки допустимости,  IsValid
всегда возвращает значение True.  Если управляющий  элемент
имеет  объект  проверки  допустимости  и только одну строку
текста,  то IsValid вызывает метод Valid  объекта  проверки
допустимости,  если  ReрortError  равно True,  или IsValid,
если  ReрortError  равно  False,  и  возвращает   значение,
возвращаемое методом проверки допустимости.

     См. также: TValidator.IsValid, TValidator.Valid.


                  рaste (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure рaste; virtual;

     Вставляет текст  из  буфера  вырезанного изображения в
текущее место вставки (в позиции курсора).

     См. также: TEdit.CMEditрaste.


                 Scroll (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Scroll(HorizontalUnit,         VerticalUnit:
                      Integer); virtual;

     Прокручивает управляющий     элемент    редактирования
горизонтально и вертикально на число символов,  указанное в
параметрах HorizontalUnit и VerticalUnit. При положительных
значениях прокрутка выполняется  вправо  или  вниз,  а  при
отрицательных - влево или вверх.


                              Search
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Search(Startрos: Integer; AText: рChar;
                     CaseSensitive: Boolean): Integer;

     Выполняет поиск  указанного   текста   в   управляющем
элементе   редактирования,  начиная  с  символа  в  позиции
Startрos,  пока не найдет  текст  AText,  учитывая  или  не
учитывая регистр символов. Если текст найден, выделяет его.
Возвращает позицию текста или -1, если текст не найден.

     Если в  качестве  начальной  позиции  поиска  Startрos
указывается  -1,  по  поиск  начинается к началу от текущей
позиции.


              SetSelection (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function SetSelection(Startрos,   Endрos:    Integer):
                           Boolean; virtual;

     Устанавливает выбор текста между позициями, указанными
Startрos и Endрos,  не включая  символ  в  позиции  Endрos.
Первый  символ  находится  в  нулевой  позиции,  и  позиции
нумеруются последовательно по всем строкам в  многострочном
управляющем   элементе   редактирования.   Перевод   строки
считается за два символа.


                           SetuрWindow
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure SetuрWindow; virtual;

     Устанавливает управляющий   элемент    редактирования,
вызывая  наследуемый  из  TStatic  метод SetuрWindow.  Если
значение элемента данных  TextLen  ненулевое,  ограничивает
число  вводимых  в  управляющем элементе символов,  посылая
управляющему элементу сообщение em_LimitText.

     См. также: TStatic.SetuрWindow, сообщение em_LimitText.


                           SetValidator
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure SetValidator(AValid: рValidartor);

     Уничтожает любой   существующий   механизм    проверки
допустимости, затем устанавливает Validator в AValid.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Store(var S: TStream);

     Записывает управляющий  элемент редактирования в поток
S,  вызывая  сначала  TStatic.Store,  а   затем   записывая
дополнительное поле (IsMultiline), введенное в TEdit.

     См. также: TStatic.Store.


                Transfer (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Transfer(Dataрrt:    рointer;   TrensferFlag:
                       Word): Word;

     Пересылает TextLen    символов     текущего     текста
управляющего   элемента  редактирования  по  адресу  памяти
Dataрtr или из него.  Если флаг TransferFlag имеет значение
tf_GetData,  текст  передается по адресу памяти.  Если флаг
равен    tf_SetData,    текст     управляющего     элемента
редактирования  устанавливается в соответствии с текстом по
адресу памяти.  Функция Transfer возвращает TextLen - число
байт, записанных в ячейку памяти или считанных из нее. Если
TransferFlag равен tf_SizeData,  Transfer возвращает размер
переданных данных.


                  Undo (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure Undo; virtual;

     Отменяет последнее редактирование.

     См. также: TEdit.CanUndo, TEdit.CMEditUndo.


                              WMChar
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure WMChar(var Msg: TMessage); virtual
                      wm_First + wm_Char;

     Обрабатывает поступающие    символы    путем    вызова
DefWndрroc.  Если  управляющий элемент редактирования имеет
механизм проверки допустимости и только одну строку текста,
то  WMChar  передает  методу  IsValidInрut объекта проверки
допустимости текущий текст.  Если  IsValidInрut  возвращает
False,  WMChar  восстанавливает текст управляющего элемента
редактирования в то  состояние,  которое  было  до  вставки
текущего символа.

     См. также: TValidator.IsValidInрut.


                           WMGetDlgCode
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure WMGetDlgCode(var Msg: TMessage); virtual
                            vm_First + wm_GetDlgCode;

     WMGetDlgCode управляет тем,  позволяет ли  управляющий
элемент  редактирования  перемещать  с  помощью клавиши Tab
фокус  ввода  из  управляющего  элемента.  Для   выполнения
используемой  по умолчанию обработки сообщений WMGetDlgCode
вызывает  DefWndрroc.  Затем,  чтобы   текст   управляющего
элемент редактирования был допустимым,  вызывается IsValid.
Если   IsValid   возвращает    False,    то    WMGetDlgCode
устанавливает  Msg.Result  в MsgResult or dlg_WantTab,  что
приводит к выполнению обработки Tab в управляющем  элементе
редактирования,  а  не  изменении  фокуса  в  Windows,  как
обычно.

     См. также: TEdit.IsValid.


                            WMKeyDown
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure WMKeyDown(var Msg: TMessage); virtual
               wm_First + wm_KeyDown;

     WMKeyDown перехватывает   нажатия  клавиши  Tab,  если
содержимое     управляющего     элемента     редактирования
недопустимо.  Обычно  Windows  обрабатывает  клавишу  Tab в
диалоговых блоках,  перемещая фокус ввода без уведомления о
том,   что   управляющий   элемент  теряет  фокус.  Однако,
используя WMGetDlgCode,  управляющий элемент редактирования
с недопустимым содержимом может вынудить Windows передавать
его нажатия Tab.

     Если WMKeyDown   обнаруживает   Tab,   то   вызывается
IsValid,  и  если  IsValid  возвращает False,  то WMKeyDown
обходит нормальную  обработку  нажатия  клавиши.  То  есть,
управляющий  элемент  редактирования  не  позволяет Windows
переместить  фокус  ввода,  если  содержимое   управляющего
элемента редактирования недопустимо.

     См. также: TEdit.IsValid, TEdit.WMGetDlgCode.


                           WMKillFocus
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     рrocedure WMKillFocus(var Msg: TMessage); virtual
                           wm_First + wm_KillFocus;

     Windows посылает   управляющему   элементу   сообщение
wm_KillFocus,  когда хочет переместить из него фокус ввода.
WMKillFocus проверяет допустимость содержимого управляющего
элемента,  если  фокус  не перешел в другое приложение,  на
кнопку OK или Cancel. Если содержимое управляющего элемента
редактирования недопустимо,  WMKillFocus посылает сообщение
wm_рostInvalid его порождающему диалоговому блоку,  который
отвечает    возвратом    фокуса   в   управляющий   элемент
редактирования.

     См. также: TDialog.WMрostInvalid.


 TEditPrintout                                     OPrinter
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TPrintout             TEditPrintout
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і Banding          і  і Editor             і
     іДInitДі  і DC               і  і LineHeight         і
     іДDoneДі  і ForceAllBand     і  і LinesPerPage       і
     і Free і  і Title            і  і NumLines           і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДґ  і StartLines         і
               іДInitДДДДДДДДДДДДДі  і StartPos           і
               іДBeginDocumentДДДДі  і StopLine           і
               і BeginPrinting    і  і StopPos            і
               і EndDocument      і  ГДДДДДДДДДДДДДДДДДДДДґ
               іДGetDialogInfoДДДДі  і Init               і
               іДGetSelectionДДДДДі  і BeginDocument      і
               іДGetNextPageДДДДДДі  і GetDialogInfo      і
               іДPrintPageДДДДДДДДі  і HasNextPage        і
               іДSetPrintParamsДДДі  і PrintPage          і
               АДДДДДДДДДДДДДДДДДДЩ  і SetPrintParams     і
                                     АДДДДДДДДДДДДДДДДДДДДЩ

     TEditPrintout - это объект распечатки, предназначенный
для    печати     содержимого     управляющего     элемента
редактирования.

                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                             Editor

     Editor: PEdit;

     Указывает на    печатаемый     управляющий     элемент
редактирования.

                           LineHeight

     LineHeight: Integer;

     Высота печатаемой  строки.  Вычисляется SetPrintParams
на основе размера текста на устройстве печати.

                          LinesPerPage

     LinesPerPage: Integer;

     Число текстовых   строк,   печатаемых   на   странице.
Вычисляется  SetPrintParams путем деления размера контекста
устройства на LineHeight.

                            NumLines

     NumLines: Integer;

     Устанавливается SetPrintParams в число строк текста  в
управляющем элементе редактирования.

                            StartLine

     StartLine: Integer;

     GebinDocument: Integer;

     BeginDocument устанавливает   StartLine  в  0  (первая
строка  текста).  Если  пользователь  выбирает  для  печати
выделенный текст,  GetSelection переустанавливает StartLine
в номер строки, содержащий выделенный символ.

                            StartPos

     StartPos: Integer;

     Если печатается выделенный  текст,  указывает  позицию
первого  выделенного символа в тексте управляющего элемента
редактирования. В противном случае это 0.

                            StopLine

     StopLine: Integer;

     BeginDocument устанавливает StopLine в NumLines  -  1,
что  означает  последнюю  строку текста.  Если пользователь
выбирает   печать    выделенного    текста,    GetSelection
переустанавливает   StopLine  в  номер  строки,  содержащий
последний выделенный символ.

                             StopPos

     StopPos: Integer;

     Если печатается выделенный  текст,  указывает  позицию
последнего   выделенного   символа  в  тексте  управляющего
элемента редактирования. В противном случае это 32767.

                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AEditor: PEdit; ATitle: PChar);

     Строит объект  управляющего  элемента  редактирования,
вызывая сначала конструктор Init, наследуемый из TPrintout.
Затем устанавливает Editor в AEditor и  инициализирует  все
остальные поля значением 0.

     См. также: TPrintout.Init.


                          BeginDocument
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure BeginDocument(StartPage, EndPage: Integer;
                             Flags: Word); virtual;

     Проверяет бит pf_Selection в поле Flags и  определяет,
хочет  ли  пользователь  печатать выделенный текст или весь
редактируемый текст.  Если печатать нужно только выделенный
текст,  BeginDocument ничего не делает,  оставляя значения,
установленные GetSelection.  В противном случае StartLine и
StartPos устанавливаются в 0,  StopLine - в NumLines - 1, а
StopPos - в 32767.


                          GetDialogInfo
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetDialogInfo(var Pages: Integer): Boolean;
                            virtual;

     Устанавливает StartPos   и   StopPos   в  начальную  и
конечную    позиции     выделенного     текста,     вызывая
Editor^.GetSelection.  Если  StartPos и StopPos равны,  что
означает  отсутствие   выделенного   текста,   GetSelection
возвращает   False.   В   противном   случае   GetSelection
устанавливает  StartLine  и   StopLine   в   число   строк,
содержащих   StartPos   и   StopPos  соответственно,  затем
устанавливает  Start  в  1,  а  Stop  -  в  число  страниц,
необходимых для печати выделенных строк текста,  после чего
возвращает значение True.


                           HasHextPage
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function HasNextPage: Boolean; virtual;

     Всегда возвращает True.  Поскольку  объект  распечатки
элемента  редактирования  может вычислить,  сколько страниц
требуется   для   печати   текста   управляющего   элемента
редактирования,  он  не полагается на значение HasNextPage,
указывающее, что печать закончена.


                            PrintPage
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure PrintPage(Page: Word; var Rect: TRect;
                         Flags: Word); virtual;

     Для каждой  строки  на странице PrintPage берет строку
текста из  Editor  и  посылает  ее  в  контекст  устройства
печати,  используя  TextOut.  Если  текущая строка является
первой или последней строкой выделенного текста,  PrintPage
перед вызовом TextOut отделяет невыделенные части строки.


                          SetPrintParams
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetPrintParams(ADC:   HDC;  ASize:  TPoint);
virtual;

     Устанавливает контекст устройства объекта распечатки и
печатает область заданного размера,  вызывая наследуемый из
TPrintout метод  SetPrintParams,  а  затем  получает  число
строк   в  Editor,  вызывая  метод  GetNumLines.  Вычисляет
LineHeight  и  LinesPerPage  на  основе  размера  текста  в
контексте устройства, переданного в ADC.

     См. также: TPrintout.SetPrintParams.

TEditWindow                                 модуль OStdWnds
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TWindow                TEditWindow
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  і Editor          і
     і DefaultProc       і  і SearchRec       і
     і Scrol[ler         і  ГДДДДДДДДДДДДДДДДДґ
     і FocusChildHandle  і  і Init            і
     ГДДДДДДДДДДДДДДДДДДДґ  і Load            і
     іДInitДДДДДДДДДДДДДДі  і CMEditFind      і
     і InitResource      і  і CMEditFindNext  і
     іДLoadДДДДДДДДДДДДДДі  і CMEditReplace   і
     і Done              і  і Store           і
     і Create            і  і WMSize          і
     і DefWndProc        і  і WMSetFocus      і
     і FocusChild        і  АДДДДДДДДДДДДДДДДДЩ
     і GetId             і
     і GetWindowClass    і
     і Paint             і
     і SetCaption        і
     і SetupWindow       і
     іДStoreДДДДДДДДДДДДДі
     і UpdateFocusChild  і
     і WMActivate        і
     і WMHScroll         і
     і WMLButtonDown     і
     і WMMDIActivate     і
     і WMMove            і
     і WMPaint           і
     іДWMSizeДДДДДДДДДДДДі
     і WMSysCommand      і
     і WMVScroll         і
     АДДДДДДДДДДДДДДДДДДДЩ

     Окно редактирования  -  это окно,  вся область клиента
которого заполнена  управляющим  элементом  редактирования.
Подробнее  о  полях  и  методах  типа TEditWindow вы можете
узнать из оперативного справочника Help.

TEmsStream                                   модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject    TStream               TEmsStream
     ЪДДДДДДї   ЪДДДДДДДДДДДДДДДДДї   ЪДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ   і Status          і   і Handle          і
     іДInitДі   і ErrorInfo       і   і PageCount       і
     іДDoneДі   ГДДДДДДДДДДДДДДДДДґ   і Position        і
     і Free і   і CopyFrom        і   і Size            і
     АДДДДДДЩ   і Error           і   ГДДДДДДДДДДДДДДДДДґ
                і Flush           і   і Init            і
                і Get             і   і Done            і
                іДGetPosДДДДДДДДДДі   і GetPos          і
                іДGetSizeДДДДДДДДДі   і GetSize         і
                і Put             і   і Read            і
                іДReadДДДДДДДДДДДДі   і Seek            і
                і StrRead         і   і Truncate        і
                і StrWrite        і   і Write           і
                іДTruncateДДДДДДДДі   АДДДДДДДДДДДДДДДДДЩ
                і WriteStr        і
                АДДДДДДДДДДДДДДДДДЩ

     TEmsStream -  это  специализированный  производный  от
TStream  тип  для  реализации  потоков  в  памяти  EMS.  Он
предусматривает  дополнительные  поля  для  описателя  EMS,
счетчика    страниц    и    текущей   позиции.   TEmsStream
переопределяет  6  абстрактных  методов  TStream,  а  также
обеспечивает специализированный конструктор и деструктор.

     При отладке   программы,   использующей   потоки  EMS,
интегрированная   интерактивная   среда   IDE   не    может
восстановить  выделенную  вашей программе память EMS,  если
программа преждевременно прекратила работу,  или вы  забыли
вызвать   для   потока   EMS  деструктор  Done.  Освободить
принадлежащие потоку страницы EMS может только  метод  Done
(или перезагрузка).

                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                     Handle (только чтение)

     Handle: Word;

     Описатель EMS для потока.

                    PageCount (только чтение)

     PageCount: Word;

     Число выделенных для потока страниц (16К на страницу).

                    Position (только чтение)

     Position: Longint;

     Текущая позиция в потоке. Первая позиция - это 0.

                      Size (только чтение)

     Size: Longint;

     Размер потока в байтах.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(MinSize, MaxSize: Longint);

     Создает поток    EMS    с   заданным   минимальным   и
максимальным  размером  в  байтах.  Вызывает  TStream.Init,
затем   устанавливает   Handle,   Size  и  PageCount.  Если
инициализация  завершается  неудачно,  вызывает   Error   с
аргументом stInitError.

     См. также: TEmsStream.Done.


                Done (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done; virtual;

     Уничтожает поток   EMS   и   освобождает  используемые
страницы EMS.

     См. также: TEmsStream.Init.


               GetPos (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetPos: Longint; virtual;

     Возвращает значение текущей позиции в потоке.

     См. также: TEmsStream.Seek.


              GetSize (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetSize: Longint; virtual;

     Возвращает общий размер потока.


                Read (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Read(var Buf; Count: Word); virtual;

     Считывает Count байт в буфер Buf,  начиная  с  текущей
позиции потока.

     См. также: TEmsStream.Write, stReadError.


                Seek (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Seek(Pos: Longint); virtual;

     Переустанавливает текущую позицию в Pos байт от начала
потока.

     См. также: TEmsStream.GetPos, TEmsStream.GetSize.


              Truncate (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Truncate; virtual;

     Удаляет все данные из потока  от  текущей  позиции  до
конца.   Текущая  позиция  устанавливается  в  новый  конец
потока.

     См. также: TEmsStream.GetPos, TEmsStream.Seek.


               Write (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Write(var Buf; Count: Word); virtual;

     Записывает Count байт из буфера  в  поток,  начиная  с
текущей позиции.

     См. также:       TStream.Read,      TEmsStream.GetPos,
TEmsStream.Seek.


Константы tf_XXXX                           модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: Константы  флага,  начинающиеся   с   tf_,
использует метод Transfer.

     Значения: Определены следующие константы:

            Константы функции Transfer       Таблица 21.25
ДДДДДДДДДДДВДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
Константы  і Значение і              Смысл               і
ДДДДДДДДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
tf_SizeDataі    0     і Определяет размер переданных объ-і
           і          і ектом данных.                    і
           і          і                                  і
tf_GetData і    1     і Считывает данные из объекта.     і
           і          і                                  і
tf_SetData і    2     і Передает   данные  для  установкиі
           і          і значения объекта.                і
           і          і                                  і
ДДДДДДДДДДДБДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


TFileDialog                                 модуль OStdDlgs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TDialog                TFileDialog
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  і Caption         і
     і IsModal           і  і Extension       і
     ГДДДДДДДДДДДДДДДДДДДґ  і FilePath        і
     іДInitДДДДДДДДДДДДДДі  і FileSpec        і
     і Load              і  і PathName        і
     і Done              і  ГДДДДДДДДДДДДДДДДДґ
     і Create            і  і Init            і
     і DefWndProc        і  і CanClose        і
     і EndDlg            і  і HandleDList     і
     і Execute           і  і HandleFList     і
     і GetItemHandle     і  і HandleFName     і
     і Ok                і  і SetupWindow     і
     і SendDlgItemMsg    і  АДДДДДДДДДДДДДДДДДЩ
     і Store             і
     і WMClose           і
     і WMInitDialog      і
     і WMPostInvalid     і
     і WMQueryEndSession і
     АДДДДДДДДДДДДДДДДДДДЩ

     Файловые диалоговые   блоки   позволяют   пользователю
выбрать  файл  для  открытия  или  указать  имя  файла  для
сохранения.

                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                             Caption

     Caption: PChar;

     Указывает на  строку,  которая  выводится  в заголовке
диалогового блока.  Если Caption  имеет  значение  nil,  то
используется текст из диалогового ресурса. Присвоив Caption
другую строку, вы можете изменить заголовок.

                            Extension

     Extension: array[0..fsExtension] of Char;

     Содержит расширение  для  файлов.  Если   пользователь
набирает  имя файла без расширения,  то файловый диалоговый
блок добавляет к имени Extension.

                            FilePath

     FilePath: PChar;

     Будучи установленным   в   значение,   переданное    в
конструкторе,  FilePath  указывает на буфер,  который будет
содержать выбранное пользователем  имя  маршрута.  Файловый
диалоговый блок помещает в буфер итоговое имя файла.

                            FileSpec

     FileSpec: array[0..fsFileSpec] of Char;

     Содержит спецификацию файла (обычно имя с трафаретными
символами), которое файловый диалоговый блок присоединяет к
текущему выбранному маршруту.

                            PathName

     PathName: array[0..fsPathName] of Char;

     Содержит текущий выбранный маршрут каталога.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AParant: PWindowsObject; AName,
                      AFilePath: PChar);

     Строит файловый  диалоговый  блок  с порождающим окном
AParent  из  диалогового   ресурса.   Ресурс   определяется
значением,   переданным  в  AName.  Параметр  AName  должен
содержать  одну  из  констант  sd_XXXX,   sd_FileOpen   или
sd_FileSave   и   для  определения  характера  создаваемого
файлового  блока  (диалоговый  блок  открытия   файла   или
диалоговый блок сохранения файла) с помощью MakeIntResource
нужно привести его тип к PChar.  На основе AName и значения
в BWCCClassName Init определяет,  какой ресурс нужно задать
для   конструктора   Init,   наследуемого    из    TDialog.
Устанавливает  Caption  в  nil,  а  FilePath - в AFilePath.
AFilePath должно указывать на буфер  размера,  достаточного
для     размещения     полного    имени    файла,    обычно
array[0..fsPathName] of Char.


                             CanClose
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function CanClose: Boolean; virtual;

     Возвращает True,  если пользователь выбрал  файл,  что
позволяет закрыть диалоговый блок.  Если текущий выделенный
маршрут  является  каталогом   или   содержит   трафаретные
символы, CanClose обновляет блоки списка файла и каталога и
возвращает False,  указывая,  что диалоговый блок закрывать
не следует.


                           SetupWindow
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetupWindow; virtual;

     Ограничивает число  символов  в  имени файла значением
fsPathName.  Если  Caption  не   равно   0,   устанавливает
заголовок диалогового блока в Caption.  копирует FilePath в
PathName,  а расширение PathName - в  Extension.  Обновляет
блоки списка для соответствия текущему имени файла.



                           HandleFName
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure HandleFName(var Msg: TMessage); virtual
                           id_First + id_FName;

     Реагирует на    изменения   в   управляющем   элементе
редактирования FileName,  разрешая или  запрещая  командную
кнопку Ok. В противном случае разрешает Ok.


                           HandleFList
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure HandleFList(var Msg: TMessage); virtual;
                           id_First + id_FList;

     Отвечает на уведомляющее  сообщение  от  блока  списка
файлов  обновлением  текущего  имени  файла  и реагирует на
двойной щелчок "мышью" на имени  файла.  Если  пользователь
дважды  щелкнул  кнопкой  "мыши",  вызывает  для завершения
диалогового блока Ok. Если блок списка потерял фокус ввода,
HandleFList отменяет выбор выделенных элементов.


                           HandleDList
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure HandleDList(var Msg: TMessage); virtual
                           id_First + id_DList;

     Реагирует на  уведомляющие  сообщения   блока   списка
каталогов,  обновляя текущее имя файла, и на двойной щелчок
на каталоге кнопкой "мыши".  Если блок списка потерял фокус
ввода, HandleFList отменяет выбор выделенных элементов.


TFileWindow                                        OStdWnds
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TWindow                TEditWindow
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  і Editor          і
     і DefaultProc       і  і SearchRec       і
     і Scrol[ler         і  ГДДДДДДДДДДДДДДДДДґ
     і FocusChildHandle  і  іДInitДДДДДДДДДДДДі
     ГДДДДДДДДДДДДДДДДДДДґ  іДLoadДДДДДДДДДДДДі
     іДInitДДДДДДДДДДДДДДі  і CMEditFind      і
     і InitResource      і  і CMEditFindNext  і
     іДLoadДДДДДДДДДДДДДДі  і CMEditReplace   і
     і Done              і  іДStoreДДДДДДДДДДДі
     і Create            і  і WMSize          і
     і DefWndProc        і  і WMSetFocus      і
     і FocusChild        і  АДДДДДДДДДДДДДДДДДЩ
     і GetId             і
     і GetWindowClass    і  TFileWindow
     і Paint             і  ЪДДДДДДДДДДДДДДДДДї
     і SetCaption        і  і FileName        і
     і SetupWindow       і  і IsNewFile       і
     іДStoreДДДДДДДДДДДДДі  ГДДДДДДДДДДДДДДДДДґ
     і UpdateFocusChild  і  і Init            і
     і WMActivate        і  і Load            і
     і WMHScroll         і  і CanClear        і
     і WMLButtonDown     і  і CanClose        і
     і WMMDIActivate     і  і CMFileNew       і
     і WMMove            і  і CMFileOpen      і
     і WMPaint           і  і CMFileSave      і
     іДWMSizeДДДДДДДДДДДДі  і CMFileSaveAs    і
     і WMSysCommand      і  і NewFile         і
     і WMVScroll         і  і Open            і
     АДДДДДДДДДДДДДДДДДДДЩ  і Read            і
                            і ReplaceWith     і
                            і Save            і
                            і SetFileName     і
                            і SetupWindow     і
                            і Store           і
                            і Write           і
                            АДДДДДДДДДДДДДДДДДЩ

     Файловое окно    -    это   окно   редактирования   со
специализированными   методами   для   чтения   и    записи
редактируемого текста в файл. Подробности о полях и методах
TFileWindow вы  можете  узнать  в  оперативном  справочнике
Help.



TFilterValidator                            модуль Validate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TValidator           TFileWindow
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і Options         і  і ValidChars      і
     іДInitДі  і Status          і  ГДДДДДДДДДДДДДДДДДґ
     іДDoneДі  ГДДДДДДДДДДДДДДДДДґ  і Init            і
     і Free і  іДInitДДДДДДДДДДДДі  і Load            і
     АДДДДДДЩ  іДLoadДДДДДДДДДДДДі  і Error           і
               іДIsInvalidДДДДДДДі  і IsValid         і
               іДIsValidInputДДДДі  і IsValidInput    і
               іДStoreДДДДДДДДДДДі  АДДДДДДДДДДДДДДДДДЩ
               і Transfer        і
               і Valid           і
               АДДДДДДДДДДДДДДДДДЩ

     Объекты фильтрации и проверки  допустимости  проверяют
информацию,   набираемую   пользователем   в  полях  ввода.
Механизм проверки допустимости  содержит  набор  допустимых
символов.  Если  пользователь  набирает один из разрешенных
символов,  то фильтр проверки допустимости  указывает,  что
символ  допустим.  Если  пользователь  набрал  любой другой
символ,  механизм проверки допустимости указывает, что ввод
недопустим.


                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                           ValidChars

     ValidChars: TCharSet;

     Содержит набор  всех символов,  которые может набирать
пользователь.  Например,  чтобы разрешить ввод только цифр,
установите     ValidChars    в    ['0'..'9'].    ValidChars
устанавливается    параметром    AValidChars,    переданным
конструктору Init.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.

                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AValidChars: TCharSet);

     Строит объект   фильтрации  и  проверки  допустимости,
вызывая сначала наследуемый из TValidator конструктор Init,
а затем устанавливая ValidChars в AValidChars.


                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и   загружает   объект  фильтрации  и  проверки
допустимости из потока S,  вызывая сначала  наследуемый  из
TValidator   конструктор   Load,  а  затем  считывая  набор
допустимых символов в ValidChars.

     См. также: TVAlidator.Load.


                              Error
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Error; virtual;

     Выводит блок  сообщений,  указывающий,  что  текстовая
строка содержит недопустимый символ.


                             IsValid
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function IsValid(const S: string): Boolean; virtual;

     Возвращает значение True,  если все символы в строке S
содержатся в множестве допустимых  символов  ValidChars.  В
противном случае возвращает False.


                           IsValidInput
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function IsValid(const    S:   string;   SuppressFill:
                      Boolean): Boolean; virtual;

     Проверяет каждый символ в строке S на принадлежность к
множеству допустимых символов ValidChars.  Возвращает True,
если все символы в строке S допустимы.  В противном  случае
возвращается значение False.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Store(var S: TStream);

     Сохраняет объект  фильтрации и проверки допустимости в
потоке S, записывая ValidChars.


TGroupBox                                          ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TWindow                TControl
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  ГДДДДДДДДДДДДДДДДДґ
     і DefaultProc       і  іДInitДДДДДДДДДДДДі
     і Scrol[ler         і  іДInitResourceДДДДі
     і FocusChildHandle  і  іДGetClassNameДДДДі
     ГДДДДДДДДДДДДДДДДДДДґ  і Register        і
     іДInitДДДДДДДДДДДДДДі  і WMPaint         і
     і InitResource      і  АДДДДДДДДДДДДДДДДДЩ
     іДLoadДДДДДДДДДДДДДДі
     і Done              і  TGroupBox
     і Create            і  ЪДДДДДДДДДДДДДДДДДї
     і DefWndProc        і  і NotifyParent    і
     і FocusChild        і  ГДДДДДДДДДДДДДДДДДґ
     і GetId             і  і Init            і
     і GetWindowClass    і  і InitResource    і
     і Paint             і  і Load            і
     і SetCaption        і  і GetClassName    і
     і SetupWindow       і  і SelectionChangedі
     іДStoreДДДДДДДДДДДДДі  і Store           і
     і UpdateFocusChild  і  АДДДДДДДДДДДДДДДДДЩ
     і WMActivate        і
     і WMHScroll         і
     і WMLButtonDown     і
     і WMMDIActivate     і
     і WMMove            і
     і WMPaint           і
     іДWMSizeДДДДДДДДДДДДі
     і WMSysCommand      і
     і WMVScroll         і
     АДДДДДДДДДДДДДДДДДДДЩ

     Объект TGroupBox     -    это    объект    интеpфейса,
пpедставляющий  соответствующий   элемент,   называемый   в
Windows гpупповым блоком. Хотя групповые блоки не играют на
экране активной  роли,  они  визуально  унифицируют  группу
блоков выбора (кнопок с зависимой и независимой фиксацией).
Однако "закулисно" они  играют  важную  роль  в  управлении
состоянием   своих   блоков  выбора.  Например,  вы  можете
отреагировать на выбор пользователем одной  кнопки  отменой
выбора всех остальных.

                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                           NotifyParent

     NotifyParent: Boolean;

     Флаг, указывающий,  должен ли уведомляться предок  пpи
изменении  состояния  блоков  выбоpа  гpуппового блока.  По
умолчанию имеет значение True.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                  Init (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AParent:     PWindowsObject;    AnID:
                      Integer;  AText:  PChar;  X, Y, W, H:
                      Integer);

     Создает объект    гpуппового    блока   с   пеpеданным
порождающим окном (AParent),  идентификатоpом  управляющего
элемента (AnId),  соответствующим текстом (AText), позицией
(X,Y)    относительно    начала    области     пользователя
pодительского  окна,  шиpиной  (W) и высотой (H).  Вызывает
конструктор TControl.Init  с  аналогичными  параметрами,  а
затем  добавляет  стиль  Windows Attr.Style и удаляет стиль
ws_TabStop   из   поля   Attr.Style    группового    блока.
NotifyParent устанавливается в значение True.  По умолчанию
предок  гpуппового   блока   уведомляется   пpи   изменении
состояния блоков выбоpа.

     См. также: TControl.Init.


                           InitResource
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor InitResource(AParent: PWindowsObject;
                              ResourceID: Word);

     Связывает объект  группового   блока   с   управляющим
элементом   в   ресурсе,  заданном  параметром  ResourceID,
вызывая конструктор InitResource,  наследуемый из TControl.
Для  исключения  группового  блока  из  механизма  передачи
вызывает DisableTransfer  (поскольку  данных  для  передачи
нет).


                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и загружает групповой блок из потока S, вызывая
сначала TConstrol.Load,  а  затем  считывая  дополнительное
поле (NotifyParent), введенное в TGroupBox.

     См. также: TControl.Load.


              GetClassName (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetClassName: PChar; virtual;

     Возвpащает имя   класса   окна   объекта  TGroupBox  -
'Button'.


            SelectionChanged (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SelectionChanged(ControlD:         Integer);
virtual;

     Если NotifyParent   имеет  значение  True,  уведомляет
порождающее окно гpуппового  блока,  что  один  из  выбоpов
изменился,  посылая ему сообщение, базиpующееся на дочеpнем
идентификатоpе.  Этот  метод  можно  пеpеопpеделить,  чтобы
гpупповой блок мог pеагиpовать на его выбоpы.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Stroe(var S: TStream);

     Записывает групповой  блок в поток S,  вызывая сначала
TControl.Store,  а  затем  записывая  дополнительное   поле
(NotifyParent), введенное в TGroupBox.

     См. также: TControlStore.


TInputDialog                                модуль OStdDlgs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TDialog                TInputDialog
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  і Caption         і
     і IsModal           і  і Prompt          і
     ГДДДДДДДДДДДДДДДДДДДґ  і Buffer          і
     іДInitДДДДДДДДДДДДДДі  і BufferSize      і
     і Load              і  ГДДДДДДДДДДДДДДДДДґ
     і Done              і  і Init            і
     і Create            і  і CanClose        і
     і DefWndProc        і  і SetupWindow     і
     і EndDlg            і  АДДДДДДДДДДДДДДДДДЩ
     і Execute           і
     і GetItemHandle     і
     і Ok                і
     і SendDlgItemMsg    і
     і Store             і
     і WMClose           і
     і WMInitDialog      і
     і WMPostInvalid     і
     і WMQueryEndSession і
     АДДДДДДДДДДДДДДДДДДДЩ

     Объект TInputDialog обеспечивает общее диалоговое окно
для  получения  текстового  ввода  от  пользователя  (одной
строки текста).

                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                             Buffer

     Buffer: PChar;

     Указывает на   буфер,   возвращающий   текстовый  ввод
пользователя.  При передаче конструктору  диалогового  окна
ввода  содержит  используемый  по умолчанию текст,  который
первоначально   выводится   в   редактируемом   управляющем
элементе.

                           BufferSize

     BufferSize: Word;

     Содержит размер   буфера,   который   возвращает  ввод
пользователя.

                             Caption

     Caption: PChar;

     Указывает на  строку,  которая  выводится  в  качестве
заголовка диалогового окна.

                             Prompt

     Prompt: PChar;

     Указывает на подсказку диалогового окна ввода, которая
выводится над строкой ввода.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AParent:   PWindowsObject;  ACaption,
           APrompt, ABuffer: PChar; ABufferSize: Word);

     Строит файловый диалоговый блок с  порождающим  окном,
переданным  в  параметре  AParent,  вызывая  наследуемый от
TDialog конструктор Init.  Имя шаблона ресурса определяется
поиском  в BWCCClassName.  Если приложение использует BWCC,
диалоговый блок ввода будет  использовать  ресурс  BWCC.  В
противном   случае  используется  обычный  диалоговый  блок
Windows.

     См. также: TDialog.Init.


                             CanClose
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function CanClose: Boolean; virtual;

     Считывает в  буфер  Buffer  из  управляющего  элемента
редактирования  диалогового  блока  до BufferSize символов,
затем возвращает True,  указывая, что диалоговый блок можно
закрыть.



                           SetupWindow
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetupWindow; virtual;

     При установке   окна   вызывает   метод   SetupWindow,
наследуемый   из  TDialog,  затем  устанавливает  заголовок
диалогового блока в соответствие со строкой Caption.  Текст
подсказки устанавливает в Prompt,  текст буфера - в Buffer,
а затем ограничивает число вводимых пользователем  символов
значением BufferSize - 1.


Тип TItemList                                модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание:

     TItemList = array[0..MaxCollectionSize - 1] of Pointer;

     Назначение: Массив  общих указателей,  предназначенных
для внутреннего использования в TCollection.


TListBox                                    модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TWindow                TControl
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  ГДДДДДДДДДДДДДДДДДґ
     і DefaultProc       і  іДInitДДДДДДДДДДДДі
     і Scrol[ler         і  і InitResource    і
     і FocusChildHandle  і  іДGetClassNameДДДДі
     ГДДДДДДДДДДДДДДДДДДДґ  і Register        і
     іДInitДДДДДДДДДДДДДДі  і WMPaint         і
     і InitResource      і  АДДДДДДДДДДДДДДДДДЩ
     іДLoadДДДДДДДДДДДДДДі
     і Done              і  TListBox
     і Create            і  ЪДДДДДДДДДДДДДДДДДї
     і DefWndProc        і  ГДДДДДДДДДДДДДДДДДґ
     і FocusChild        і  і Init            і
     і GetId             і  і AddString       і
     і GetWindowClass    і  і ClearList       і
     і Paint             і  і DeleteString    і
     і SetCaption        і  і GetClassName    і
     і SetupWindow       і  і GetCount        і
     іДStoreДДДДДДДДДДДДДі  і GetMsgID        і
     і UpdateFocusChild  і  і GetSelIndex     і
     і WMActivate        і  і GetSelString    і
     і WMHScroll         і  і GetString       і
     і WMLButtonDown     і  і GetStringLen    і
     і WMMDIActivate     і  і InsertSrtring   і
     і WMMove            і  і SetSelIndex     і
     і WMPaint           і  і SetSelString    і
     іДWMSizeДДДДДДДДДДДДі  і Transfer        і
     і WMSysCommand      і  АДДДДДДДДДДДДДДДДДЩ
     і WMVScroll         і
     АДДДДДДДДДДДДДДДДДДДЩ

     Объект TListBox     -     это    объект    интеpфейса,
пpедставляющий  соответствующий   элемент,   называемый   в
Windows блоком cписка.  Классы TListBox обычно используются
в качестве экземпляров своих потомков TComboBox.

                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AParent:    PWindowsObject;     AnId:
                      Integer; X, Y, W, H: Integer);

     Создает объект  блока  списка с пеpеданным порождающим
окном  (AParent),   упpавляющим   идентификатоpом   (AnId),
позицией  (X,Y)  относительно  начала  области пользователя
порождающего окна,  шиpиной (W)  и  высотой  (H).  Вызывает
TControl.Init  и  добавляет к полю Attr.Style объекта блока
списка константу lbs_Standard,  дающую полосу пpокpутки  со
следующими элементами:

     - гpаницей (ws_Border);

     - веpтикальной полосой пpокpутки (ws_VScroll);

     - автоматической  соpтиpовкой  по  алфавиту  элементов
       списка (lbs_Sort);

     - уведомлением   порождающего    окна    пpи    выбоpе
(lbs_Notify).

     В наследующих   объектах   или   в  конструкторе  Init
порождающего оконного объекта блока списка эти стили  могут
переопределяться.


               AddString (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function AddString(AString: PChar): Integer; virtual;

     Добавляет AString  (как элемент списка) в объект блока
списка и возвpащает индекс позиции элемента (начинающийся с
нуля) или отpицательное значение в случае ошибки.  Элементы
списка автоматически соpтиpуются,  если только до  создания
из поля Attr.Style объекта блока списка не был удален стиль
lbs_Sort.


               ClearList (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure ClearList; virtual;

     Удаляет из блока списка все элементы списка.


              DeleteString (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function DeleteString(Index:    Integer):     Integer;
virtual;

     Удаляет элемент     списка    с    индексом    позиции
(начинающимся с нуля),  пеpеданным  в  Index.  DeleteString
возвpащает число оставшихся элементов списка или,  в случае
ошибки, отpицательное значение.


              GetClassName (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetClassName: Integer; virtual;

     Возвpащает имя класса окна TListBox - 'ListBox'.


              GetCount (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetCount: Integer; virtual;

     Возвращает число  элементов   в   блоке   списка   или
отрицательное значение в случае ошибки.


                             GetMsgID
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetMsgID(AMsg: TMsgName): Word; virtual;

     Транслирует сообщения блока списка для использования в
TComboBox.


               GetSelIndex (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetSelIndex: Integer; virtual;

     Возвpащает индекс  позиции   (начинающийся   с   нуля)
выделенного   в   данный   момент   элемента   списка   или
отpицательное значение, если выделенного элемента нет.


              GetSelString (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetSelString(AString: PChar; Index: Integer):
                           Integer; virtual;

     Удаляет текущий  выделенный  элемент списка,  если его
длина не превышает MaxChars,  и возвращает его  в  AString.
Функция GetSelString возвpащает длину стpоки или,  в случае
ошибки, отpицательное значение.


                GetString (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetString(AString: PChar; Index: Integer):
                        Integer; virtual;

     Извлекает элемент  в  позиции  (отсчитывающейся  с 0),
переданной в параметре Index,  и возвращает его в  AString.
Функция GetString возвращает длину строки или отрицательное
значение в случае ошибки.


              GetStringLen (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetStringLen(Index:    Integer):     Integer;
virtual;

     Возвращает длину   строки   элемента  блока  списка  в
позиции,  заданной параметром  Index,  и  возвpащает  длину
стpоки или отpицательное значение в случае ошибки.


              InsertString (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function InsertString(AString: PChar; Index: Integer)
                           Integer; virtual;

     Вставляет строку   AString   в    позиции,    заданной
параметром Index, и возвращает фактическую позицию элемента
(которая отсчитывается с  0)  в  списке.  В  случае  ошибки
возвращается отрицательное значение.  Пересортировка списка
не выполняется.  Если параметр Index имеет значение -1,  то
строка присоединяется к концу списка.


               SetSelIndex (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function SetSelIndex(Index:     Integer):     Integer;
virtual;

     Устанавливает выбоp элемента списка в индексе  позиции
(начинающемся с нуля), пеpеданном в Index. Если Index = -1,
блок списка очищается от любого  выбоpа.  В  случае  ошибки
возвpащается отpицательное число.


              SetSelString (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetSelString(AString:      PChar;     AIndex:
                           Integer): Integer; virtual;

     Устанавливает выбоp    пеpвого    элемента     списка,
совпадающего  с  текстом,  пеpеданным  в  AString,  котоpый
встpечается после индекса позиции (начинающегося  с  нуля),
пеpеданного   в  AIndex.  Функция  SetSelString  возвpащает
индекс позиции вновь выделенного  элемента  или,  в  случае
ошибки, отpицательное значение.


                Transfer (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Transfer(DataPtr:    Pointer;   TransferFlag:
                       Word): Word; virtual;

     Пеpедает элементы и выделения элементов  блока  списка
в/из  буфера  пеpедачи.  Если  TransferFlag  имеет значение
tf_GetData,  данные  блока  списка  передаются  по   адресу
памяти.   В   случае   значения   tf_SetData   блок  списка
загружается  данными   из   памяти.   Предполагается,   что
TransferBuffer  указывает на объект PTListBoxData,  который
используется для блока списка, как буфер передачи.

     Характер записи  может  изменяться  в  зависимости  от
того,  допускает ли блок выделение нескольких строк. Первый
передаваемый элемент всегда представляет собой указатель на
набор   строк,   являющихся   записями  блока  списка.  Для
однострочных блоков списка  этот  указатель  сопровождается
целочисленными  индексом  выделенного элемента.  Для блоков
списка с возможностью выбора нескольких строк за указателем
набора следует указатель на запись TMultiSelRec, содержащую
массив  целых  чисел,  каждая  из  которых   указывает   на
выделенный элемент.

     Типичная запись  передачи  для  блока  списка выглядит
следующим образом:

     type
       TListBoxXferRec = record         { одиночный выбор }
          Strings: PStrCollection;
          Selection: Integer;
       end;

       TMultiListBoxXferRec = record{ множественный выбор }
          Strings: PStrCollection;
          Selection: PMultiSelRec;
       end;

     PMultiSelRec -   это  запись,  определенная  в  модуле
ODialogs.  Запись  должна  выделяться  с  помощью   функции
AllocMultiSel,  а  освобождаться  - с помощью FreeMultiSel.
Указатель nil указывает на отсутствие выбранных элементов.


TLookupValidator                            модуль Validate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TValidator           TFileWindow
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДї
     ГДДДДДДґ  і Options         і  ГДДДДДДДДДДДґ
     іДInitДі  і Status          і  і IsValid   і
     і Done і  ГДДДДДДДДДДДДДДДДДґ  і Lookup    і
     і Free і  і Init            і  АДДДДДДДДДДДЩ
     АДДДДДДЩ  і Load            і
               іДIsInvalidДДДДДДДі
               і IsValidInput    і
               і Store           і
               і Transfer        і
               і Valid           і
               АДДДДДДДДДДДДДДДДДЩ

     Средство проверки допустимости с просмотром сравнивает
набранную   пользователем   строку  со  списком  допустимых
значений.  TLookupValidator - это абстрактный тип  проверки
допустимости,   из  которого  вы  можете  создать  полезные
производные механизмы проверки допустимости  с  просмотром.
При  создании  типа  проверки допустимости с просмотром вам
нужно задать список допустимых элементов  и  переопределить
метод Lookup,  чтобы он возвращал True только в том случае,
если ввод пользователя совпадает с элементами списка. Одним
из  примеров  работающего потомка TLookupValidator является
TStringLookupValidator.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                 IsValid (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function IsValid(const S: string): Boolean; virtual;

     Для поиска  строки  S  в  списке  допустимых элементов
ввода  вызывает  Lookup.  Возвращает  True,   если   Lookup
возвращает True,  что означает,  что Lookup нашла S в своем
списке. В противном случае возвращается False.

     См. также: TLookupValidator.Lookup.


                 Lookup (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ищет строку  S  в  списке   допустимых   элементов   и
возвращает  True,  если  строка  там  найдена.  В противном
случае возвращает значение False.  Функция  Lookup  объекта
TLookupValidator  -  это абстрактный метод,  который всегда
возвращает False.  Наследующие типы проверки допустимости с
просмотром  должны  переопределять Lookup и выполнять поиск
на основе фактического списка допустимых элементов.


TMDIClient                                  модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TWindow                TMDIClient
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  і ClientAttr      і
     і DefaultProc       і  ГДДДДДДДДДДДДДДДДДґ
     і Scrol[ler         і  і Init            і
     і FocusChildHandle  і  і ArrangeIcons    і
     ГДДДДДДДДДДДДДДДДДДДґ  і CascadeChildren і
     іДInitДДДДДДДДДДДДДДі  і GetClassName    і
     і InitResource      і  і Register        і
     іДLoadДДДДДДДДДДДДДДі  і Store           і
     і Done              і  і TitleChildren   і
     і Create            і  і WMPaint         і
     і DefWndProc        і  АДДДДДДДДДДДДДДДДДЩ
     і FocusChild        і
     і GetId             і
     і GetWindowClass    і
     і Paint             і
     і SetCaption        і
     і SetupWindow       і
     іДStoreДДДДДДДДДДДДДі
     і UpdateFocusChild  і
     і WMActivate        і
     і WMHScroll         і
     і WMLButtonDown     і
     і WMMDIActivate     і
     і WMMove            і
     і WMPaint           і
     іДWMSizeДДДДДДДДДДДДі
     і WMSysCommand      і
     і WMVScroll         і
     АДДДДДДДДДДДДДДДДДДДЩ

     Пользовательские окна  интерфейса работы с документами
(MDI),  представляемые   объектом   TDMIClient,   управляют
дочерними  окнами  MDI  приложения  MDI.  Методы TMDIClient
предназначены для работы с дочерними окнами MDI.

     В более  ранних   версиях   ObjectWindows   TMDIClient
наследовал из TControl. В данной версии TMDIClient является
прямым потомком TWindow.

                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                           ClientAttr

     ClientAttr: TClientCreateStruct;

     ClientAttr содержит запись атрибутов окна клиента MDI.
TClientCreateStruct определен следующим образом:

     type
       PClientCreateStruct = ^TClientCreateStruct;
       TClientCreateStruct = record
          hWindowMenu: THandle;
          idFirstChild: Word;
       end;

                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                  Init (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AParent: PMDIWindow);

     Создает объект  пользовательского окна MDI c AParent в
качестве  порождающего  окна.  Вызывает  конструктор  Init,
наследуемый из TWindow,  затем добавляет в Attr.Style стиль
ws_ClipChildren.  Кроме того,  Init удаляет окно клиента из
списка   порожденных  окон  его  предка,  так  что  оно  не
интерпретируется  (как  другие  дочерние  окна)  как  блоки
списка и командные кнопки.

     См. также: TWindow.Init.

                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и загружает  окно  клиента  MDI  из  потока  S,
вызывая    сначала    TControl.Load,   а   затем   считывая
дополнительное поле (CLientAttr), введенное TMDIClient.

     См. также: TControl.Load.


              ArrangeIcons (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure ArrangeIcons; virtual;

     Упорядочивает и минимизирует порожденные  окна  MDI  в
нижней части окна клиента MDI.


             CascadeChildren (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure CascadeChildren; virtual;

     Настраивает размер       и      упорядочивает      все
неминимизированные дочерние окна MDI в  окне  клиента  MDI.
Дочерние  окна могут перекрываться,  хотя заголовок каждого
окна остается видимым.


            GetClassName (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetClassName: PChar; virtual;

     Возвpащает имя  класса  окна  объекта   TDMIClient   -
'MDIClient'.


                             Register
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Register: Boolean; virtual;

     Возвращает True,  поскольку  класс  окна  клиента  MDI
предварительно зарегистрирован в Windows.

     См. также: TWindowsObject.Register.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Store(var S: TStream);

     Сохраняет окно клиента MDI в потоке S, вызывая сначала
TControl.Store,   а  затем  записывая  дополнительное  поле
(ClientAttr), введенное в TMDIClient.

     См. также: TControl.Store.


              TileChildren (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure TileChildren; virtual;

     Настраивает размер      и      упорядочивает       все
безпиктограммные  дочерние  окна  MDI  в  окне клиента MDI.
Порожденные окна будут заполнять область  пользователя  без
перекрытия.


              WMPaint (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMPaint(var Msg: TMessage); virtual
                       wm_First + wm_Paint;

     Для отображения окна (как стандартного класса Windows)
вызывает DefWndProc.


TMDIWindow                                  модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TWindow                TMDIWindow
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДї
     і Attr              і  і ChildMenuPos      і
     і DefaultProc       і  і ClientWnd         і
     і Scrol[ler         і  ГДДДДДДДДДДДДДДДДДДДґ
     і FocusChildHandle  і  і Init              і
     ГДДДДДДДДДДДДДДДДДДДґ  і Load              і
     іДInitДДДДДДДДДДДДДДі  і Done              і
     і InitResource      і  і ArrangeIcons      і
     іДLoadДДДДДДДДДДДДДДі  і CascadeChildren   і
     іДDoneДДДДДДДДДДДДДДі  і CloseChildren     і
     і Create            і  і CMArrangeIcons    і
     іДDefWndProcДДДДДДДДі  і CMCascadeChildren і
     і FocusChild        і  і CMCloseChildren   і
     і GetId             і  і CreateChild       і
     іДGetWindowClassДДДДі  і DefWndProc        і
     і Paint             і  і GetClassName      і
     і SetCaption        і  і GetClient         і
     і SetupWindow       і  і GetWindowClass    і
     іДStoreДДДДДДДДДДДДДі  і GetClient         і
     і UpdateFocusChild  і  і GetWindowClass    і
     і WMActivate        і  і InitChild         і
     і WMHScroll         і  і InitClientWindow  і
     і WMLButtonDown     і  і SetupWindow       і
     і WMMDIActivate     і  і Store             і
     і WMMove            і  і TileChildren      і
     і WMPaint           і  АДДДДДДДДДДДДДДДДДДДЩ
     і WMSize            і
     і WMSysCommand      і
     і WMVScroll         і
     АДДДДДДДДДДДДДДДДДДДЩ

     Пользовательские окна-рамки   интерфейса   работы    с
документами   (MDI),  представляемые  объектом  TDMIWindow,
представляют собой перекрываемые окна, которые используются
в качестве основных окон прикладной программы MDI. Одним из
основных   средств   объекта   TDMIWindow   является    его
собственный  объект  TMDIClient  и  сохранение  его  в поле
ClientWnd.  Другое средство  -  это  меню  дочернего  окна,
предлагающее  возможности  для  работы  с  дочерними окнами
приложения MDI.  Для  отражения  всех  выводимых  на  экран
дочерних окон это окно автоматически получает уведомление.

                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                  ChildMenuPos (чтение/запись)

     ChildMenuPos: Integer;

     ChildMenuPos определяет   индекс,   задающий   позицию
управляющего  меню  дочернего  окна.  В индексе учитываются
только элементы верхнего уровня,  а верхний  левый  элемент
занимает нулевую позицию.

                    ClientWnd (только чтение)

     ClientWnd: PMDIClient;

     ClientWnd указывает  на  обрамляющее окно (окно-рамку)
окна клиента MDI, экземпляр объекта TMDIClient.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                  Init (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(ATitle: PChar; AMenu: HMenu);

     Строит объект   окна-рамки   MDI,  используя  заданный
заголовок ATitle и меню, переданное в AMenu. Окна-рамки MDI
требуют наличия меню. Окна-рамки не имеют порождающего окна
и должны быть основным окном приложения.  По умолчанию Init
устанавливает  ChildMenuPos  в  ноль,  указывая,  что  меню
дочернего  окна  -  это   меню   верхнего   уровня.   Чтобы
модифицировать ChildPos, переопределите в наследующих типах
TMDIWindow.Init, например:

     constructor MyMDIWindow.Init(ATitle:   PChar;   AMenu:
     HMenu);
     begin
        TMDIWindow.Init(ATitle, AMenu);
        ChildMenuPos := 3;
     end;

     См. также: TMDIWindow.InitClientWindow.


                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и загружает окно-рамку MDI из потока S, вызывая
сначала  TWindow.Load,   а   затем   получая   и   считывая
дополнительные поля (ClientWnd и ChildMenuPos), введенные в
TMDIWindow.

     См. также TWindow.Load.


                  Done (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done; virtual;

     Перед вызовом   для   уничтожения   оконного   объекта
окна-рамки  MDI  наследуемого  из  TWindow деструктора Done
уничтожает объект окна клиента MDI, записанный в ClientWnd.

     См. также: TWindow.Done.


              ArrangeIcons (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure ArrangeIcons;

     Упорядочивает порожденные окна MDI с  пиктограммами  в
нижней  части  пользовательского  окна MDI.  Вызывает метод
ClientWnd^.ArrangeIcons.

     См. также: TMDIClient.ArrangeIcons.


             CascadeChildren (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure CascadeChildren;

     Настраивает размер      и      упорядочивает       все
безпиктограммные  (неминимизированные)  дочерние окна MDI в
окне клиента MDI,  так что они  перекрываются  и  выводится
заголовок          каждого          окна.          Вызывает
ClientWnd^.CascadeChildren.

     См. также: TMDIClient.CascadeChildren.


              CloseChildren (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure CloseChildren;

     Завершает все созданные дочерние окна MDI, для которых
CanClose возвращает True.

     См. также: TWindow.CanClose.


             CMArrangeIcons (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure CMArrangeIcons(var Msg: TMessage); virtual
                              cm_First + cm_ArrangeIcons;

     Вызывая ArrangeIcons,  отвечает  на   выбор   меню   с
идентификатором cm_ArrangeIcons.

     См. также: TDMIWindow.ArrangeIcons.


            CMCascadeChildren (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure CMCascadeChildren(var     Msg:    TMessage);
                                 virtual     cm_First     +
                                 cm_CascadeChildren;

     Вызывая CascadeChildren,  отвечает  на  выбор  меню  с
идентификатором cm_CascadeChildren.

     См. также: TDMIWindow.CascadeChildren.


           CMCreateChild (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure CMCreateChild(Msg: TMessage); virtual
                             cm_First + cm_CloseChildren;

     Вызывая CreateChild,   отвечает   на   выбор   меню  с
идентификатором cm_CloseChildren.

     См. также: TDMIWindow.CreateChild.


             CMTileChildren (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure CMTileChildren(var Msg: TMessage); virtual
                              cm_First + cm_TileChildren;

     Вызывая TileChildren,   отвечает   на   выбор  меню  с
идентификатором cm_TileChildren.

     См. также: TDMIWindow.InitChild.


                           CreateChild
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function CreateChild: PTWindowObject; virtual;

     Вызывая InitChild и MakeWindow, строит и создает новое
дочернее  окно  MDI.  Вам нужно переопределить CreateChild,
для  наследующих  дочерних  оконных  типов  MDI  аналогично
TMDIWindow.InitChild.  CreateChild  возвращает указатель на
новое порожденное окно MDI.

     См. также:                       TDMIWindow.InitChild,
TApplication.MakeWindow.


                            DefWndProc
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure DefWndProc(var Msg: TMessage); virtual;

     Переопределяет выполняемую   по  умолчанию  в  TWindow
обработку сообщений Windows,  вызывая вместо  DefWindowProc
функцию Windows DefFrameProc.


              GetClassName (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetClassName: PChar; virtual;

     Возвpащает имя  класса окна Windows объекта TDMIWindow
- 'TurboMDIWindow'.


             GetClient (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function CetClient:  PTMDIClient; virtual;

     Возвращает указатель на окно клиента MDI,  сохраненное
в ClientWnd.


             GetWindowClass (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure GetWindowClass(var   AWndClass:  TWndClass);
virtual;

     Модифицирует используемую по умолчанию  запись  класса
окна  и  передает  ее  обратно в AWndClass.  GetWindowClass
устанавливает поле стиля в 0 и удаляет стили, установленные
TWindow.GetWindowClass.

     См. также: TWindow.GetWindowClass.


                InitChild (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function InitChild: PTWindowsObject; virtual;

     Строит объект   дочернего   окна   MDI   (TWindow)   с
заголовком 'MDI Child' и возвращает указатель на него. Если
вы  определите  тип  дочернего  окна  MDI,  наследующий  из
TWindow,  для  построения  окна  своего  нового   дочернего
оконного   типа  MDI  переопределите  TMDIWindow.InitChild,
например:

     function MyMDIWindow.InitChild: PWindowsObject;
     begin
       InitChild := New(PMyMDIChild, Init(@Self,
                                     'Окно без заголовка');
     end;

     См. также: TDMIWindow.CreateChild.


            InitClientWindow (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure InitClientWindow; virtual;

     Строит окно  клиента   MDI   как   экземпляр   объекта
TMDIClient, сохраняя его в ClientWnd.


               SetupWindow (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetupWindow; virtual;

     Строит окно  клиента  MDI (ClientWnd) соответствующего
оконного  элемента  объекта,  вызывая  InitClientWindow,  и
создает   его  с  помощью  вызова  MakeWindow.  Если  вы  в
наследующем типе переопределите  SetupWindow,  убедитесь  в
наличии явного вызова TDMIWindow.SetupWindow.

     См. также:                TMDIWindow.InitClientWindow,
TApplication.MakeWindow.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Store(var S: TStream);

     Сохраняет окно  MDI  в  потоке  S,   вызывая   сначала
TWindow.Store,  а  затем помещая и записывая дополнительные
поля (ClientWnd и ChildMenuPos), введенные в TMDIWindow.

     См. также: TWindow.Store.


              TileChildren (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure TileChildren;

     Вызывая ClientWnd^.TileChildren,  настраивает размер и
упорядочивает все безпиктограммные дочерние окна MDI в окне
клиента MDI,  так что будет использовано без перекрытия все
доступное пространство.

     См. также: TMDIClient.TileChildren.

Тип TMessage                                модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание:

     TMessage = record
        Reseiver: HWnd;
        Message: Word;
        case Integer of
           0: (WParam: Word;
               LParam: Longint;
               Result: Longint);
           1: (WParamLo: Byte;
               WParamHi: Byte;
               LParamLo: Word;
               LParamHi: Word;
               ResultLo: Word;
               ResultHi: Word);
        end;

     Назначение: Цикл  сообщения в TApplication упаковывает
информацию  сообщения  Windows  в  записи  TMessage   перед
передачей   информации  вместе  с  соответствующим  методом
реакции на сообщение.

     См. также: TApplication.MessageLoop.


Тип TMultiSelRec                            модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание:

     TMultiSelRec = record
          Count: Integer;
          Selections: array[0..0] of Integer;
     end;

     TMultiSelRec содержит  список выделенных элементов для
передачи в блок списка с множественным выбором или из него.
Count  указывает число выделенных элементов,  а Selection -
это   открытый    массив    целых    значений.    Используя
Al[locMultiSel, вы можете распределить запись с достаточным
для используемого блока списка числом выделяемых элементов.

     См. также: AllocMultiSel, FreeMultiSel.


TObject                                      модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

      TObject
      ЪДДДДДДї
      ГДДДДДДґ
      і Init і
      і Done і
      і Free і
      АДДДДДДЩ

     TObject -  это  отправная  точка   иерархии   объектов
ObjectWindows.  Как базовый объект, он не имеет предков, но
имеет много потомков. Все стандартные объекты ObjectWindows
в  конечном  счете являются производными от TObject.  Любой
объект,  использующий  потоковые  средства   ObjectWindows,
должен отслеживать наследование обратно к TObjects.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init;

     Выделяет для  объекта   пространство   в   динамически
распределяемой  области  памяти.  Вызывается конструкторами
всех производных объектов.


                               Free
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Free;

     Уничтожает объект и вызывает деструктор Done.


                               Done
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done; virtual;

     Выполняет необходимую    очистку    и     освобождение
динамических объектов.


Тип TPaintStruct                            модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание:

     TPaintStruct = record
        hdc: HDC;
        fErase: Bool;
        rcPaint: TRect;
        fRestore: Bool;
        fIncUpdate: Bool;
        rgbReserved: array[0..15] of Byte;
     end;

     Назначение: Запись TPaintStruct  содержит  информацию,
используемую  приложением  для отображения областей клиента
окон.   Большая   часть   информации   резервируется    для
внутреннего  использования  в  Windows,  но несколько полей
могут использоваться пользователем.

     Поле hdc - это описатель контекста дисплея, на котором
происходит  отображение.  fErase  указывает,  требуется  ли
повторно отображать фон (отображение  происходит  в  случае
ненулевого значения).  rcPaint определяет прямоугольник,  в
котором происходит отображение.

     Все другие   поля   резервируются   для    внутреннего
использования в Windows.


Тип TPicResult                              модуль Validate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание:

     TPicResult =   (prComplete,   prIncomplete,   prEmpty,
                   prError,     prSyntax,      prAmbiguous,
                   prIncompNoFill);

     Назначение: TPicResult - это тип, возвращаемый методом
Picture объекта TPCPictureValidator.

     См. также: TPCPictureValidator.


TPrintDialog                                модуль OPrinter
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TDialog                TPrintDialog
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  і AllBtn          і
     і IsModal           і  і Colate          і
     ГДДДДДДДДДДДДДДДДДДДґ  і Controls        і
     іДInitДДДДДДДДДДДДДДі  і FromPage        і
     і Load              і  і PageBtn         і
     і Done              і  і Pages           і
     і Create            і  і PData           і
     і DefWndProc        і  і Printer         і
     і EndDlg            і  і PrinterName     і
     і Execute           і  і PrnDC           і
     і GetItemHandle     і  і SelAllowed      і
     і Ok                і  і SelectBtn       і
     і SendDlgItemMsg    і  і ToPage          і
     і Store             і  ГДДДДДДДДДДДДДДДДДґ
     і WMClose           і  і Init            і
     і WMInitDialog      і  і IDSetup         і
     і WMPostInvalid     і  і SetupWindow     і
     і WMQueryEndSession і  і TransferData    і
     АДДДДДДДДДДДДДДДДДДДЩ  АДДДДДДДДДДДДДДДДДЩ

     Диалоговый блок  печати TPrintDialog дает пользователю
возможность настроить конкретное  задание  печати,  выбирая
такие  параметры,  как  число  выводимых на печать страниц,
число копий или используемый принтер.  TPrintDialog  -  это
используемый  по умолчанию диалоговый объект печати,  но вы
можете,   переопределив   метод   InitPrintDialog   объекта
принтера,   включить  свой  собственный  специализированный
диалоговый блок.

                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                             AllBtn

     Al[lBtn: PRadioButton;

     AllBtn -  это  один из трех наборов кнопок с зависимой
фиксацией. При его выборе AllBtn указывает, что на принтере
должны печататься все страницы документа.

     См. также:                     TPrintDialog.SelectBtn,
TPrintDialog.PageBtn.

                             Collate

     Collate: PCheckBox;

     Указывает на  кнопку   с   независимой   фиксацией   в
диалоговом   блоке,  определяющую,  хочет  ли  пользователь
сравнения вывода.

                            Controls

     Controls: PCollection;

     Это поле предназначено для внутреннего использования в
диалоговом блоке печати.

                             Copies

     Copies: PEdit;

     Copies позволяет  пользователю задать число печатаемых
копий документа.

                            FromPage

     FromPage: PEdit;

     Если пользователь выбирает печать  диапазона  страниц,
FromPage содержит номер первой печатаемой страницы.

                             PageBtn

     PageBtn: PRadioButton;

     PageBtn -  это один из трех наборов кнопок с зависимой
фиксацией.  При  его  выборе  пользователь  хочет  печатать
выделенный диапазон страниц.

     См. также: TPrintDialog.AllBtn, TPrintDialog.FromPage,
TPrintDialog.SelectBtn, TPrintDialog.ToPage.

                              Pages

     Pages: Integer;

     Pages - это общее число страниц в документе.

                              PData

     PData: PPrintDialogRec;

     PData указывает  на  тип  TPrintDialogRec.  Диалоговые
блоки печати используют эту запись как буфер передачи.

     См. также: тип TPrintDialogRec.

                             Printer

     Printer: PPrinter;

     Printer указывает  на  объект  принтера,  связанный  с
диалоговым блоком печати.

                           PrinterName

     PrinterName: PStatic;

     Указывает на   статический    текстовый    управляющий
элемент, содержащий имя текущего выбранного принтера.

                              PrnDC

     PrnDC: HDC;

     PrnDC -   это   описатель   используемого  для  печати
контекста устройства.

                           SetAllowed

     SetAllowed: Boolean;

     В случае  значения  True  указывает,  что   устройство
печати   поддерживает   печать  только  выделенного  текста
документа.  SelectBtn разрешается только  когда  SelAllowed
имеет значение True.

     См. также: TPrintDialog.SelectBtn.

                            SelectBtn

     SelectBtn: PRadioButton;

     SelectBtn -   это   один  из  трех  наборов  кнопок  с
зависимой фиксацией.  При  его  выборе  пользователь  хочет
печатать текущий выделенный в документе текст.

     См. также: TPrintDialog.SelAllowed.

                             ToPage

     ToPage: PEdit;

     Если пользователь  выбирает  печать диапазона страниц,
ToPage  содержит  номер  последней  выводимой   на   печать
страницы.

     См. также: TPrintDialog.PageBtn, TPrintDialog.FromPage.

                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AParent:   PWindowsObject;  Template:
                 PChar;  APrnDC:  HDC;   APages:   Integer;
                 APrinter:  PPrinter; ASelAllowed: Boolean;
                 var Data: TPrintDialogRec);

     Строит диалоговый   блок   печати,   вызывая   сначала
конструктор Init,  наследуемый из TDialog,  а затем выбирая
поля в соответствии со  значениями  переданных  параметров.
Затем  Init  строит  управляющие объекты диалогового блока,
вызывая для каждого из них InitResource.

                             IDSetup

     procedure IDSetup(var Msg: TMessage); virtual
                       id_First + id_Setup;

     Отвечает на   нажатие   пользователем   кнопки  Setup,
вызывая диалоговый блок установки  принтера.  По  умолчанию
диалоговый  блок  установки  принтера  является экземпляром
типа TPrinterSetupDialog.

     См. также: объект TPrinterSetupDialog.

                           SetupWindow

     procedure SetupWindow; virtual;

     Инициализирует диалоговый   блок,   вызывая    сначала
наследуемый из TDialog метод SetupWindow,  а затем считывая
имя устройства печати из объекта принтера и устанавливая  в
это значение поле PrinterName.

                          TransferData

     procedure TransferData(Direction: Word); virtual;

     Переопределяет наследуемый   метод   TransferData  для
установки управляющих значение на основе значения в  PData,
если Direction равно tf_SetData или устанавливает на основе
управляющих   значений   PData,   если   Direction    равно
tf_GetData.   TransferData   не  просто  устанавливает  или
считывает управляющие элементы,  как при взаимообмене между
полями  PData  и  управляющими элементами диалогового блока
печати.


Тип TPrintDialogRec                         модуль OPrinter
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание:

     TPrintDialogRec = record
         drStart: Integer;
         drStop: Integer;
         drCopies: Integer;
         drCollate: Boolean;
         drUseSelection: Boolean;
     end;

     Назначение: Диалоговые объекты печати  используют  тип
TPrintDialogRec как буферы передачи.  Поля drStart и drStop
представляют,  соответственно,  первую и последнюю страницы
для  печати.  drCopies  указывает  число  печатаемых копий.
drCollate  сообщает  принтеру  о  сравнении   копий,   если
drCopies вызывается несколько раз.  drUseSelection сообщает
принтеру  о  печати  выделенного  текста,  а   не   текста,
указанного drStart и drStop.


TPrinter                                    модуль OPrinter
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TPrintout
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і Device           і
     іДInitДі  і DeviceMode       і
     іДDoneДі  і DeviceModule     і
     і Free і  і DevSettings      і
     АДДДДДДЩ  і DevSettingSize   і
               і Driver           і
               і Error            і
               і ExtDeviceMode    і
               і Port             і
               і Status           і
               ГДДДДДДДДДДДДДДДДДДґ
               і Init             і
               і Done             і
               і ClearDevice      і
               і Configure        і
               і GetDC            і
               і InitAbortDialog  і
               і InitPrintDialog  і
               і Print            і
               і ReportError      і
               і SertDevice       і
               і Setup            і
               АДДДДДДДДДДДДДДДДДДЩ

     Объект TPrinter   представляет   инкапсуляцию  системы
драйвера принтера Windows. Чтобы напечатать на принтере или
настроить   его   конфигурацию,  инициализируйте  экземпляр
TPrinter.


                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Device

     Device: PChar;

     Указывает на  имя  текущего   устройства.   В   случае
значения   nil   объект   не   связан  в  данный  момент  с
устройством.

                           DeviceMode

     DeviceMode: TDeviceMode;

     Функциональная переменная,  содержащая  адрес  функции
DeviceMode текущего связанного принтера.  Данная переменная
используется  при  вызове  Configure,  если  устройство  не
поддерживает ExtDeviceMode.

                          DeviceModule

     DeviceModule: THandle;

     Описатель текущего драйвера принтера.

                         DeviceSettings

     DeviceSettings: PDevMode;

     Указатель на  локальную копию установленных параметров
устройства   печати    (называемую    также    операционным
окружением).  Используется  только  если текущее устройство
печати поддерживает ExtDeviceMode.

                        DeviceSettingSize

     DeviceSettingSize: Integer;

     Объем памяти, выделенной для DeviceSetings.

                             Driver

     Driver: PChar;

     Указатель на имя текущего драйвера.  В случае значения
nil объект не связан в данный момент с драйвером.

                              Error

     Error: Integer;

     Код ошибки,  возвращаемый GDI при печати. Это значение
инициализируется при вызове Print.

                          ExtDeviceMode

     ExtDeviceMode: TExtDeviceMode;

     Функциональная переменная,  содержащая  адрес  функции
ExtDeviceMode  текущего устройства печати.  Если драйвер не
поддерживает данную подпрограмму,  специфичную для  Windows
3.0,  то  данный  адрес равен nil (то есть @ExtDeviceMode =
nil равно True).  Эта переменная  используется  при  вызове
Configure.

                              Port

     Port: PChar;

     Указатель на имя порта, к которому подсоединен текущий
принтер. В случае значения nil объект не содержит принтера.

                             Status

     Status: Integer;

     Текущее состояние драйвера принтера.

                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init;

     Создает экземпляр TPrinter,  связанный с  используемым
по  умолчанию  принтером.  Чтобы сменить принтер,  TPrinter
после инициализации объекта вызывает SetDevice. Вызов Setup
также  позволяет  пользователю  выбрать  новое устройство в
ходе диалога.


                  Done (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     desctuctor Done; virtual;

     Освобождает ресурсы, выделенные для TPrinter.


                           ClearDevice
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure ClearDevice;

     Отменяет связь   устройства   с   текущим   принтером.
Вызывается  SetDevice  и  Done.  Изменяет текущее состояние
принтера на pf_Unassociated,  что приводит к  игнорированию
объектом  всех  вызовов  Print,  пока объект не будет снова
связан с принтером.


                            Configure
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Confuigure(Window: PWindowsObject);

     Вызывает драйвер устройства для конфигурации  текущего
принтера. Если драйвер принтера поддерживает ExtDeviceMode,
то  сохраняется  локальная  копия  параметров  принтера,  и
значения принтера по умолчанию не изменяются.  Если принтер
поддерживает  только  DeviceMode,  глобальные  значения  по
умолчанию для принтера будут модифицированы.


                  GetDC (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetDC: HDC; virtual;

     Возвращает для текущего связанного с объектом принтера
контекст устройства.  Если объект находится в  недопустимом
состоянии,  или принтер связан с неактивным портом (то есть
с портом "None"), возвращает 0.


             InitAbortDialog (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function InitAbortDialog(Parent: PWindowsObject;
                              Title: PChar):       PDialog;
virtual;

     Вызывается методом  Print  в  начале  печати  задания.
Возвращаемым  результатом  является  созданный  безрежимный
диалоговый  блок.  По  умолчанию   возвращается   экземпляр
TPrinterAbortDlg.  Отмена  этого диалогового блока отменяет
задание печати.

     Может переопределяться          для           возврата
специализированного  диалога,  выводящего  на экран текущую
печать.


             InitPrintDialog (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function InitPrintDialog(Parent:       PWindowsObject;
                   PrnDC:  HDC; Pages: Integer; SetAllowed:
                   Boolean;  var  Data;   TPrintDialogRec):
                   PDialog; virtual;

     Вызывается методом   Print  для  возврата  диалогового
блока, если объект распечатки указывает, что поддерживается
печать выбранных страниц.  Диалоговый блок печати позволяет
пользователю задать печать всех страниц, выделенного текста
или   диапазона   страниц.   По  умолчанию  InitPrintDialog
возвращает экземпляр типа TPrintDialog.


             InitSetupDialog (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function InitSetupDialog(Parent:      PWindowsObject):
                              PDialog; virtual;

     Вызывается методом   Setup  для  возврата  диалогового
блока   установки   принтера.   В   приложении    результат
предполагается   в  виде  режимного  диалогового  окна.  По
умолчанию возвращается  экземпляр  TPrinterSetupDlg.  Может
переопределяться  для  возврата специализированного диалога
установки принтера.


                              Print
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Print(ParentWin: PWindowsObject;
                    PrintOut: PPrintOut): Boolean;

     Переводит указанный  объект  распечатки  на  связанное
устройство печати.  При печати выводит на экран  диалоговое
окно прерывания и обнаруженные ошибки.


              ReportError (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure ReportError(PrintOut: PPrintOut); virtual;

     Print вызывает   ReportError   в   случае  обнаружения
ошибки. По умолчанию выводится блок системного сообщения со
строкой ошибки,  полученной из значений таблицы строк 32512
- 32519.  Чтобы вывести специализированный диалоговый  блок
ошибки, данный метод можно переопределить.


                            SetDevice
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetDevice(ADevice, ADriver, APort: PChar);

     Изменяет связь  с  устройством печати.  Setup вызывает
SetDevice для интерактивного  изменения  связи.  Допустимые
параметры  данного  метода  можно  найти в секции устройств
файла WIN.INI.

     Записи секции устройств имеют следующий формат:

     <имя_устройства>=<драйвер>, <порт> {, <порт>}

где порт может повторяться любое число раз.


TPrinterAbortDlg                            модуль OPrinter
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TDialog                TPrinterAbortDlg
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  ГДДДДДДДДДДДДДДДДДґ
     і IsModal           і  і Init            і
     ГДДДДДДДДДДДДДДДДДДДґ  і SetupWindow     і
     іДInitДДДДДДДДДДДДДДі  і WMCommand       і
     і Load              і  АДДДДДДДДДДДДДДДДДЩ
     і Done              і
     і Create            і
     і DefWndProc        і
     і EndDlg            і
     і Execute           і
     і GetItemHandle     і
     і Ok                і
     і SendDlgItemMsg    і
     і Store             і
     і WMClose           і
     і WMInitDialog      і
     і WMPostInvalid     і
     і WMQueryEndSession і
     АДДДДДДДДДДДДДДДДДДДЩ

     Это объектный    тип    используемого   по   умолчанию
диалогового  окна  прерывания   принтера.   Данный   диалог
инициализируется для вывода заголовка текущей распечатки, а
также устройства и порта,  которые  используются  в  данный
момент для печати.

     Предполагается, что    TPrinterAbortDlg    имеет   три
статических    текстовых     управляющих     элемента     с
идентификаторами   управляющих   элементов:   101   -   для
заголовка,  102  -  для  устройства   и   103   для   порта
соответственно.  В  своих текстовых строках эти управляющие
элементы должны содержать символ '%',  который  заменяется,
соответственно, заголовком, устройством и портом. Позиция и
порядок табуляции управляющих элементов в диалоговом  блоке
важного значения не имеет.

                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AParent:   PWindowsObject;  Template,
                      Title, Device, Port: PChar);

     Строит диалоговый блок прерывания  печати,  в  котором
наряду   с  кнопкой  Cancel  выводятся  заданный  заголовок
(Title), устройство (Device) и порт (Port).


               SetupWindow (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetupWindow; virtual;

     Предназначена для    внутреннего    использования    в
связанных объектах с шаблоном диалогового ресурса,  так что
могут заполняться заголовок, устройство и порт.


                WMCommand (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMCommand(var Msg: TMessage); virtual
                         wm_First + wm_Command;

     Предназначена для  внутренней  работы с кнопкой Cancel
(Отмена).


TPrinterSetupDlg                            модуль OPrinter
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TDialog                TPrinterSetupDlg
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  і Printer         і
     і IsModal           і  ГДДДДДДДДДДДДДДДДДґ
     ГДДДДДДДДДДДДДДДДДДДґ  і Init            і
     іДInitДДДДДДДДДДДДДДі  і Done            і
     і Load              і  і Cancel          і
     і Done              і  і IDSetup         і
     і Create            і  і TransferData    і
     і DefWndProc        і  АДДДДДДДДДДДДДДДДДЩ
     і EndDlg            і
     і Execute           і
     і GetItemHandle     і
     і Ok                і
     і SendDlgItemMsg    і
     і Store             і
     і WMClose           і
     і WMInitDialog      і
     і WMPostInvalid     і
     і WMQueryEndSession і
     АДДДДДДДДДДДДДДДДДДДЩ

     Это используемый    по   умолчанию   диалоговый   блок
установки  принтера.  Он   аналогичен   диалоговому   блоку
установки принтера в IDE для Windows.  Предполагается,  что
TPrinterSetupDlg  имеет  комбинированный  блок  для  списка
допустимых  устройств  и командную кнопку Setup.  Они имеют
идентификаторы 101 и 102  соответственно.  В  него  следует
также включить кнопки OK и Cancel.

                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                             Printer

     Printer: PPrinter;

    Указывает на текущий принтер, модифицируемый в диалоге.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AParent: PWindowsObject;
                      TemplateName: PChar;        APrinter:
PPrinter);

     Строит диалоговый     блок     установки     принтера,
модифицирующий указанный принтер.


                  Done (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done; virtual;

     Освобождает связанные с объектом ресурсы.


               Cancel (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Cancel(var Msg: TMessage); virtual
                      id_First + id_Cancel;

     Предназначается для  внутреннего использования с целью
восстановления   предыдущего   состояния   принтера,   если
пользователь после Setup нажал командную кнопку Cancel.


              IDSetup (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure IDSetup(var Msg: TMessage); virtual
                      id_First + id_Setup;

     Обрабатывает нажатия   кнопки   Setup.    Модифицирует
заданный принтер и вызывает его метод Configure.


            TransferData (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure TransferData(TransferFlag: Word); virtual;

     Предназначается для  внутреннего использования с целью
пересылки данных из диалогового  блока  и  непосредственной
модификации заданного принтера.


TPrintout                                   модуль OPrinter
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject    TPrintout
     ЪДДДДДДї   ЪДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ   і Banding         і
     іДInitДі   і DC              і
     іДDoneДі   і ForceAllBands   і
     і Free і   і Size            і
     АДДДДДДЩ   і Title           і
                ГДДДДДДДДДДДДДДДДДґ
                і Init            і
                і Done            і
                і BeginDocument   і
                і BeginPrinting   і
                і EndDocument     і
                і EndPrinting     і
                і GetDialogInfo   і
                і GetSelection    і
                і HasNextPage     і
                і PrintPage       і
                і SetPrintParams  і
                АДДДДДДДДДДДДДДДДДЩ

     Этот объект  используется  в  сочетании   с   объектом
TPrinter   для   печати   информации  на  принтере.  Данный
объектный тип является абстрактным.  Это означает,  что сам
по  себе  он  не может использоваться для печати каких-либо
данных.  Должны создаваться наследники  TPrinter,  а  метод
PrintPage должен переопределяться для печати нужных данных.


                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                             Banding

     Banding: Boolean;

     В случае   значения   True   распечатка   выводится  с
использование разбиения на  полосы,  и  для  каждой  полосы
вызывается   метод  PrintPage.  В  противном  случае  метод
PrintPage  вызывается  однократно  для   каждой   страницы.
Разбиение  распечатки на полосы более эффективно по времени
и затратам памяти,  чем его отсутствие.  По  умолчанию  это
поле имеет значение False.

                                DC

     DC: HDC;

     DC -  это описатель используемого для печати контекста
устройства.

                          ForceAllBands

     ForceAllBands: Boolean;

     Многие драйверы    устройств    не     предусматривают
многополосной печати на принтере,  если и текст,  и графика
не выполняются с использованием первой полосы  (обычно  это
только   текстовая  полоса).  Если  оставить  в  этом  поле
значение True,  это вынудит драйвер  принтера  использовать
все полосы,  независимо от того, какие вызовы выполняются в
методе PrintPage.  Если PrintPage ничего  не  делает  кроме
вывода текста,  то эффективнее установить это поле в False.
По умолчанию оно равно True. Данное поле действует только в
том случае, если Banding равно True.

                               Size

     Size: TPoint;

     Size представляет  размер  области  печати на странице
распечатки.

                              Title

     Title: PChar;

     Текущий заголовок,  используемый  для  распечатки.  По
умолчанию  этот  заголовок  выводится  в  диалоговом  блоке
прерывания печати и  в  качестве  имени  задания  печати  в
администраторе печати.

                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(ATitle: PChar);

     Строит экземпляр TPrintOut с заданным заголовком.


                               Done
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done; virtual;

     Уничтожает ресурс, выделенный конструктором Init.

                          BeginDocument

     procedure BeginDocument(StartPage, EndPage: Integer;
                             Flag: Word); virtual;

     Метод Print объекта печати вызывает BeginDocument один
раз   перед  печатью  каждой  копии  документа.  Поле  Flag
содержит pf_Banding или pf_Selection и указывает,  будет ли
использоваться  разбиение  на полосы или печать выделенного
текста.

     Используемый по умолчанию метод  BeginDocument  ничего
не делает. Наследующие объекты могут переопределять его для
выполнения в  начале  каждой  копии  документа  необходимой
инициализации.


                          BeginPrinting
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure BeginPrinting; virtual;

     Независимо от  того,  сколько  копий  документа  будет
печататься,   метод   Print   объекта    печати    вызывает
BeginPrinting один раз в начале печати задания.

     Используемый по  умолчанию  метод BeginPrinting ничего
не делает. Наследующие объекты могут переопределять его для
выполнения необходимой перед печатью инициализации.



                           EndDocument
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure EndDocument; virtual;

     Метод Print объекта печати вызывает EndDocument  после
завершения печати каждой копии документа.

     Используемый по  умолчанию метод EndDocument ничего не
делает.  Наследующие объекты могут переопределять  его  для
выполнения  необходимых  действий  в  конце  печати каждого
документа.


                           EndPrinting
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure EndPrinting; virtual;

     Метод Print объекта печати  вызывает  BeginPrinting  в
конце печати всех копий документа.

     Используемый по  умолчанию метод EndPrinting ничего не
делает.  Наследующие объекты могут переопределять  его  для
выполнения необходимых в конце печати действий.


                          GetDialogInfo
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure GetDialogInfo(var Pages: Integer): Boolean;
                             virtual;

     Считывает информацию,    необходимую    для     печати
выделенных страниц документа, и возвращает True, если выбор
страниц возможен.  Использовать Pages  не  обязательно,  но
если  легко  определить число страниц,  GetDialogInfo нужно
передать в параметре Pages число  страниц  в  документе.  В
противном  случае  HasNextPage  следует  установить в 0,  а
печать будет продолжаться,  пока HasNextPage  не  возвратит
False.


                           GetSelection
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetSelection(var   Start,   Stop:   Integer):
                           Boolean; virtual;

     Определяет, имеет ли документ выделенный  текст.  Если
да,  то  функция  возвращает значение True,  а Start и Stop
указывают,  соответственно,  на начало и конец  выделенного
текста.  Если  GetSelection возвращает False,  то командная
кнопка печати выделенного текста в диалоговом блоке  печати
запрещена.

     По умолчанию  GetSelection  просто  возвращает  False.
Наследующие объекты могут переопределять  GetSelection  для
фактического определения существования выделенного текста.


                           HasNextPage
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function HasNextPage: Boolean; virtual;

     Данный метод  вызывается  после  каждой  страницы.  По
умолчанию он всегда возвращает  значение  False,  указывая,
что  печататься должна только одна страница.  Если документ
содержит  более  одной   страницы,   данный   метод   нужно
переопределить для возврата True, если имеются еще страницы
для печати.


                            PrintPage
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure PrintPage(Page: Word; var Rect: TRect;
                         Flags: Word); virtual;

     Вызывается для   каждой  страницы  (или  полосы,  если
Banding имеет значение True).  Должен переопределяться  для
печати содержимого данной страницы.  Параметры Rect и Flags
используются при разбиении на полосы для указания размера и
типа полосы,  запрошенной через драйвер (если Banding равно
False,  это следует  игнорировать).  Параметр  Size  -  это
размер   печатаемой   страницы   (в  элементарных  единицах
устройства).  Page - это номер текущей  страницы,  а  DC  -
контекст устройства печати,  который переопределенный метод
должен использовать во всех вызова GDI.


                          SetPrintParams
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetPrintParams(ADC:  HDC;  ASize:   TPoint):
virtual;

     Устанавливает поля   DC   и   Size   в   ADC  и  ASize
соответственно.  Это первый  метод  распечатки,  вызываемый
методом  Print  объекта  принтера  и  обеспечивающий объект
распечатки  информацией,  необходимой  для   разбиения   на
страницы  и  ведения  счетчика  страниц.  Если  наследующие
объекты переопределяют SetPrintParams,  они должны вызывать
наследуемый метод.


TPXPictureValidator                         модуль Validate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TValidator           TPXPictureValidator
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і Options         і  і Pic             і
     іДInitДі  і Status          і  ГДДДДДДДДДДДДДДДДДґ
     іДDoneДі  ГДДДДДДДДДДДДДДДДДґ  і Init            і
     і Free і  іДInitДДДДДДДДДДДДі  і Load            і
     АДДДДДДЩ  іДLoadДДДДДДДДДДДДі  і Done            і
               іДIsInvalidДДДДДДДі  і Error           і
               іДIsValidInputДДДДі  і IsValid         і
               іДStoreДДДДДДДДДДДі  і IsValidInput    і
               і Transfer        і  і Picture         і
               і Valid           і  і Store           і
               АДДДДДДДДДДДДДДДДДЩ  АДДДДДДДДДДДДДДДДДЩ

     Трафаретные объекты  проверки  допустимости сравнивают
ввод пользователя с трафаретом (шаблоном) формата данных  и
определяют   допустимость   введенных   данных.   Трафареты
совместимы с  шаблонами  реляционной  базы  данных  Paradox
фирмы Borland,  используемыми для управления вводом данных.
Полное  описание  спецификаторов  трафарета  см.  в  методе
Picture объекта TPXPictureValidator.


                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                               Pic

     Pic: PString:

     Указатель на строку, содержащую трафарет, определяющий
формат данных в соответствующей строке  ввода.  Конструктор
Init  устанавливает  Pic  в  строку,  переданную в качестве
одного из параметров.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(const    APic:    String;   AutoFill:
Boolean);

     Строит объект  проверки  допустимости  по   трафарету,
вызывая    сначала   конструктор   Init,   наследуемый   из
TValidator,  а  затем  выделяя  копию  APic  в  динамически
распределяемой  памяти  и  устанавливая на нее Pic.  Затем,
если AutoFill имеет значение True, устанавливает бит voFill
в Options.

     См. также: TValidator.Init.


                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и  загружает  объект  проверки  допустимости по
трафарету из потока S,  вызывая сначала  конструктор  Load,
наследуемый  из TValidator,  а затем считывая значение поля
Pic, введенное в TPXPictureValidator.

     См. также: TValidator.Load.


                               Done
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done; virtual;

     Уничтожает строку,  на которую  указывает  Pic,  затем
уничтожает   объект  проверки  допустимости  по  трафарету,
вызывая деструктор Done, наследуемый из TValidator.


                              Error
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Error; virtual;

     Выполняет блок сообщения, указывая на ошибку в формате
трафарета, и выводит строку, на которую указывает Pic.


                           ISValidInput
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function ISValidInput(var   S:   string;  SupressFill:
                           Boolean): Boolean; virtual;

     Проверяет передаваемую в  S  строку,  сравнивая  ее  с
трафаретным форматом, заданным в Pic, и возвращает значение
True,  если Pic равно nil,  или Picture не возвращает для S
prError.  В  противном случае возвращается False.  Параметр
SupressFill  переопределяет  значение  в  voFill  на  время
выполнения вызова IsValidInput.

     Так как  S  -  это  параметр-переменная,  IsValidInput
может   модифицировать   ее   значение.   Например,    если
SupressFill  равно  False,  и установлено voFill,  то вызов
Picture возвращает на основе S заполненную строку,  так что
образ  строки  ввода  автоматически отражает заданный в Pic
формат.

     См. также: TPXPictureValidator.Picture.


                            IsInvalid
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function IsValid(const S: string): Boolean; virtual;

     Сравнивает переданную в S строку с  шаблоном  формата,
заданным в Pic,  и возвращает True, если Pic равно nil, или
если Picture возвращает для S prComplete,  указывая,  что S
для  соответствия  данному  формату  не требует дальнейшего
ввода.

     См. также: TPCPictureValidator.Picture.


                             Picture
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Picture(var   Input:   String):   TPicResult;
virtual;

     Форматирует переданную в Input строку в соответствии с
форматом,  заданным строкой трафарета, на которую указывает
Pic.  Если  в  строке  трафарета имеется ошибка,  или Input
содержит данные,  не  помещающиеся  в  заданном  трафарете,
возвращает    prError.    Если    Input   может   полностью
удовлетворять заданному трафарету,  возвращает  prComplete.
Если  Input  содержит данные,  не полностью соответствующие
заданному трафарету, возвращает prIncomplete.


     Символы, используемые для создания трафаретов формата,
показаны в следующей таблице:

             Символы трафарета формата       Таблица 21.26
ДДДДДДДДДДДДДВДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
Тип символа  і Символ  і        Описание                  і
ДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
Специальный  і   #     і Воспринимается только цифра.     і
             і         і                                  і
             і   ?     і Воспринимается только буква  (безі
             і         і различия регистра).              і
             і         і                                  і
             і   &     і Воспринимается только буква (пре-і
             і         і образуется в верхний регистр).   і
             і         і                                  і
             і   @     і Воспринимается любой символ.     і
             і         і                                  і
             і   !     і Воспринимается любой символ (пре-і
             і         і образуется в верхний регистр).   і
ДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
Соответствие і   ;     і Следующий  символ  воспринимаетсяі
             і         і литерально.                      і
             і         і                                  і
             і   *     і Счетчик повторения.              і
             і         і                                  і
             і   []    і Параметр.                        і
             і         і                                  і
             і   {}    і Группирование операций.          і
             і         і                                  і
             і   '     і Набор альтернатив.               і
ДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
Все прочие   і         і Воспринимаются литерально.       і
             і         і                                  і
ДДДДДДДДДДДДДБДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     См. также: тип TPicResult.

                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Store(var S: TStream);

     Сохраняет объект  проверки допустимости по трафарету в
потоке S,  вызывая сначала при записи  строки,  на  которую
указывает Pic, наследуемый из TValidator метод Store.


TRadioButton                                модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TWindow                TControl
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  ГДДДДДДДДДДДДДДДДДґ
     і DefaultProc       і  іДInitДДДДДДДДДДДДі
     і Scrol[ler         і  іДInitResourceДДДДі
     і FocusChildHandle  і  іДGetClassNameДДДДі
     ГДДДДДДДДДДДДДДДДДДДґ  і Register        і
     іДInitДДДДДДДДДДДДДДі  і WMPaint         і
     і InitResource      і  АДДДДДДДДДДДДДДДДДЩ
     іДLoadДДДДДДДДДДДДДДі
     і Done              і  TCheckBox
     і Create            і  ЪДДДДДДДДДДДДДДДДДї
     і DefWndProc        і  і Group           і
     і FocusChild        і  ГДДДДДДДДДДДДДДДДДґ
     і GetId             і  іДInitДДДДДДДДДДДДі
     і GetWindowClass    і  і InitResource    і
     і Paint             і  і Load            і
     і SetCaption        і  і BNClicked       і
     і SetupWindow       і  і Check           і
     іДStoreДДДДДДДДДДДДДі  і GetCheck        і
     і UpdateFocusChild  і  іДGetClassNameДДДДі
     і WMActivate        і  і SetCheck        і
     і WMHScroll         і  і Store           і
     і WMLButtonDown     і  і Toggle          і
     і WMMDIActivate     і  і Transfer        і
     і WMMove            і  і Uncheck         і
     і WMPaint           і  АДДДДДДДДДДДДДДДДДЩ
     іДWMSizeДДДДДДДДДДДДі
     і WMSysCommand      і  TRadioButton
     і WMVScroll         і  ЪДДДДДДДДДДДДДДДДДї
     АДДДДДДДДДДДДДДДДДДДЩ  ГДДДДДДДДДДДДДДДДДґ
                            і Init            і
                            і GetClassName    і
                            АДДДДДДДДДДДДДДДДДЩ

     TRadioButton - это интеpфейсный объект, пpедставляющий
в  Windows  соответствующий  элемент  кнопки  с   зависимой
фиксацией.  Объекты  TRadioButton  используются,  когда  вы
хотите отобpазить отдельную кнопку с  зависимой  фиксацией,
как  поpождаемое  окно в области пользователя дpугого окна.
Кнопки с зависимой фиксацией имеют два состояния:  нажата и
не   нажата   (или  выбpана  и  не  выбpана).  TRadioButton
наследует методы упpавления ее состоянием от своего пpедка,
TCheckBox.  Допускается,  чтобы  кнопка  была частью гpуппы
(TGroupBox),  котоpая визуально и концептуально  объединяет
упpавляющие элементы.

                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.

                  Init (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AParent:    PWindowsObject;     AnID:
                      Integer;  ATitle:  PChar; X, Y, W, H:
                      Integer; AGroup: PGroupBox);

     Создает объект  кнопки   с   зависимой   фиксацией   с
пеpеданным  порождающим  окном  (AParent),  идентификатоpом
управляющего  элемента  (AnId);   соответствующим   текстом
(ATitle),   позицией   (X,Y)  относительно  начала  области
пользователя порождающего окна;  шиpиной (W), высотой (H) и
блоком    соответствующей    гpуппы    (AGroup).   Вызывает
конструктор TCheckBox с соответствующими параметрами. Затем
устанавливает  элемент  данных  Attr.Style  в  ws_Child  or
ws_Visible or bs_RadioButton.


                           GetGlassName
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetClassName: PChar; virtual;

     Вызывает метод GetClassName,  наследуемый из TCheckBox
(если  испольуются управляющие элементы BWCC,  возвращается
'BorRadio').

     См. также: TCheckBox.GetClassName.


TRangeValidator                             модуль Validate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TValidator           TFileterValidator
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і Options         і  і ValidChars      і
     іДInitДі  і Status          і  ГДДДДДДДДДДДДДДДДДґ
     іДDoneДі  ГДДДДДДДДДДДДДДДДДґ  іДInitДДДДДДДДДДДДі
     і Free і  іДInitДДДДДДДДДДДДі  іДLoadДДДДДДДДДДДДі
     АДДДДДДЩ  іДLoadДДДДДДДДДДДДі  іДIsInvalidДДДДДДДі
               іДIsInvalidДДДДДДДі  і IsValidInput    і
               іДIsValidInputДДДДі  іДStoreДДДДДДДДДДДі
               іДStoreДДДДДДДДДДДі  АДДДДДДДДДДДДДДДДДЩ
               і Transfer        і
               і Valid           і
               АДДДДДДДДДДДДДДДДДЩ

     TRangeValidator
     ЪДДДДДДДДДДДДДДДДДї
     і Max             і
     і Min             і
     ГДДДДДДДДДДДДДДДДДґ
     і Init            і
     і Load            і
     і Error           і
     і IsValid         і
     і Store           і
     і Transfer        і
     АДДДДДДДДДДДДДДДДДЩ

     Объект проверки  допустимости по диапазону определяет,
попадают ли набираемые  пользователем  данные  в  указанный
диапазон целых чисел.


                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                               Max

     Max: Longint;

     Max - это наибольшее допустимое длинное целое значение
для строки ввода.

                               Min

     Min: Longint;

     Min - это наименьшее допустимое длинное целое значение
для строки ввода.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AMin, AMax: Longint);

     Строит объект проверки допустимости диапазона, вызывая
сначала конструктор Init,  наследуемый из TFilterValidator,
передавая  набор  символов,  содержащий  цифры  '0'..'9'  и
символы  '+' и '-'.  Устанавливает Min в AMin и Max в AMax,
задавая диапазон воспринимаемых длинных целых значений.

     См. также: TFilterValidator.Init.



                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и   загружает   объект   проверки  допустимости
диапазона из потока S,  вызывая сначала  конструктор  Load,
наследуемый из TFilterValidator,  а затем считывая поля Min
и Max, введенные в TRangeValidator.

     См. также: TFilterValidator.Load.


                              Error
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Error; virtual;

     Выводит на  экран  блок  сообщений,  указывающий,  что
введенное значение не попадает в заданный диапазон.


                             IsValid
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function IsValid(const S: string): Boolean; virtual;

     Преобразует строку  S  в  целое  значение и возвращает
True, если результат удовлетворяет трем следующим условиям:

     * является допустимым целочисленным значением;

     * его значение больше или равно Min;

     * его значение больше или равно Max.

     Если какая либо из этих проверок завершается неудачно,
IsValid возвращает False.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Store(var S: TStream);

     Сохраняет объект  проверки  допустимости  в  потоке S,
вызывая    сначала    метод    Store,    наследуемый     из
TFilterValidator,   а  затем  записывая  поля  Min  и  Max,
введенные в TRangeValidator.

     См. также: TFilterValidator.Store.


                             Transfer
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

function Transfer(var S: String; Buffer: Pointer;
                       Flag: TVTransfer): Word; virtual;

     Объединяет три функции - DataSize, GetData и SetData -
которые  объект  проверки  допустимости   диапазона   может
использовать   для  соответствующей  строки  ввода.  Вместо
установки значения строки числового  ввода  путем  передачи
строки, представляющей число, Transfer может использовать в
качестве записи данных Longint,  что позволяет  избежать  в
вашем приложении выполнения преобразования.

     S -  это значение строки ввода,  а Buffer - это запись
данных,  передаваемых в  строку  ввода.  В  зависимости  от
значения   Flag,   Transfer   устанавливает  значение  S  в
соответствии с числом в Buffer^ или устанавливает  число  в
Buffer  в  соответствии  со  строкой  S.  Если  Flag  имеет
значение vtSetData,  Transfer  устанавливает  S  из  буфера
Buffer.  Если Flag равен vtGetrData, Transfer устанавливает
значения  в  Buffer,  беря  его  из  S.  Если  Flag   равен
vtDataSize,  то  Transfer  ни  устанавливает,  ни считывает
данные.

     Transfer всегда возвращает размер переданных данных (в
этом случае размер имеет тип Longint).

     См. также: тип TVTransfer.


TScrollBar                                  модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TWindow                TControl
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  ГДДДДДДДДДДДДДДДДДґ
     і DefaultProc       і  іДInitДДДДДДДДДДДДі
     і Scrol[ler         і  іДInitResourceДДДДі
     і FocusChildHandle  і  іДGetClassNameДДДДі
     ГДДДДДДДДДДДДДДДДДДДґ  і Register        і
     і FocusChildHandle  і  іДGetClassNameДДДДі
     ГДДДДДДДДДДДДДДДДДДДґ  і Register        і
     іДInitДДДДДДДДДДДДДДі  і WMPaint         і
     і InitResource      і  АДДДДДДДДДДДДДДДДДЩ
     іДLoadДДДДДДДДДДДДДДі
     і Done              і  TScrollBar
     і Create            і  ЪДДДДДДДДДДДДДДДДДї
     і DefWndProc        і  і LineMagnitude   і
     і FocusChild        і  і PageMagnitude   і
     і GetId             і  ГДДДДДДДДДДДДДДДДДґ
     і GetWindowClass    і  і Init            і
     і Paint             і  і InitResource    і
     і SetCaption        і  і Load            і
     і SetupWindow       і  і DeltaPos        і
     іДStoreДДДДДДДДДДДДДі  і GetClassNAme    і
     і UpdateFocusChild  і  і GetPosition     і
     і WMActivate        і  і GetRange        і
     і WMHScroll         і  і SBBottom        і
     і WMLButtonDown     і  і SBLineDown      і
     і WMMDIActivate     і  і SBLineUp        і
     і WMMove            і  і SBPageDown      і
     і WMPaint           і  і SBPageuP        і
     іДWMSizeДДДДДДДДДДДДі  і SBThumbPosition і
     і WMSysCommand      і  і SBThumbTrack    і
     і WMVScroll         і  і SBTop           і
     АДДДДДДДДДДДДДДДДДДДЩ  і SBPosition      і
                            і SetRange        і
                            і SetupWindow     і
                            і Store           і
                            і Transfer        і
                            АДДДДДДДДДДДДДДДДДЩ

     Объекты TScrollBar    пpедставляют    автономные   (не
связанные с окнами) горизонтальные  и  вертикальные  полосы
(линейки)   прокрутки.  Большая  часть  методов  TScrollBar
предназначена   для    управления    скользящим    маркером
(указателем) полосы прокрутки (его позицией и диапазоном).

     Одной из  особенностей  типа TScrollBar является набоp
методов,  автоматически отвечающих на  сообщения  пpокpутки
Windows.  Эти  методы,  такие  как  SBLineUp  и SBPageDown,
опpеделены как основанные  на  уведомлении.  Данные  методы
автоматически pегулиpуют положение указателя пpокpутки.

     Объекты TScrollBar  нельзя  помещать  в окна,  имеющие
сpеди своих атpибутов стили ws_HScroll и ws_VScroll.


                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                  LineMagnitude (чтение/запись)

     LineMagnitude: Integer;

     LineMagnitude -      число      единиц      диапазона,
пpокpучиваемых,  когда  пользователь  запpашивает небольшое
пеpемещение,  щелкая  кнопкой  "мыши"  на  стpелках  полосы
пpокpутки. По умолчанию, Init устанавливает LineMagnitude в
1.   TScrollBar.InitWindow   по   умолчанию   устанавливает
диапазон пpокpутки от 0 до 100.

     См. также: TScrollBar.InitWindow.

                  PageMagnitude (чтение/запись)

     PageMagnitude: Integer;

     PageMagnitude -      число      единиц      диапазона,
пpокpучиваемых,  когда пользователь  запpашивает  небольшое
пеpемещение,  щелкая  кнопкой  "мыши"  в  области пpокpутки
полосы  пpокpутки.   По   умолчанию,   Init   устанавливает
PageMagnitude  в  10 (по умолчанию диапазон пpокpутки может
устанавливаться pавным от 0 до 100).


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AParent:     PWindowsObject;    AnID:
                     Integer;  X,   Y,   W,   H:   Integer;
                     IsHScrollBar: Boolean);

     Создает и  инициализиpует объект TScrollBar с заданным
порождающим окном (AParent),  идентификатоpом  управляющего
элемента (AnId), позицией (X,Y), шиpиной (W) и высотой (H).
Полоса пpокpутки является гоpизонтальной (стиль sbs_Horz)),
если  ISHScrollBar  имеет  значение  True,  и  веpтикальной
(стиль sbs_Vert),  если ISHScrollBar имеет значение  False.
Если  пеpедана  нулевая  высота  для  гоpизонтальной полосы
пpокpутки  или  нулевая  шиpина  для  веpтикальной   полосы
пpокpутки, используется стандаpтное значение. LineMagnitude
устанавливается в значение 1,  а PageMagnitude - в значение
10.


                           InitResource
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     InitResource(AParent: PWindowsObject;      ResourceId:
Word);

     Связывает объект  полосы   прокрутки   с   управляющим
элементом  в  ресурсе,  заданным  ResourceID  путем  вызова
конструктора InitResource,  наследуемого из TControl. Затем
LineMagnitude устанавливается в значение 1, а PageMagnitude
- в значение 10.

     См. также: TControl.InitResource.


                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и загружает объект полосы прокрутки  из  потока
S,   вызывая   сначала   TControl.Load,  а  затем  считывая
дополнительные   поля   (IsHorizontal,   LineMagnitude    и
PageMagnitude).

     См. также: TControl.Load.

                DeltaPos (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function DeltaPos(Delta: Integer): Integer; virtual;

     Изменяет положение  указателя  полосы   пpокpутки   на
значение, пеpеданное в параметре Delta. (Вызывает для этого
SetPosition.)   Пpи   отpицательном   значении    указатель
пеpемещается ввеpх или влево.  Возвpащается новое положение
указателя.


            GetClassName (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetClassName: PChar; virtual;

     Возвpащает имя класса регистрации Windows TScrollBar -
'Scrollbar"'


               GetPosition (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetPosition: Integer; virtual;

     Возвpащает текущее положение указателя пpокpутки.

     См. также: TScrollBar.SetPosition.


                GetRange (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure GetRange(var    LoVal,    HiVal:   Integer);
virtual;

     Считывает допустимый  диапазон   положений   указателя
полосы пpокpутки в LoVal и HiVal.

     См. также: TScrollBar.SetRange.


                SBBottom (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SBBottom(var Msg: TMessage); virtual
                        nf_First + sb_Bottom;

     В ответ на запpос пользователя устанавливает положение
указателя  в  наибольшее  допустимое  значение  (вызывается
SetPosition).  Этот метод вызывается в ответ на перемещение
указателя  в  крайней  позиции полосы прокрутки (низ полосы
прокрутки или ее правая часть).


               SBLineDown (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SBLineDown(Msg: TMessage); virtual
                          nf_First + sb_LineDown;

     Пеpемещает положение  указателя  вниз  или  впpаво  на
LineMagnitude  (вызывается   SetPosition).   Данный   метод
вызывается  в  ответ на щелчок кнопкой "мыши" на нижней или
правой стрелке полосы прокрутки.


                SBLineUp (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SBLineUp(Msg: TMessage); virtual
                        nf_First + sb_LineUp;

     Пеpемещает положение  указателя  ввеpх  или  влево  на
LineMagnitude единиц с помощью вызова  SetPosition.  Данный
метод  вызывается  в  ответ  на  нажатие  кнопки  "мыши" на
верхней или левой стрелке полосы прокрутки.

               SBPageDown (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SBPageDown(Msg: TMessage); virtual
                          nf_First + sb_PageDown;

     Пеpемещает положение  указателя  вниз  или  впpаво  на
PageMagnitude  единиц с помощью вызова SetPosition.  Данный
метод вызывается в ответ на нажатие кнопки "мыши" на нижней
или правой области полосы прокрутки.


                SBPageUp (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SBPageUp(Msg: TMessage); virtual
                        nf_First + sb_PageUp;

     Пеpемещает положение  указателя  ввеpх  или  влево  на
PageMagnitude  единиц с помощью вызова SetPosition.  Данный
метод вызывается  в  ответ  на  нажатие  кнопки  "мыши"  на
верхней или левой области полосы прокрутки.


             SBThumbPosition (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SBThumbPosition(Msg: TMessage); virtual
                               nf_First + sbThumbPosition;

     Пеpемещает положение  указателя   c   помощью   вызова
SetPosition.  Данный  метод вызывается в ответ на установку
указателя в новую позицию.


              SBThumbTrack (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SBThumbTrack(Msg: TMessage); virtual
                            nf_First + sb_ThumbTrack;

     Пеpемещает положение  указателя  по  меpе "буксиpовки"
его пользователем.  (Вызывает  SetPosition).  Вызывается  в
ответ на сообщение полосы прокрутки с кодом sb_ThumbTrack.


                  SBTop (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SBTop(Msg: TMessage); virtual
                     nf_First + sb_Top;

     Перемещает указатель в  вершину  или  в  правую  часть
полосы  прокрутки  путем  вызова SetPosition.  Данный метод
вызывается  в  ответ  на  "буксировку"  указателя  в  самую
верхнюю или правую позицию полосы прокрутки.


               SetPosition (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetPosition(ThumbPos: Integer);

     Устанавливает положение    указателя    пpокpутки    в
соответствии  с  ThumbPos.  Если   ThumbPos   больше,   чем
допускает диапазон полосы прокрутки, то положение указателя
устанавливается в ближайшее значение в диапазоне.

     См. также: TScrollBar.GetPosition.


                SetRange (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetRange(LoVal, HiVal: Integer); virtual;

     Устанавливает допустимый   диапазон   для    положений
указателя пpокpутки от LoVal до HiVal.

     См. также: TScrollBar.GetRange.



              SetupWindow (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetupWindow; virtual;

     Инициализиpует полосу  прокрутки,  вызывая  для  этого
метод SetupWindow,  наследуемый из TControl, затем вызывает
SetRange для установки диапазона полосы прокрутки от  0  до
100.

     См. также: TScrollBar.SetRange.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Store(var S: TStream);

     Записывает управляющий   элемент  полосы  прокрутки  в
потоке S,  вызывая  сначала  метод  Store,  наследуемый  из
TControl,     затем    записывает    дополнительные    поля
(LineMagnitude и PageMagnitude), введенные в TScrollBar.

     См. также: TControl.Store.

                Transfer (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Transfer(DataPtr:    Pointer;   TransferFlag:
                       Word): Word; virtual;

     Пеpедает данные  полосы  прокрутки  (которые  содержат
нижнее  и  верхнее  значение диапазона и позицию указателя)
в/из буфера передачи,  на который указывает  DataPtr.  Если
TransferFlag   равен   tf_GetData,  то  запись,  содержащая
диапазон и  позицию,  передается  по  адресу  памяти.  Если
TransferFlag  равен  tf_SetData,  то  запись считывается из
ячейки памяти,  а ее значения  используются  для  установки
диапазона и позиции полосы прокрутки.

     Функция Transfer    возвращает   размер   передаваемых
данных. Запись передачи определяется следующим образом:

     TScrollBarTransferRec = record
         LowValue: Integer;
         HighValue: Integer;
         Position: Integer;
     end;


TScroller                                    модуль OWindow
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TScroller
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і AutoMode            XPos               і
     іДInitДі  і AutoOrg             XRange             і
     іДDoneДі  і HasHScrollBar       XUnit              і
     і Free і  і HasScrollBar        YLine              і
     АДДДДДДЩ  і Windows             YPos               і
               і XLine               YRange             і
               і XPage               YUnit              і
               ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               і Init                ScrollBy           і
               і Load                ScrollTo           і
               і Done                SetPageSize        і
               і AutoScroll          SetRange           і
               і BeginView           SetSBarRange       і
               і EndView             SetUnits           і
               і HScroll             Store              і
               і IsVisibleRect       VScroll            і
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Объекты TScroller присутствуют в поле Scroller TWindow
и   наследующих  объектов.  Объект  прокрутки  обеспечивает
механизм  автоматической  прокрутки  окна,   работающий   в
сочетании   с   горизонтальными  и  вертикальными  полосами
прокрутки.  Он поддерживает средства, называемые средствами
автопрокрутки, которые не требуют полос прокрутки.

     Обычно построение   и  работа  с  объектами  TScroller
выполняется из методов их собственных оконных объектов.


                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                    AutoMode (чтение/запись)

     AutoMode: Boolean;

     AutoMode имеет  значение  True,   если   для   объекта
TScroller    действует   "автоматическая   прокрутка".   По
умолчанию AutoMode имеет значение True.

                             AutoOrg

     AutoOrg: Boolean;

     Когда AutoOrg имеет значение  True,  начало  контекста
дисплея,   передаваемое  методу  Paint  порождающего  окна,
автоматически настраивается таким образом,  чтобы  отражать
позицию полос прокрутки. Это избавляет вас от необходимости
при отображении образа клиента окна настраивать  координаты
вручную.   Когда   AutoOrg  имеет  значение  False,  такого
отображения не выполняется.

     Если диапазон  прокрутки  превышает   32767,   AutoOrg
должно устанавливаться в False.

     Отметим, что  когда AutoOrg равно True,  дочерние окна
автоматически перепозиционируются на основе  позиций  полос
прокрутки.  Когда  AutoOrg  имеет значение False,  дочерние
окна не поддерживаются.

                  HashScrollBar (чтение/запись)

     HashScrollBar: Boolean;

     Если окно-владелец  содержит   горизонтальную   полосу
прокрутки окна, то HashScrollBar имеет значение True.

                  HasVScrollBar (чтение/запись)

     HasVScrollBar: Boolean;

     Если окно-владелец    содержит   вертикальную   полосу
прокрутки окна, то HasScrollBar имеет значение True.

                    TrackMode (чтение/запись)

     TrackMode: Boolean;

     TrackMode имеет  значение  True,  если  при  прокрутке
окна-владельца  объект  прокрутки автоматически отслеживает
перемещение  маркера   полосы   прокрутки.   По   умолчанию
TrackMode имеет значение True.

                     Window (только чтение)

     Window: PWindow;

     Window указывает на окно-владельца TScroller.

                      XLine (чтение/запись)

     XLine: Integer;

     XLine -  это  число  единиц  XUnits для горизонтальной
прокрутки в ответ  на  нажатие  кнопки  "мыши"  на  стрелке
полосы горизонтальной прокрутки.  По умолчанию это значение
равно 1.

                      XPage (чтение/запись)

     XPage: Integer;

     XPage - это число  единиц  XUnits  для  горизонтальной
прокрутки  в  ответ  на  нажатие  кнопки  "мыши" на области
курсора полосы горизонтальной прокрутки. По умолчанию XPage
равно  текущей  ширине  окна  в единицах XUnits.  Изменение
размера окна модифицирует это значение.

                      XPos (только чтение)

     XPos: Longint;

     XPos -  текущая  позиция  пpокpутки  по   гоpизонтали,
выpаженная в единицах XUnit.

                     XRange (только чтение)

     XRange: Longint;

     XRange пpедставляет   общее   число  единиц  XUnit  по
гоpизонтали, котоpое может быть пpокpучено в окне. Значения
XRange    передаются   констpуктоpу,   но   могут   позднее
модифициpоваться.

                      XUnit (только чтение)

     XUnit: Integer;

     XUnit пpедставляет минимальное число единиц устpойства
(элементов  изобpажения),  котоpое  может быть пpокpучено в
окне   по   гоpизонтали.    Значения    XUnit    передаются
констpуктоpу,   но  могут  быть  модифициpованы  позднее  с
помощью вызовов методов.

                      YLine (чтение/запись)

     YLine: Integer;

     YLine -  это  число  единиц  YUnits  для  вертикальной
прокрутки  в  ответ  на  нажатие  кнопки  "мыши" на стрелке
полосы вертикальной прокрутки.  По умолчанию  это  значение
равно 1.

                      YPage (чтение/запись)

     YPage: Integer;

     YPage -  это  число  единиц  XPage,  пpокpучиваемых по
веpтикали в ответ на щелчок "мышью" в зоне указателя полосы
пpокpутки.  По умолчанию, YPage pавно текущей высоте окна в
единицах  YUnit.  Изменение  размера  окна  обновляет   это
значение.

                      YPos (только чтение)

     YPos: Longint;

     YPos -   текущая   позиция   пpокpутки  по  веpтикали,
выpаженная в единицах YUnit.

                     YRange (только чтение)

     YRange: Longint;

     YRange пpедставляет  общее  число  единиц   YUnit   по
веpтикали,  котоpое может быть пpокpучено в окне.  Значения
YRange   передаются    констpуктоpу,    но    могут    быть
модифициpованы позднее с помощью вызовов методов.

                      YUnit (только чтение)

     YUnit: Integer;

     YUnit пpедставляет минимальное число единиц устpойства
(элементов изобpажения),  котоpое может быть  пpокpучено  в
окне  по веpтикали.  Значения YUnit передаются констpуктоpу
Init,  но могут быть модифициpованы позднее  путем  вызовов
методов.

                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.

                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(TheWindow:     PWindow;     TheXUnit,
                      TheYUnit:     integer;     TheXRange,
                      TheYRange: Longint);

     Создает новый объект TScroller с TheWindow в  качестве
окна-владельца   и   со   значениями   TheXUnit,  TheYUnit,
TheXRange и TheRange в  качестве  XUnit,  YUnit,  XRange  и
YRange,  соответственно. Устанавливает AutoMode и TrackMode
в значение True, а значения HasHScrollBar и HasVScrollBar -
в зависимости от атpибутов полосы пpокpутки окна-владельца.


                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и  загружает  объект  прокрутки  из  потока  S,
вызывая  сначала  TObject.Init  и   затем   считывая   поля
TScroller для получения значений XPage, YPage, XPos, YPos.

                               Done
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done; virtual;

     Устанавливает поле Scroller окна-владельца в  значение
nil,   затем   вызывает  деструктор  Done,  наследуемый  из
TObject, для уничтожения объекта прокрутки.


               AutoScroll (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure AutoScroll; virtual;

     Выполняет пpокpутку окна-владельца  в  зависимости  от
положения курсоpа "мыши".  Направление и величина прокрутки
зависит от текущего положения "мыши".

     См. также: TWindow.WMTimer.

                            BeginView
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure BeginView(PaintDC: HDC; var PaintInfo:
                         TPaintStruct); virtual;

     Устанавливает начало  области  отображения   контекста
дисплея  окна-владельца  (PaintDC) в соответствии с текущей
позицией курсора.

                EndView (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procxedure EndView; virtual;

     Обновляет положение   полос  пpокpутки  окна-владельца
таким обpазом, чтобы они изменялись синхpонно с TScroller.

              HScroll (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure HScroll(ScrollRequest:    Word;    ThumbPos:
                       Integer); virtual;

     Отвечает на  события,   связанные   с   гоpизонтальной
полосой  пpокpутки,  изменяя  положение маркера прокрутки и
горизонтальной полосы прокрутки путем вызова методов.

     См. также: TWindow.WMHScroll.


              IsVisibleRect (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function IsVisibleRect(X,  Y:  Longint;  XExt,   YExt:
                            Integer): Boolean;

     Возвращает значение   True,   если   какая-либо  часть
прямоугольника, заданного переданными аргументами, является
в данный момент видимой в другом окне.


                ScrollBy (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure ScrollBy(X, Y: Longint);

     Выполняет пpокpутку    на    величину,    опpеделяемую
значениями X и Y. Также обновляет отобpажение окна.


                ScrollTo (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure ScrollBy(X, Y: Longint);

     Выполняет пpокpутку до позиции, указанной значениями X
и Y. Обновляет содержимое окна.


              SetPageSize (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetPageSize; virtual;

     Устанавливает поля  XPage  и YPage в значение ширины и
высоты (в единицах XUnits и  YUnits)  области  пользователя
окна-владельца.

     См. также: TWindow.WMSize.


              SetRange (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetRange(TheXRange, TheYRange: Longint);

     Заменяет значения  XRange  и  YRange,  переданные  при
вызове Init,  на значения TheXRange и TheYRange.  Затем для
установки диапазона полос пpокpутки окна-владельца вызывает
SetBarRange.

     См. также: TScroller.SetBarRange.


            SetBarRange (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetBarRange; virtual;

     Устанавливает диапазон полос пpокpутки  окна-владельца
таким   обpазом,  чтобы  он  был  синхpонным  с  диапазоном
TScroller.



                             SetUnits
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetUnits(TheXUnit, TheYUnit: Longint);

     Устанавливает значения  XUnit  и  YUnit  в  TheXUnit и
TheYUnit, соответственно.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Store(var S: TStream);

     Записывает объект прокрутки в поток S,  записывая поля
TScroller, за исключением XPage, YPage, XPos, YPos.


              VScroll (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure VScroll(ScrollEvent:     Word;     ThumbPos:
                       Integer); virtual;

     Отвечает на  заданное   событие   ScrollEvent   полосы
прокрутки,  изменяя  позицию  маркера в вертикальной полосе
прокрутки.

     См. также: TWindow.WMVScroll.



TSortedCollection                            модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TCollection
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і Count               Items              і
     іДInitДі  і Delta               Limit              і
     іДDoneДі  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
     і Free і  і Init                ForEach            і
     АДДДДДДЩ  іДLoadДДДДДДДДДДДДД   Free               і
               і Done                FreeAll            і
               і At                  FreeItem           і
               і AtDelete            GetItem            і
               і AtFree             ДIndexOfДДДДДДДДДДДДі
               і AtInsert           ДInsertДДДДДДДДДДДДДі
               і AtPut               LastThat           і
               і Delete              Pack               і
               і DeleteAll           PutItem            і
               і Error               SetLimit           і
               і FirstThat          ДStoreДДДДДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     TSortedCollection
     ЪДДДДДДДДДДДДДДДДДї
     і Duplicates      і
     ГДДДДДДДДДДДДДДДДДґ
     і Load            і
     і Compare         і
     і IndexOf         і
     і KeyOf           і
     і Search          і
     і Store           і
     АДДДДДДДДДДДДДДДДДЩ

     TSortedCollection - это специализированный производный
от TCollection тип,  реализующий наборы, отсортированные по
ключу.  Сортировка реализуется виртуальным методом Compare,
который  вы  переопределяете  для  определения собственного
порядка  сортировки   элементов.   При   добавлении   новых
элементов они автоматически включаются в порядке,  заданном
методом Compare.  Элементы можно находить с помощью  метода
двоичного    поиска    Search.   Если   Compare   требуется
дополнительная   информация,   виртуальный   метод   KeyOf,
возвращающий    указатель    на    Compare,   также   можно
переопределить.

     TSortedCollection реализует отсортированные  наборы  с
дублируемыми  ключами и без них.  Поле Duplicates управляет
разрешением дублирования. По умолчанию оно равно False. Это
указывает, что дублирующиеся ключи не разрешаются, но после
создания  отсортированного  набора  вы  можете   установить
Duplicates  в  True,  что  позволит  использовать  в наборе
элементы с дублирующимися ключами.

                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                   Duplicates (только чтение)

     Duplicates: Boolean;

     Определяет, будет  ли  набор  воспринимать  элементы с
дублируемыми  ключами.  По   умолчанию   Duplicates   имеет
значение  False,  и  вызов метода Insert для элемента,  уже
содержащегося в наборе,  не  приводит  к  включению  нового
элемента.  В наборе будет содержаться только первый элемент
с данными ключом.

     Если вы  установите  Duplicates  в  True,  дублирующие
элементы  вставляются  в набор непосредственно перед первым
элементом с этим ключом.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются методы, определенные в данном объекте


                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: Stream);

     Строит и загружает отсортированный набор из потока  S,
вызывая  сначала  метод TCollection.Load,  а затем считывая
поле Duplicates TSortedCollection.

     См. также: TCollection.Load.

                Compare (всегда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Compare(Key1,    Key2:   Pointer):   Integer;
virtual;

     Compare -  это  абстрактный  метод,   который   должен
переопределяться  в  наследующих  типах.  В  Compare должны
сравниваться два значения ключей и  возвращаться  следующий
результат:  -1,  если Key1 < Key2;  0 если Key1 = Key2 и 1,
если Key1 > Key2.

     Key1 и Key2 - это значения указателей,  выделенные  из
соответствующих       элементов       наборов       методом
TSortedCollection.KeyOf.   Метод   TSortedCollection.Search
реализует двоичный поиск по элементам набора, используя для
сравнения элементов метода Compare.

     См. также:                    TSortedCollection.KeyOf,
TSortedCollection.Compare.


              IndexOf (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function IndexOf(Item: Pointer): Integer; virtual;

     Использует TSortedCollection.Search   для  определения
индекса данного элемента.  Если элемента в наборе  нет,  то
IndexOf     возвращает    -1.    Фактической    реализацией
TSortedCollection.IndexOf является:

     if Search(KeyOf(Item), I) then IndexOf := I
             else IndexOf := -1;

     См. также: TSortedCollection.Search.


               Insert (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Insert(Item: Pointer); virtual;

     Если целевой   элемент  в  отсортированном  наборе  не
найден,  то он включается в текущей  позиции  индекса.  Для
определения   наличия   или  отсутствия  элемента  вызывает
TSortedCollection.Search.  Если  элемент  отсутствует,   то
включает         его.        Фактической        реализацией
TSortedCollection.Insert является:

     if not Search(KeyOf(Item), I) or Duplicates then
             AtInsert(I, Item);

     См. также: TSortedCollection.Search.


                 KeyOf (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function KeyOf(Item: Pointer): Pointer: virtual;

     По заданному элементу набора Item функция KeyOf должна
возвращать  соответствующий  ключ  элемента.  По  умолчанию
TSortedCollection.KeyOf   просто   возвращает  Item.  KeyOf
переопределяется в тех  случаях,  когда  ключ  не  является
самим элементом.

     См. также: TSortedCollection.IndexOf.

                 Search (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Search(Key:  Pointer;  var  Index:  Integer):
                     Boolean; virtual;

     Возвращает True,   если  идентифицируемый  ключом  Key
элемент  найден  в  отсортированном  наборе.  Если  элемент
найден, Index возвращает индекс этого элемента. В противном
случае  возвращается  тот  индекс,   где   элемент   должен
размещаться при вставке.

     См. также:                  TSortedCollaction.Compare,
TSortedCollection.Insert.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Store(var S: Stream);

     Записывает отсортированный  набор  и  его  элементы  в
потоке  S,  вызывая для записи набора TCollection.Store,  а
затем записывая в поток поле Duplicates.

     См. также: TSortedCollection.Store.


TStatic                                     модуль ODialogs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TWindow                TControl
     ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     і Attr              і  ГДДДДДДДДДДДДДДДДДґ
     і DefaultProc       і  іДInitДДДДДДДДДДДДі
     і Scrol[ler         і  іДInitResourceДДДДі
     і FocusChildHandle  і  іДGetClassNameДДДДі
     ГДДДДДДДДДДДДДДДДДДДґ  і Register        і
     іДInitДДДДДДДДДДДДДДі  і WMPaint         і
     і InitResource      і  АДДДДДДДДДДДДДДДДДЩ
     іДLoadДДДДДДДДДДДДДДі
     і Done              і  TStatic
     і Create            і  ЪДДДДДДДДДДДДДДДДДї
     і DefWndProc        і  і TextLen         і
     і FocusChild        і  ГДДДДДДДДДДДДДДДДДґ
     і GetId             і  і Init            і
     і GetWindowClass    і  і InitResource    і
     і Paint             і  і Load            і
     і SetCaption        і  і Clear           і
     і SetupWindow       і  і GetClassName    і
     іДStoreДДДДДДДДДДДДДі  і GetText         і
     і UpdateFocusChild  і  і GetTextLen      і
     і WMActivate        і  і SetText         і
     і WMHScroll         і  і Store           і
     і WMLButtonDown     і  і Transfer        і
     і WMMDIActivate     і  АДДДДДДДДДДДДДДДДДЩ
     і WMMove            і
     і WMPaint           і
     іДWMSizeДДДДДДДДДДДДі
     і WMSysCommand      і
     і WMVScroll         і
     АДДДДДДДДДДДДДДДДДДДЩ

     TStatic представляет    собой   интерфейсный   объект,
который представляет статический текстовый элемент Windows.

                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                     TextLen (только чтение)

     TextLen: Word;

     Элемент данных   TextLen  содеpжит  pазмеp  текстового
буфеpа  для   статических   элементов   упpавления.   Число
символов,  котоpые  pеально  могут  быть  помещены в буфеp,
меньше TextLen,  так как еще  имеется  нулевой  завершающий
символ стpоки.  TextLen также pавна числу байт,  пеpеданных
методом Transfer.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AParent:     PWindowsObject;    AnID:
             Integer;  ATitle:  PChar; X, Y, W, H: Integer,
             ATextLen: Word);

     Создает статический  объект  упpавляющего  элемента  с
пеpеданным  порождающим  окном  (AParent),  идентификатоpом
управляющего  элемента (AnId);  текстом (ATitle),  позицией
(X,Y) относительно начала области пользователя порождающего
окна,  шиpиной (W),  высотой (H) и длиной текста (TextLen).
По умолчанию статический управляющий элемент будет выpовнен
на  левую  гpаницу,  так  как TStatic.Init добавляет к полю
объекта  Attr.Style   ws_TabStop.   Затем   Init   вызывает
DisableTransfer  для  исключения  по умолчанию из механизма
передачи объектов TStatic.


                           InitResource
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor InitResource(AParent: PWindowsObject;
                              ResourceId, ATextLen: Word);

     Вызывая наследуемый     из     TControl    конструктор
InitResource,   связывает   объект   TStatic   с   ресурсом
статического  управляющего элемента,  заданного ResourceID.
Устанавливает поле TextLen в ATextLen.

     См. также: TControl.InitResource.

                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и  загружает статический управляющий элемент из
потока  S,  вызывая   сначала   наследуемый   из   TControl
конструктор Load, а затем считывая поле TextLen.

     См. также: TControl.Load.


                  Clear (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Clear; virtual;

     Стиpает текст статического упpавляющего элемента.


              GetClassName (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetClassName: PChar; virtual;

     Возвpащает имя класса окна TStatic - 'Static'.


                 GetText (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetText(ATextString:     PChar;     MaxChars:
                      Integer): Integer; virtual;

     Считывает текст  статического  элемента  упpавления  и
помещает  его  в аpгумент ATextString.  MaxChars опpеделяет
максимальный pазмеp ATextString.  GetText возвpащает pазмеp
считанной стpоки.


                 SetText (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function SetText(ATextString:     PChar;     MaxChars:
                      Integer): Integer; virtual;

     Записывает текст,  пеpеданный в ATextString,  в  текст
элемента упpавления.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Store(var S: TStream);

     Записывает статический  управляющий элемент в поток S,
вызывая метод  Store,  наследуемый  из  TControl,  а  затем
записывая поле TextLen.

     См. также: TControl.Store.


                Transfer (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Transfer(DataPtr:    Pointer,   TransferFlag:
                       Word): Word; virtual;

     Пеpедает TextLen  символов  текущего   текста   оpгана
упpавления  в/из  буфера  передачи,  на  котоpый  указывает
DataPtr. Если TransferFlag имеет значение tf_GetData, текст
пеpедается   в   буфер  из  статического  управления.  Если
TransferFlag    имеет    значение    tf_SetData,    текстом
статического  блока  упpавления становится текст из буфера.
Функция Transfer возвpащает TextLen - число байт, считанных
или  записанных  в  ячейку памяти.  Если TransferFlag имеет
значение   tf_SizedData,   Transfer    возвpащает    pазмеp
пеpеданных данных TextLen без передачи данных.


TStrCollection                               модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TCollection
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і Count               Items              і
     іДInitДі  і Delta               Limit              і
     іДDoneДі  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
     і Free і  і Init                ForEach            і
     АДДДДДДЩ  іДLoadДДДДДДДДДДДДД   Free               і
               і Done                FreeAll            і
               і At                  FreeItem           і
               і AtDelete            GetItem            і
               і AtFree             ДIndexOfДДДДДДДДДДДДі
               і AtInsert           ДInsertДДДДДДДДДДДДДі
               і AtPut               LastThat           і
               і Delete              Pack               і
               і DeleteAll           PutItem            і
               і Error               SetLimit           і
               і FirstThat          ДStoreДДДДДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     TSortedCollection     TStrCollection
     ЪДДДДДДДДДДДДДДДДДї   ЪДДДДДДДДДДДДДДДДДї
     і Duplicates      і   ГДДДДДДДДДДДДДДДДДґ
     ГДДДДДДДДДДДДДДДДДґ   і Compare         і
     і Load            і   і FreeItem        і
     і Compare         і   і GetItem         і
     і IndexOf         і   і PutItem         і
     і KeyOf           і   АДДДДДДДДДДДДДДДДДЩ
     і Search          і
     і Store           і
     АДДДДДДДДДДДДДДДДДЩ

     TStrCollection -   это    простой    производный    из
TSoortedCollection тип,  реализующий отсортированный список
строк ASCII. Метод TStrCollection.Compare переопределен для
обеспечения обычного упорядочивания строк ASCII.  Вы можете
переопределить метод Compare для  задания  другого  порядка
(например, алфавитного порядке нелатинских символов).
                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.


                Compare (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Compare(Key1,   Key2:   Pointer):    Integer;
virtual;

     Сравнивает строки Key1^ и Key2^ и возвращает -1,  если
Key1 < Key2; 0, если Key1 = Key2 и 1, если Key1 > Key2.

     См. также: TSortedCollection.Search.


                FreeItem (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure FreeItem(Item: Pointer); virtual;

     Удаляет строку  Item^  из  отсортированного  набора  и
уничтожает ее.


                 GetItem (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetItem(var S: TStream): Pointer; virtual;

     По умолчанию   считывает  строку  из  потока,  вызывая
S.ReadStr.

     См. также: TStream.ReadStr.


                 PutItem (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure PutItem(var  S:  TStream;  Item:   Pointer);
virtual;

     По умолчанию записывает строку Item^ в поток,  вызывая
S.WriteStr.

     См. также: TStream.WriteStr.


TStream                                       метод Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject    TStream
     ЪДДДДДДї   ЪДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ   і Status          і
     іДInitДі   і ErrorInfo       і
     іДDoneДі   ГДДДДДДДДДДДДДДДДДґ
     і Free і   і CopyFrom        і
     АДДДДДДЩ   і Error           і
                і Flush           і
                і Get             і
                і GetPos          і
                і GetSize         і
                і Put             і
                і Read            і
                і ReadStr         і
                і Reset           і
                і Seek            і
                і StrRead         і
                і StrWrite        і
                і Truncate        і
                і Write           і
                і WriteStr        і
                АДДДДДДДДДДДДДДДДДЩ

     TStream - это общий абстрактный объект, обеспечивающий
полиморфический ввод-вывод в/на  устройство.  Переопределяя
виртуальные методы GetPos,  GetSize, Read, Seek, Truncate и
Write,  вы можете создать собственные производные потоковые
объекты.  Сама ObjectWindows делает это,  строя производные
объекты  TDosSteram  и  TEmsStream.  Для   буферизированных
производных   потоков   вы   должны   также  переопределить
TStream.Flush.



                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                     Status (чтение/запись)

     Status: Integer;

     Status указывает  текущее состояние потока,  используя
одну  из  констант  stXXXX:  stOk,  stError,   stInitError,
stReadError, stWriteError, stGetError или stPutError.

     Если Status  не равно stOk,  то все операции с потоком
приостанавливаются до вызова Reset.

     См. также: константы stXXXX.



                    ErrorInfo (чтение/запись)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ErrorInfo: Integer;

     ErrorInfo содержит  дополнительную  информацию,  когда
Status  не  равно  stOk.  Для  значений   Status   stError,
stInitError,  stReadError и stWriteError ErrorInfo содержит
код ошибки DOS или EMS (если  он  доступен).  Когда  Status
имеет значение stGetError, ErrorInfo содержит идентификатор
объектного    типа    (поле    ObjType    в     TStreamRec)
незарегистрированного  типа  объекта.  Когда  Status  равно
stPutError,  ErrorInfo содержит  смещение  сегмента  данных
таблицы  виртуальных  методов  (поле  VmLink  в TStreamRec)
незарегистрированного типа объекта.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются методы, определенные в данном объекте.


                             CopyFrom
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure CopyFrom(var S: TStream; Count: Longint);

     Копирует Count байт  из  потока  S  в  объект  потока.
Например:

     { создать копию всего потока }
    NewStream := New(TEmsStream, Init(oldStream^.GetSize));
    OldStream^.Seek(0);
    NewStream^.CopyFrom(OldStream, OldStream^.GetSize);

     См. также: TStream.GetSize, TObject.Init.



                 Error (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Error(Code, Info: Integer); virtual;

     Вызывается, когда   происходит   ошибка   потока.   По
умолчанию TStream.Error  сохраняет  Code  и  Info  в  полях
Status  и  ErrorInfo,  а затем,  если глобальная переменная
StreamError не равна nil,  вызывает процедуру,  на  которую
указывает StreamError. Если происходит ошибка, все операции
с потоком приостанавливаются до вызова Reset.

     См. также: TStream.Reset, переменную StreamError.



                 Flush (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Flush; virtual;

     Сбрасывает все  буферы путем очистки буфера чтения или
записи   буфера   записи   (или   обоих).   По    умолчанию
TStream.Flush  ничего не делает и должна переопределяться в
наследующих типах, где реализуются буферы.

     См. также: TBufStream.Flush.


                               Get
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Get: PObject;

     Считывает объект  из  потока.   Объект   должен   быть
предварительно  записан  в  поток методом TStream.Put.  Get
сначала считывает из потока идентификатор  объектного  типа
(слово).  Затем  она находит соответствующий объектный тип,
сравнивая    идентификатор    с    полем    ObjType    всех
зарегистрированных объектных типов (см.  тип TStreamRec), и
наконец вызывает конструктор Load этого объектного типа для
создания  и  загрузки  объекта.  Если считываемый из потока
объектный тип равен 0,  Get возвращает указатель nil.  Если
указатель  объектного  типа  не  зарегистрирован (с помощью
RegisterType),  Get  вызывает  TStream.Error  и  возвращает
указатель nil.  В противном случае Get возвращает указатель
на вновь созданный объект.

     См. также:  TStream.Put,   RegisterType,   TStreamRec,
методы Load.

                 GetPos (всегда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetPos: Longint; virtual;

     Возвращает значение  текущей   позиции   потока.   Это
абстрактный метод, который должен переопределяться.

     См. также: TStreamSeek.


                GetSize (всегда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetSize: Longint; virtual;

     Возвращает общий размер потока. Это абстрактный метод,
который должен переопределяться.


                               Put
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Put(P: PObject);

     Записывает объект  в  поток.  Позднее   объект   может
считываться из потока с помощью TStreamGet.Get. Put сначала
находит запись регистрации типа объекта, сравнивая смещение
таблицы  виртуальных  методов  объекта с полем WmtLink всех
зарегистрированных объектных типов  (см.  тип  TStreamRec),
затем  записывает  в  поток идентификатор тип объекта (поле
ObjType записи  регистрации)  и,  наконец,  вызывает  метод
Store  этого  объектного  типа  для  записи  объекта.  Если
передаваемый в Put аргумент  имеет  значение  nil,  то  Put
записывает в поток слово,  содержащее 0. Если объектный тип
P не зарегистрирован (с помощью RegisterType), Put вызывает
TStreamError и с потоком ничего не делает.

     См. также:     методы     TStreamGet,    RegisterType,
TStreamRec, Store.


                  Read (всегда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Read(var Buf; Count; Word); virtual;

     Считывает из потока Stream  Count  байт  и  продвигает
текущую позицию потока на Count байт.  В случае ошибки Read
вызывает Error и заполняет Buf Count нулевыми байтами.  Это
абстрактный   метод,   который  должен  переопределяться  в
наследующих типах.

     См. также: TStream.Write, TStream.Error.


                             ReadStr
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function ReadStr: PString;

     Считывает строку  из   текущей   позиции   в   потоке,
возвращая указатель PString.  TStream.ReadStr для выделения
для строки Length + 1 байт вызывает GetMem.

     См. также: TStream.WriteStr.


                              Reset
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Reset;

     Сбрасывает для   потока   любой   ошибочное   условие,
устанавливая  Status и ErrorInfo в 0.  Этот метод позволяет
вам продолжить работу с потоком после  исправления  условия
ошибки.

     См. также:   TStream.Status,  TStream.ErrorInfo,  коды
ошибок stXXXX.

                  Seek (всегда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Seek(Pos: Longint); virtual;

     Устанавливает текущую  позицию  в  Pos  байт от начала
потока.  Начальной  позицией   потока   является   0.   Это
абстрактный метод,  который должен переопределяться во всех
потомках.

     См. также: TStream.GetPos.


                             StrRead
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function StrRead: PChar;

     Считывает из  потока  строку  с   завершающим   нулем,
считывая  сначала  длину  строки,  а  затем  заданное число
символов.  Возвращает указатель  на  прочитанную  строку  с
завершающим нулем.

     См. также: TStream.StrWrite.

                            StrWrite

     procedure StrWrite(P: PChar);

     Записывает в   поток   строку   с  завершающим  нулем,
записывая сначала длину  строки,  а  затем  заданное  число
символов.

     См. также: TStream.StrWrite.


                Truncate (всегда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Trancate: virtual;

     Удаляет все  данные  из  потока  от текущей позиции до
конца.    Это    абстрактный    метод,    который    должен
переопределяться во всех потомках.

     См. также: TStream.GetPos, TStream.Seek.


                 Write (всегда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Write(var Buf; Count: Word); virtual;

     Записывает Count  байт  из  Buf  в  потоки  продвигает
текущую позицию в потоке на Count  байт.  В  случае  ошибки
Write вызывает Error. Это абстрактный метод, который должен
переопределяться во всех потомках.

     См. также: TStream.Read, TStream.Error.


                             WriteStr
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WriteStr(P: PString);

     Записывает строку  P^  в  поток,  начиная  с   текущей
позиции.

     См. также: TStream.ReadStr.


Тип TStreamRec                               модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание:

     TStreamRec = record
          ObjType: Word;
          VmtLink: Word;
          Load: Pointer;
          Store: Pointer;
          Next: Word;
     end;

     Назначение: Перед   тем   как   все  его  типы  смогут
загружаться из объекта TStream  или  записываться  в  него,
объектный тип ObjectWindows должен иметь зарегистрированный
тип  TStreamRec.  Подпрограмма  RegisterTypes  регистрирует
объектный тип, устанавливая запись TStreamRec.

  Поля в записи регистрации определены следующим образом:

                Поля записи потока           Таблица 21.27
ДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
 Поле      і                    Содержимое               і
ДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ObjType    і Уникальный числовой идентификатор объектногоі
           і типа.                                       і
ДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
VmtLink    і Связь с записью таблицы виртуальных  методові
           і объектного типа.                            і
ДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
Load       і Указатель на конструктор Load объектного ти-і
           і па.                                         і
ДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
Store      і Указатель на метод Store объектного типа.   і
ДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
Next       і Указатель на следующую запись TStreamRec.   і
ДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     ObjectWindows резервирует   идентификаторы   объектных
типов (ObjType)  со  значением  от  0  до  999  для  своего
внутреннего  использования.  Программисты  могут определять
свои собственные значения в диапазоне от 1000 до 65535.

     По соглашению TStreamRec  для  объектного  типа  Txxxx
называется  Rxxxx.  Например,  как показано ниже TStreamRec
для типа TCalculator называется RCalculator:

     type TCalculator = object(TDialog)
            constructor Load(var S: TStream);
            procedure Store(var S: TStream);
              .
              .
              .
           end;

     const
       RCalculator: TStreamRec = (
           ObjType: 2099;
           VmtLink: Ofs(TypeOf(TCalculator)^);
           Load: @TCalculator.Load;
           Store: @TCalculator.Store);

     begin
       RegisterType(RCalculator);
        .
        .
     end;

     См. также: RegisterType.


TStringLookupValidator                      модуль Validate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TValidator           TPXPictureValidator
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і Options         і  ГДДДДДДДДДДДДДДДДДґ
     іДInitДі  і Status          і  і IsValid         і
     іДDoneДі  ГДДДДДДДДДДДДДДДДДґ  іДLookupДДДДДДДДДДі
     і Free і  іДInitДДДДДДДДДДДДі  АДДДДДДДДДДДДДДДДДЩ
     АДДДДДДЩ  іДLoadДДДДДДДДДДДДі
               іДIsInvalidДДДДДДДі  TStringLookupValidator
               і IsValidInput    і  ЪДДДДДДДДДДДДДДДДДї
               іДStoreДДДДДДДДДДДі  і Strings         і
               і Transfer        і  ГДДДДДДДДДДДДДДДДДґ
               і Valid           і  і Init            і
               АДДДДДДДДДДДДДДДДДЩ  і Load            і
                                    і Done            і
                                    і Error           і
                                    і Lookup          і
                                    і NewStringList   і
                                    і Store           і
                                    АДДДДДДДДДДДДДДДДДЩ

     Объект проверки допустимости с помощью просмотра строк
TStringLookupValidator проверяет данные  в  соответствующей
строке ввода путем просмотра набора допустимых строк.  Если
в строке ввода вам требуются только строки из определенного
набора строк, вы можете использовать данные объекты.


                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Strings: PStringsCollection;

     Указывает на  набор  строк,  содержащий все допустимые
строки,  которые может набирать пользователь.  Если Strings
имеет значение nil, все строки будут недопустимыми.

                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже перечисляются  методы,  содержащиеся   в   данном
объекте.

                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AStrings: PStringCollection);

     Строит объекты  проверки  допустимости  с   просмотром
строк,  вызывая  сначала  конструктор Init,  наследуемый из
TLookupValidator, а затем устанавливая Strings в AStrings.

     См. также: TLookupValidator.Init.

                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и  загружает  объекты  проверки  допустимости с
просмотром строк из потока S,  вызывая сначала  конструктор
Load,  наследуемый  из  TLookupValidator,  а затем считывая
набор строк Strings.

     См. также: TLookupValidator.Load.

                               Done
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done; virtual;

     Уничтожает список     допустимых     строк,    вызывая
NewString(nil),  а   затем   уничтожает   объект   проверки
допустимости  с  просмотром  строк путем вызова деструктора
Done, наследуемого из TLookupValidator.

     См. также:                      TLookupValidator.Done,
TStringLookupValidator.NesStringList.


                              Error
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Error; virtual;

     Выводит блок  сообщения,  указывающий,  что  набранная
строка не совпадает с записью в списке строк.


                              Lookup
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Lookup(const S: string): Boolean; virtual;

     Возвращает True,  если переданная в S строка совпадает
с  какой-либо  из  строк в наборе Strings.  Для определения
присутствия S использует метод Search набора строк.


                          NewStringList
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure NewStringList(AStrings: PStringCollection;

     Устанавливает для  объекта  проверки  допустимости   с
просмотром строк список допустимых строк ввода.  Уничтожает
любой существующий  список  строк,  а  затем  устанавливает
Strings  в  AStrings.  Передача  в  AStrings  значения  nil
уничтожает существующий список, не присваивая новый.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Store(var S: TStream);

     Записывает объект проверки допустимости  с  просмотром
строк в потоке S,  вызывая сначала метод Store, наследуемый
из TValidatos,  а затем записывая  содержащийся  в  Strings
набор строк.


TValidator                                  модуль Validate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TValidator
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і Options         і
     іДInitДі  і Status          і
     і Done і  ГДДДДДДДДДДДДДДДДДґ
     і Free і  і Init            і
     АДДДДДДЩ  і Load            і
               і IsInvalid       і
               і IsValidInput    і
               і Store           і
               і Transfer        і
               і Valid           і
               АДДДДДДДДДДДДДДДДДЩ

     TValidator определяет   объект  проверки  допустимости
абстрактных  данных.  На  самом   деле   вам   никогда   не
потребуется   создавать   экземпляры   TValidator,   но  он
обеспечивает  абстрактные  функции  для   других   объектов
проверки допустимости.


                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                             Options

     Options: Word;

     Options -   это   поле   с   побитовым   отображением,
используемое в различных потомках TValidator.  По умолчанию
TValidator.Init очищает все биты в Options.

     См. также: константы voXXXX.


                              Status
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Status: Word;

     Status указывает     состояние     объекта    проверки
допустимости.  Если значение Status равно vsOK,  то  объект
проверки  допустимости строится корректно.  Любое значение,
отличное от vsOK, указывает, что произошла ошибка.

     См. также: TInputLine.Valid, константы ValidatorOK.



                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже перечисляются   методы,   содержащиеся  в  данном
объекте.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init;

     Строит абстрактный   объект   проверки   допустимости,
вызывая сначала конструктор Init, наследуемый из TObject, а
затем устанавливая поля Options и Status в значение 0.

     См. также: TObject.Init.

                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     constrictor Load(var S: Stream);

     Строит объект    проверки    допустимости,     вызывая
конструктор Init, наследуемый из TObject, а затем считывает
из потока S слово Options.

     См. также: TObject.Init.


                              Error
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     propcedure Error; virtual;

     Error -  это  абстрактный метод,  вызываемый Valid при
обнаружении ввода пользователем недопустимой информации. По
умолчанию TValidator.Error ничего не делает, но наследующие
типы могут переопределять Error  для  обеспечения  обратной
связи с пользователем.


                             IsValid
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     function IsValid(const S: string): Boolean; virtual;

     По умолчанию   TValidator.IsValid   возвращает   True.
Наследующие типы проверки допустимости могут переопределять
IsValid для проверки данных в  полной  строке  ввода.  Если
строка   ввода   имеет   соответствующий   объект  проверки
допустимости,  то его  метод  Valid  вызывает  метод  Valid
объекта  проверки  допустимости,  который,  в свою очередь,
вызывает IsValid для определения допустимости строки  ввода
IsValid.

     См. также: TInputLine.Valid, TValidator.Valid.


                           IsValidInput
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     function IsValidInput(var  S:  string;   SuppressFill:
                           Boolean): Boolean; virtual;

     Если строка   ввода   имеет   соответствующий   объект
проверки допустимости,  то  IsValidInput  вызывается  после
обработки  каждого  клавиатурного  события.  Это дает таким
средствам проверки  допустимости  как  фильтры  возможность
перехватывать  ошибки перед тем,  как пользователь заполнит
весь элемент на экране.

     По умолчанию  TValidator.IsInput  возвращает  значение
True.  Наследующие  объекты  проверки  допустимости  данных
могут переопределять IsValidInput для проверки допустимости
набираемых  пользователем  данных,  возвращая True,  если S
содержит допустимые данные, и False в противном случае.

     S - это текущая строка ввода.  SupressFill определяет,
будет   ли   объект   проверки  допустимости  автоматически
форматировать строку перед ее проверкой.  Если  SupressFill
имеет  значение True,  то проверка допустимости выполняется
для немодифицированной строки  S.  Если  SupressFill  имеет
значение  False,  то  перед  проверкой  допустимости данных
средство  проверки  допустимости   должно   заполнить   или
дополнить   строку.   Из   стандартных   объектов  проверки
допустимости       SupressFill       проверяет       только
TPXPictureValidator.

     Так как  S  -  это  параметр-переменная,  IsValidInput
может  модифицировать  содержимое  строк  ввода,  например,
преобразовывать  символы  в  верхний  регистр или вставлять
литеральные символы из  трафарета  формата.  Однако,  метод
IsValidInput  не  должен  удалять  из  строки  недопустимых
символов. Возвращая значение False, IsValidInput указывает,
что в строке ввода следует стереть неверные символы.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Store(var S: TStream);

     Записывает объект  проверки  допустимости  в  поток S,
записывая значение поля Options.


                             Transfer
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     function Transfer(var   S:  String;  Buffer:  Pointer;
                       Flag: TVTransfer): Word; virtual;

     Позволяет объекту  проверки  допустимости  на   основе
установленных  значений  считывать соответствующие значения
строки ввода,  которые наиболее полезны в объектах проверки
допустимости,  проверяющих  нестроковые  данные  (такие как
числовые значения).  Например,  TRAngeValidator  использует
Transfer  вместо  передачи целой строки для чтения и записи
значений типа Longint в запись данных.

     По умолчанию строки  ввода  с  проверкой  допустимости
дают  сначала  объекту  проверки  допустимости  возможность
ответить на DataSize,  GetData  и  SetData,  вызывая  метод
Transfer объекта проверки допустимости. Если метод Transfer
возвращает что-либо,  отличное от 0,  это указывает  строке
ввода,    что    соответствующая    передача    обработана.
Используемым  по  умолчанию  действием  TValidator.Transfer
является  возврат  значения  0  (в  любом случае).  Если вы
хотите,  чтобы  объект  проверки   допустимости   пересылал
данные, то нужно переопределить метод Transfer.

     Первые два  параметра  Transfer  - это соответствующая
текстовая строка ввода и  запись  GetData  или  SetData.  В
зависимости от значения Flag,  Transfer может устанавливать
S из буфера Buffer или считывать в буфер Buffer  данные  из
S.  Возвращаемое  значение  всегда  равно  число переданных
данных.

     Если Flag имеет значение vtSetData, Transfer считывает
буфера Buffer в S соответствующее число байт, преобразуя их
в нужную строковую форму и возвращая число считанных  байт.
Если Flag равен vtGetData,  Transfer устанавливает значения
в Buffer, беря соответствующее число байт и преобразуя их в
нужную  строковую  форму S,  возвращая размер данных.  Если
Flag равен vtDataSize,  Transfer просто  возвращает  размер
данных.

     См. также:   TInputLine.DataSize,  TInputLine.GetData,
TInputLine.SetData.


                              Valid
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Valid(const S: string): Boolean;

     Возвращает True,  если IsValid(S) возвращает  значение
True.  В  противном  случае  вызывает  Error  и  возвращает
значение False.  Метод Valid объекта проверки  допустимости
вызывается методом Valid соответствующей строки ввода.

     Строки ввода  и  связанные  с  ними  объекты  проверки
допустимости  вызывают   метод   Valid   объекта   проверки
допустимости  при  двух условиях:  когда установлена строка
ввода или ее параметр ofValidarte (в этом случае при вызове
Valid   теряется   фокус   ввода),  либо  диалоговый  блок,
содержащий строку ввода,  вызывает  метод  Valid  для  всех
своих   управляющих   элементов  (обычно  из-за  того,  что
пользователь требует закрыть  диалоговый  блок  или  ввести
запись с экрана).

     См. также:     TInputLine.Valid,     TValidator.Error,
TValidator.IsValid.

Тип TVTransfer                              модуль Validate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: TVTransfer   =    (vtDataSize,    vtSetData,
vtGetData);

     Назначение: Объекты  проверки  допустимости используют
параметры типа TVTransfer  в  своих  методах  Transfer  для
управления  передачей  данных  при установке или считывании
значения из соответствующей строки ввода.

     См. также: TValidator.Transfer.

Тип TWndClass                               модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание:

     TWndClass = record
        style: Word;
        lpfnWndProc: TFarProc;
        cbClsExtra: Integer;
        cbWndExtra: Integer;
        hInstance: THandle;
        hIcon: HIcon;
        hCursor: HCursor;
        hbrBackGround: HBrush;
        lpszMenuName: PChar;
        lpszClassName: PChar;
     end;

     Назначение: Запись TWndClass содержит атрибуты  класса
окна,    известные    также   как   атрибуты   регистрации,
зарегистрированные с помощью функции RegisterClass.

     Поле style содержит стиль класса - одну из  комбинаций
констант стиля класса cs_.

     Поле lpfnWndProc  указывает  на оконную функцию окна -
подпрограмму, которая получает и обрабатывает сообщения.

     cbClsExtra - это число байт, которые должны выделяться
в  конце  записи TWndClass.  Они называются дополнительными
байтами класса и доступны с помощью функций GetWindowLong и
GetWindowWord.   Установить  их  можно  с  помощью  функций
SetWindowLong и SetWindowWord.

     cbWndExtra дает  число  байт,   выделенных   в   конце
экземпляра окна.

     hInstance -  это описатель экземпляра,  который должен
указывать на модуль класса. Он должен быть ненулевым.

     Поля hIcon,  hCursor и hbrBackGround -  это  описатели
пиктограммы,   курсора   класса  и  фонового  цвета  класса
соответственно.   В   качестве   фонового   цвета    должно
указываться  значение  цвета (один из стандартных системных
цветов,  заданный константой color_,  увеличенный на 1) или
описатель  кисти  для  раскраски  фона.  Если hbgBackGround
равно  0,  то  фон  приложения  должен  раскрашиваться  при
раскраске   области   клиента.  Необходимость  этого  можно
определить обработкой сообщения wm_EraseBkgnd или проверкой
поля fErase записи TPaintStruct, созданной BeginPaint.

     Поля lpszMenuName  и lpszClassName указывают на строки
с завершающим нулем,  представляющими,  соответственно, имя
ресурса меню класса и имя класса.

     См. также: TWindowsObject.GetWindowClass.



TWindow                                     модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДД        GetChildren        і
               іДLoadДДДДДДДД       ДGetClassNameДДДДДДДі
               і Done                GetClient          і
               і AddChild           ДGetIdДДДДДДДДДДДДДДі
               і At                  GetSiblingPtr      і
               і Canclose           ДGetWindowClassДДДДДі
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               іДCreateДДДДДД        Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc     ДRegisterДДДДДДДДДДДі
               і DefNotificationProc RemoveChild        і
               іДDefWndProcДД        SetFlags           і
               і Destroy            ДSetupWindowДДДДДДДДі
               і Disable             Show               і
               і DisableAutoCreate  ДStoreДДДДДДДДДДДДДДі
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable             ДWMActivateДДДДДДДДДі
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat          ДWMNScrollДДДДДДДДДДі
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr        ДWMVScrollДДДДДДДДДДі
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


     TWindow
     ЪДДДДДДДДДДДДДДДДДДДї
     і Attr              і
     і DefaultProc       і
     і Scrol[ler         і
     і FocusChildHandle  і
     ГДДДДДДДДДДДДДДДДДДДґ
     і Init              і
     і InitResource      і
     і Load              і
     і Done              і
     і Create            і
     і DefWndProc        і
     і FocusChild        і
     і GetId             і
     і GetWindowClass    і
     і Paint             і
     і SetCaption        і
     і SetupWindow       і
     і Store             і
     і UpdateFocusChild  і
     і WMActivate        і
     і WMHScroll         і
     і WMLButtonDown     і
     і WMMDIActivate     і
     і WMMove            і
     і WMPaint           і
     і WMSize            і
     і WMSysCommand      і
     і WMVScroll         і
     АДДДДДДДДДДДДДДДДДДДЩ

     TWindow определяет  фундаментальное поведение для всех
окон и объектов управляющих элементов.  Экземпляры объектов
TWindow  -  это просто общие окна,  но они могут включать в
себя меню, курсоры и пиктограммы.


                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                      Attr (чтение/запись)

     Attr: TWindowAttr;

     Attr содеpжит запись TWindowAttr,  котоpая  опpеделяет
атpибуты   создания  окон  -  хаpактеpистики,  влияющие  на
создание соответствующего интеpфейсного  элемента  окна.  К
ним относятся текст,  стиль, pасшиpенный стиль, положение и
pазмеp,  описатель  окна   и   идентификатоp   управляющего
элемента.   Эти   атрибуты   устанавливаются  по  умолчанию
конструктором   Init,   но   могут    переопределяться    в
конструкторах наследующих типов.

     См. также: тип TWindowAttr.

                   DefaultProc (только чтение)

     DefaultProc: TFarProc;

     DefaultProc содержит  адрес  используемой по умолчанию
процедуры окна, которая определяет применяемую по умолчанию
обработку сообщений Windows.

                FocusChildHandle (только чтение)

     FocusChildHandle: THandle;

     FocusChildHandle cодеpжит описатель дочеpнего окна для
данного окна,  котоpое было активно в  момент,  когда  окно
активизиpовалось  в  последний pаз.  Windows не отслеживает
автоматически фокус дочерних окон,  так что когда вы  вновь
активизируете окно или восстанавливаете его из пиктограммы,
ObjectWindows обеспечивает восстановление фокуса  для  того
дочернего окна, где он бы в последний раз.

     С данным  полем  вы  можете работать с помощью методов
FocusChild и UpdateFocusChild.

                    Scroller (чтение/запись)

     Scroller: PScroller;

     Scroller содеpжит  указатель  на   объект   TScroller,
котоpый используется для организации прокрутки изображения.
В конструкторе TWindow создается экземпляр объекта Scroller
и устанавливается элемент прокрутки.

                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже перечисляются  методы,  содержащиеся   в   данном
объекте.


                  Init (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AParent:   PTWindowsObject;   ATitle,
PChar);

     Создает объект окна с порождающим окном,  пеpедаваемым
в  AParent и соответствующим текстом (заголовком для окон),
пеpедаваемым  в  ATitle.  Для  основных  окон,  не  имеющих
порождающих  окон  AParent должно иметь значение nil.  Поле
Attr.Style объекта  устанавливается  в  ws_OverlappedWindow
(если  окно  не  является  порожденным  окном  MDI - в этом
случае    оно    устанавливается    в     ws_ClipSiblings).
Устанавливает  позицию  и  поля в Attr в их соответствующие
используемые  по   умолчанию   значения   для   образования
перекрывающихся и всплывающих окон.

     В конструкторе объекта, производного от TWindow (или в
любой  момент  перед  созданием  интерфейсного   элемента),
используемые  по  умолчанию  значения  структуры Attr можно
установить по-другому.  Конструктор производного от TWindow
объекта  может  также  устанавливать Scroller (по умолчанию
nil) в экземпляр объекта TScroller.


                           InitResource
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor InitResource(AParent: PWindowsObject;
                              ResourceID: Word);

     На основе   определения  ресурса  строит  интерфейсный
объект,  связанный с элементом экрана  (обычно  управляющим
элементов).     Для     построения     объекта     вызывает
TWindowsObject.Init.

     См. также: TWindowsObject.Init.


                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и загружает окно из потока S,  вызывая  сначала
TWindowsObjecrt.Load,    а   затем   считывая   и   получая
дополнительные поля (Attr и Scroller), введенные в TWindow.

     См. также: TWindowsObject.Load.


                  Done (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done; virtual;

     Перед вызовом   для    уничтожения    всего    объекта
деструктора    Done,    наследуемого   из   TWindowsObject,
уничтожает объект TScroller в Scroller (при его наличии).


                              Create
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Create: Boolean; virtual;

     Если объект не был построен с помощью InitResource  (в
этом  случае экранный элемент уже существует),  создает для
оконного объекта  соответствующий  экранный  элемент.  Если
класс  окна еще не зарегистрирован,  Create для регистрации
вызывает Register.  Затем Create создает  окно  и  вызывает
метод   SetupWindow,   который  вы  можете  определить  для
инициализации вновь созданного окна,  обычно путем создания
дочерних  окон  и изображения графики или текста.  В случае
успешного выполнения Create  возвращает  значение  True.  В
случае   неуспешного   выполнения   возвращается  False,  и
вызывается Error.

     Обычно функция   Create    никогда    не    вызывается
непосредственно.       Create       вызывается      методом
TApplication.MakeWindow, который выполняет сначала проверку
наличия памяти.

     См. также:                    TWindowsObject.Register,
TApplication.MakeWindow, TWindowsObject.SetupWindow.


             DefWndProc (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure DefWndProc(var Msg: TMessage); virtual;

     Вызывает используемую  по  умолчанию  процедуру  окна,
выполняющую   обработку   поступающих   сообщений  Windows.
Результат этого вызова сохраняется  в  поле  Result  записи
сообщения Msg.


                            FocusChild
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure FocusChild;

     Вызывается WMActivate  и  WMSysCommand  для  установки
фокуса   ввода    на    дочернем    окне    с    описателем
FocusChildHandle.

     См. также: TWindow.WMActive, TWindow.WMSysCommand.


                  GetID (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetID: Integer; virtual;

     Возвращает идентификатор окна (такой как идентификатор
управляющего элемента).


             GetWindowClass (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure GetWindowClass(var  AWndClass:   TWndClass);
            virtual; protected
     Заполняет структуру класса окна, задаваемую AWndClass,
соответствующим    TWindow   используемыми   по   умолчанию
атрибутами.   Поле   стиля   устанавливается   в   значение
cs_HRedraw  или  cs_VRedraw.  Пиктограмма устанавливается в
общую пиктограмму, курсор принимает форму в виде стрелки, а
фоновый  цвет  становится  равным фоновому цвету системного
окна.  Имя регистрируемого класса можно получить с  помощью
вызова GetClassName.

     См. также:                TWindowsObject.GetClassName,
TWindowObject.Register, TWindow.Create.


                  Paint (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     procedure Paint(PaintDC:     HDC;    var    PaintInfo:
                     TPaintStruct); virtual;

     Служит меткой-заполнителем  для   поpожденных   типов,
котоpые    опpеделяют   метод   Paint.   Paint   вызывается
автоматически в ответ на запpос от Windows  для  повтоpного
отобpажения содеpжимого окна.  PaintDC следует использовать
как контекст дисплея.  Он всегда получается до вызова Paint
и освобождается после Paint. Пеpеданная стpуктуpа pаскpаски
PaintInfo содеpжит инфоpмацию непосpедственно о запpосе  на
отображение.

     См. также: TWindow.WMPaint.


                            SetCaption
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     procedure SetCaption(ATitle: PChar);

     Уничтожает текст  в  поле  Attr.Title  окна,   вызывая
StrDispose,  а  затем  вызывает  StrNew для выделения новой
копии  строки  в  ATitle  для  Attr.Style.  Для  обновления
заголовка окна вызывает функцию API SetWindowText.

               SetupWindow (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetupWindow: virtual;

     Устанавливает вновь созданное окно. Если окно является
дочерним  окном  MDI,  то SetupWindow вызывает SetFocus для
передачи  фокуса  новому  окну.  Если  окно  имеет   объект
прокрутки,  SetupWindow  вызывает  для  установки диапазона
полос прокрутки SetBarRange.

     См. также: TScroller.SetBarRange.


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     procedure Store(var S: TStream);

     Сохраняет окно    в    потоке   S,   вызывая   сначала
TWindowsObject.Store,   а   затем   записывая   и   помещая
дополнительные поля (Attr и Scroller), введенные в TWindow.

     См. также: TWindowsObject.Store.

                         UpdateFocusChild
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     procedure UpdateFocusChild;

     Устанавливает FocusChildHandle  в  описатель дочернего
окна, имеющее в данный момент фокус ввода.

     См. также: TWindow.FocusChildHandle.

               WMActivate (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMActivate(var Msg: TMessage) virtual
                          vm_First + vm_Activate;

     Для окон,  которые перехватывают для своих управляющих
элементов  сообщения  от клавиатуры,  реагирует на потерю и
получение окном фокуса путем сохранения описателя дочернего
управляющего элемента,  который в данный момент имеет фокус
в FocusChildHandle, и восстанавливает фокус.

     См. также: TWindowsObject.EnableKBDriver.

                             WMCreate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMCreate(var Msg: TMessage); virtual
                        wm_First + wm_Create;

     Отвечает на сообщение wm_Create  вызовом  SetupWindow,
после  чего вызывает DefWntProc.  Поскольку создание окна в
ObjectWindows выполняется иначе чем  в  Windows,  сообщение
wm_Create  нужно перехватывать и использовать для установки
атрибутов окна.

     См. также: TWindow.SetupWindow.


               WMHScroll (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMHScroll(var Msg: TMessage); virtual
                         wm_First + wm_HScroll;

     Для окон  с  пpокpуткой  на  события  в гоpизонтальной
полосе пpокpутки окна отвечает вызовом  методов  HScroll  и
DefWndProc объекта прокрутки HScroll.

     См. также: TScroller.HScroll.


             WMLButtonDown (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMLButtonDown(var Msg: TMessage); virtual
                             vmFirst + wm_LButtonDown;

     Этот метод при автоматической  прокрутки  отвечает  на
нажатие левой кнопки "мыши", перехватывая весь будущий ввод
от "мыши",  пока левая кнопка "мыши" не будет  освобождена.
Если  вы  планируете  для  обработки  нажатий кнопок "мыши"
переопределить  данный  метод,  но  все  равно  собираетесь
пользоваться автоматической прокруткой, убедитесь, что этот
метод вызывается из вашего метода WMLButtonDown.


                          WMMDIActivate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure TWindow.WMMDActivate(var   Msg:   TMessage);
                                    virtual    wm_First   +
                                    wm_MDIActivate;

     Вызывая WMActivate,   управляется   активизацией   MDI
Windows.

     См. также: TWindow.WMActivate.


                              WMMove
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMMove(var Msg: TMessage); virtual
                      wm_First + wm_MDIActivate;

     При получении сообщения wm_Move  обновляет  координаты
Attr.X  и  Attr.Y.  Если  окно  имеет  вид  пиктограммы или
минимизировано, то это сообщение игнорируется.


                 WMPaint (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMPaint(var Msg: TMessage); virtual
                       wm_First + wm_Paint;

     Отвечает на сообщение Windows wm_Paint,  вызывая метод
Paint оконного объекта.  Если окно имеет полосу  прокрутки,
перед  вызовом  Paint  WMPaint вызывает BeginView,  а после
вызова - EndView.

     См. также:      TWindow.Paint,      TScroller.EndView,
TScroller.BeginView.

                 WMSize (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMSize(var Msg: TMessage); virtual
                      wm_First + wm_Size;

     Для окон  с  пpокpутками на события изменения pазмеpов
окна отвечает  вызовом  SetPageSize  для  установки  нового
pазмеpа окна.

     См. также: TScroller.SetPageSize.


                           WMSysCommand
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMSysCommand  TWindow.WMSysCommand(var  Msg:
                     TMessage); virtual wm_First +
wm_SysCommand;

     Если окно   обрабатывает   ввод  с  клавиатуры,  перед
вызовом  DefWndProc  для  выполнения  нормальной  обработки
проверяет  поле  wParam  на  два значения.  Если Msg.wParam
равно sc_Mininize (это означает,  что окно  будет  сжато  в
пиктограмму),   вызывает   перед   сжатием   в  пиктограмму
UpdateFocusChild.   Если   Msg.wParam   равно   sc_Restore,
WMSysCommand вызывает для восстановления фокуса ввода перед
восстановлением окна FocusChild.

     См. также:                         TWindow.FocusChild,
TWindow.UpdateFocusChild.


               WMVScroll (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMVScroll(var Msg: TMessage); virtual
                         wm_First + wm_VScroll;

     Для окон с объектами  прокрутки  отвечает  на  события
вертикальной  полосы  прокрутки  вызовом  метода DefWndProc
объекта VScroll.

     См. также: TScroll.DefWndProc.


Тип TWindowAttr                             модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание:

     TWindowAttr = record
           Title: PChar;
           Style: Longint;
           ExStyle: Longint;
           X, Y, W, H: Integer;
           Param: Pointer;
           case Integer of
       0: (Menu: HMenu);     { обработка меню окна или ...
       1: Id: Integer);      { идентификатор управляющего
                                      элемента }
     end;

     Назначение: В  записях  TWindowAtt   определяет   свои
атрибуты объекта TWindow.

     См. также: TWindowAttr.


TWindowPrintout                             модуль OPrinter
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TPrintout
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і Banding         і
     іДInitДі  і DC              і
     іДDoneДі  і ForceAllBands   і
     і Free і  і Size            і
     АДДДДДДЩ  і Title           і
               ГДДДДДДДДДДДДДДДДДґ
               іДInitДДДДДДДДДДДДі
               і Done            і
               і BeginDocument   і
               і BeginPrinting   і
               іДGetDialogInfoДДДі
               і GetSelection    і
               і HasNextPage     і
               іДPrintPageДДДДДДДі
               і SetPrintParams  і
               АДДДДДДДДДДДДДДДДДЩ

     TWindowPrintout обеспечивает    объект     распечатки,
упрощенный для печати содержимого окна.



                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                              Scale

     Scale: Boolean;

     Имеет значение   True,    если    распечатка    должна
масштабировать образ для заполнения страницы.  По умолчанию
TWindowPrintout.Init устанавливает Scale в значение True.

                             Window

     Window: PWindow;

     Window указывает на распечатываемое окно.


                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются методы объекта распечатки.


                               Init
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(ATitle: PChar; AWindow: PWindow);

     Строит объект   распечатки   окна,   вызывая   сначала
конструктор   Init,  наследуемый  из  TPrintout,  передавая
ATitle,  а  затем   устанавливая   Window   в   AWindow   и
устанавливая Scale в значение True.

     См. также: TPrintout. Init.


                          GetDialogInfo
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetDialogInfo(var Pages: Integer): Boolean;
                            virtual;

     Устанавливает Pages в 0 и возвращает  False,  так  как
окно   генерирует  только  одну  страницу  распечатки.  Это
предотвращает вывод диалога печати.


                            PrintPage
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure PrintPage(Page: Word; var Rect: TRect;
                         Flags: Word); virtual;

     Масштабирует для  окна  контекст  устройства,  так что
распечатка будет иметь правильный вид,  а затем для  вывода
образа окна в контекст устройства вызывает метод Paint.


TWindowsObject                              модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TObject   TWindowsObject
     ЪДДДДДДї  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     ГДДДДДДґ  і ChildList           Parent             і
     іДInitДі  і Flags               Status             і
     іДDoneДі  і HWindow             TransferBuffer     і
     і Free і  і Instance                               і
     АДДДДДДЩ  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
               і Init                GetChildren        і
               і Load                GetClassName       і
               і Done                GetClient          і
               і AddChild            GetId              і
               і At                  GetSiblingPtr      і
               і Canclose            GetWindowClass     і
               і ChildWithId         IndexOf            і
               і CloseWindow         IsFlagSet          і
               і CMExit              Next               і
               і Create              Previous           і
               і CreateChildren      PutChildPtr        і
               і CreateMemoryDC      PutChildren        і
               і DefChildProc        PutSiblingPtr      і
               і DefCommandProc      Register           і
               і DefNotificationProc RemoveChild        і
               і DefWndProc          SetFlags           і
               і Destroy             SetupWindow        і
               і Disable             Show               і
               і DisableAutoCreate   Store              і
               і DisableTransfer     Transfer           і
               і DispatchScroll      TransferData       і
               і Enable              WMActivate         і
               і EnableAutoCreate    WMClose            і
               і EnableKBHandler     WMCommand          і
               і EnableTransfer      WMDestroy          і
               і FirstThat           WMNScroll          і
               і Focus               WMNCDestroy        і
               і ForEach             WMNQueryEndSession і
               і GetChildPtr         WMVScroll          і
               АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     TWindowsObject определяет   фундаментальное  поведение
всех интерфейсных объектов,  включая окна, диалоговые блоки
и  управляющие  элементы.  TWindowsObject - это абстрактный
объект,  производный от Object, и его методы полезны только
для  наследующих  типов.  Методы  TWindowsObject  реализуют
фундаментальное создание элементов экрана и действия по  их
уничтожению,   поведение  при  регистрации  класса  окна  и
механизм автоматического ответа на сообщения.


                               Поля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                    ChildList (только чтение)

     ChildList: PWindowsObject;

     ChildList -  это  связанный   список   всех   объектов
дочерних окон интерфейсного объекта,  таких как всплывающие
окна,  диалоговые блоки и управляющие  элементы.  ChildList
всегда указывает на последний добавленный объект.

                      Flags (чтение/запись)

     Flags: Byte;

     Flags -  это  байт данных,  биты которого используются
для записи следующих атрибутов окна:  обработки клавиатуры,
автоматического создания,  передачи, статуса MDI и создания
ресурса.  Flags  содержит  одну  или  более  констант   wb_
(которые описываются в данной главе).

     См. также:                    TWindowsObject.SetFlags,
TWindowsObject.ISFlagSet.

                     HWindow (только чтение)

     HWindow:; HWnd;

     HWindow содержит описатель связанного  с  интерфейсным
объектом  интерфейсного элемента.  Если HWindow содержит 0,
то  значение  является  недопустимым  описателем.   HWindow
устанавливается   в   описатель   связанного  интерфейсного
элемента  при  его  создании  (Create)  и  обнуляется   при
уничтожении интерфейсного элемента (WMNCDestroy).

                     Parent (только чтение)

     Parent: TPWindowsObject;

     PWindowsObject указывает   на   интерфейсный   объект,
который служит порождающим окном для данного  интерфейсного
объекта.  Например, выводимое в оконном объекте поле Parent
объекта управляющего элемента  будет  указывать  на  своего
предка - оконный объект.

                     Status (чтение/запись)

     Status: Integer;

     Status используется,   чтобы   сообщить  об  ошибке  в
инициализации  интерфейсного  объекта.  Ненулевое  значение
Status указывается,  что инициализация объекта не выполнена
успешно,   отрицательное   свидетельствует    о    неудаче.
Производные  от  TWindowsObject объекты,  включая TWindow и
TDialog,  проверяют Status перед созданием  соответствующих
элементов.  Используйте Status в коде наследующих объектных
типов, чтобы отметить ошибку инициализации.

     Возможные значения     ошибки,     определенные      в
TWindowsObject,    включают    в    себя   em_InvalidWindow
(недопустимое   окно),    em_InvalidClient    (недопустимый
пользователь),  em_InvalidChild  (недопустимое  порожденное
окно) и em_InvalidMainWindow (недопустимое основное окно).

                 TransferBuffer (чтение/запись)

     TransferBuffer: Pointer;

     TransferBuffer указывает    на     буфер     передачи,
определенный приложением, использующим механизм передачи. В
противном случае это nil.

                              Методы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Ниже описываются   методы,   определенные   в   данном
объекте.

                  Init (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Init(AParent: PWindowsObject);

     Строит и     инициализирует    интерфейсный    объект.
Конструктор    наследующих    типов     должен     вызывать
TWindowsObject.Init.  Вызывает  EnableAutoCreate,  так  что
дочерние окна будут по умолчанию создаваться  и  выводиться
наряду  с их порождающими окнами.  Кроме того,  добавляет к
списку дочерних окон объекта порождающего окна интерфейсный
объект.

     См. также:            TWindowsObject.EnableAutoCreate,
TWindowsObject.AddChild.


                               Load
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     constructor Load(var S: TStream);

     Строит и загружает интерфейсный объект  из  потока  S,
считывая  Status,  другие  атрибуты  и размер ChildList,  а
затем загружая каждое дочернее окно.


                  Done (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     destructor Done; virtual;

     Уничтожает интерфейсный  объект,   уничтожая   сначала
соответствующий  интерфейсный элемент (если он имеется),  а
затем  вызывая  наследуемый  из  TObject  деструктор  Done.
Уничтожает  все свои дочерние окна и удаляет себя из списка
дочерних окон своего порождающего  окна.  Деструкторы  всех
наследующих    типов   должны   включать   в   себя   вызов
TWindowsObject.Don.


                             AddChild
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure AddChild(AChild: PWindowsObject);

     Добавляет Achild с списку дочерних окон.


                                At
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function At(I: Integer): PWindowsObject;

     Возвращает указатель на I-ое дочернее  окно  в  списке
дочерних  окон  объекта.  Список дочерних окон циклический,
так что если I больше числа дочерних окон,  то At выполняет
переход к началу списка.

                CanClose (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function CanClose: Boolean; virtual

     Для каждого дочернего окна вызывает метод  CanClose  и
возвращает False, если возвращает False какое-либо дочернее
окно, указывая, что закрыть интерфейсный элемент нельзя (не
OK).  Если  методы  CanClose  всех дочерних окон возвращают
True, то CanClose также возвращает True.


            ChildWithID (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ChildWithid(Id: Integer): PWindowsObject; virtual;

     Возвpащает указатель    на    окно    с     пеpеданным
идентификатоpом в списке дочеpних окон. Если дочеpнего окна
с указанным идентитфикатором Id нет, ChildWithid возвpащает
значение nil.  Если Id равно -1,  то ChildWithID возвращает
первый неуправляющий объект в списке дочерних окон.


                           CloseWindow
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure CloseWindow;

     Чтобы увидеть,  готово ли окно  к  закрытию,  вызывает
CanClose.  Если  метод  CanClose  возвращает значение True,
CloseWindow уничтожает объект и уничтожает  соответствующий
оконный элемент.

     См. также: TWindowObject.CanClose.


                              CMExit
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     procedure CMExit(var Msg: TMessage); virtual
                      cm_First + cm_Exit;

     Если CanCLose  возвращает True,  отвечает на командное
сообщение   cm_Exit,   прекращая   выполнение   приложения.
Сообщение   cm_Exit   обычно   посылается   основному  окну
приложения.

               Create (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     function Create: Boolean; virtual;

     Создает соответствующий экранный элемент интерфейсного
объекта.   Это   абстрактный   метод,   переопределяемый  в
наследующих типах.

                          CreateChildren
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function CreateChildren: Boolean;

     Вызывает Create  для всех дочерних окон.  CreateWindow
вызывается  SetupWindow,  так  что  вам  не  нужно   обычно
вызывать   этот   метод   непосредственно.   CreateChildren
требуется вызывать только после GetChildren  для  получения
визуальных   элементов   для   дочерних  оконных  объектов,
загружаемых из потока.

     См. также: TWindowsObject.GetChildren.

                         CreateDCMemory

     function CreateDCMemory(var Msg: TMessage); virtual;

     Создает контекст устройства памяти (DC), совместимый с
контекстом   дисплея   окна.  Значения  DC  необходимы  для
поразрядного отображения.

              DefChildProc (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     procedure DefChildProc(var Msg: TMessage); virtual

     Выполняет стандаpтную   обpаботку   для   поступающего
сообщения,  базиpующегося на идентификатоpе дочеpнего окна,
устанавливая поле Result в Msg  в  0  (это  указывает,  что
сообщение обработано не было).


             DefCommandProc (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     procedure DefCommandProc(var Msg: TMessage); virtual;

     Выполняет стандаpтную   обpаботку   для   поступающего
сообщения,  базиpующегося  на  команде,  устанавливая  поле
Result в Msg в 0 (это указывает,  что сообщение  обработано
не было).


          DefNotificationProc (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure DefNotificationProc(var    Msg:   TMessage);
virtual;

     Выполняет стандаpтную   обpаботку   для   поступающего
уведомляющего сообщения, устанавливая поле Result в Msg в 0
(это указывает, что сообщение обработано не было).


                            DefWndProc
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure DefWndProc(var Msg: TMessage); virtual;

     Эта используемая по  умолчанию  оконная  процедура  не
выполняет  никаких операций и обычно переопределяется.  Она
полагает,  что поле Result  в  Msg  остается  нулевым  (это
указывает,    что   сообщение   не   обработано).   TWindow
переопределяет  DefWndProc  для  вызова  предусмотренных  в
Windows стандартной реакции на сообщения Windows.

     См. также: TWindow.DefWndProc.


              Destroy (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Destroy; virtual;

     Вызывает уничтожение связанного элемента интеpфейсного
объекта,  удаляя его с экрана,  вызывая  получение  оконным
объектом  сообщения wm_Destroy.  Destroy вызывает также для
любого созданного дочернего окна  метод  EnableCreate.  Это
обеспечивает,  что  при  повторном  создании  объект  будет
выглядеть как в момент уничтожения.

     См. также:                   TWindowsObject.WMDestroy,
TWindowsObject.EnableAutoCreate.


                             Disable
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Disable;

     Вызывая DisableWindow,     запрещает    связанный    с
интерфейсным   объектом   экранный   элемент.   Запрещенный
экранный  элемент  обычно  выводится серым и не реагирует в
Windows на ввод с клавиатуры или от  "мыши".  Все  экранные
элементы  по  умолчанию  разрешены,  но  могут  запрещаться
вызовом Disable.

     См. также: TWindowsObject.Enable.


                        DisableAutoCreate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure DisableAutoCreate;

     Запpещает возможность, котоpая позволяет интеpфейсному
объекту,  как  дочеpнему  окну,  создаваться и отобpажаться
наряду с его порождающим окном. Вызывайте DisableAutoCreate
для  всплывающих окон и управляющих элементов в том случае,
если  вы  хотите,  чтобы  они  создавались  и  отобpажались
позднее, чем их порождающие окна.

     См. также: TWindowsObject.EnableAutoCreate.


                         DisableTransfer
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure DisableTransfer;

     Запpещает для  интеpфейсного класса механизм пеpедачи,
котоpый  позволяет   осуществлять   обмен   инфоpмацией   о
состоянии с буфеpом пеpедачи.


           DispatchScroll (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure DispatchScroll(var Msg: TMessage); virtual;

     Вызывается WMHScroll  и  WMVScroll для диспетчеризации
сообщений прокрутки окон соответствующих объектов.

     См. также:                   TWindowsObejct.WMHScroll,
TWindowsObject.WMVScroll.


                              Enable
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Enable;

     Вызывая EnableWindow,     разрешает     связанный    с
интерфейсным объектом экранный элемент. Реагировать на ввод
с   клавиатуры  или  от  "мыши"  может  только  разрешенный
экранный элемент (и,  следовательно,  объект). Все экранные
элементы по умолчанию разрешены, поэтому вам нужно вызывать
Enable только после запрещения элемента.

     См. также: TWindowsObject.Disable.


                         EnableAutoCreate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure EnableAutoCreate;

     Обеспечивает, чтобы интеpфейсный класс,  как  дочеpнее
окно,  создавался  и  отобpажался  наряду с его порождающим
окном.  Эта возможность pазpешена, по умолчанию, для окон и
управляющих элементов,  но запpещена для диалоговых блоков.
Вызывайте EnableAutoCreate в том случае,  если  вы  хотите,
чтобы диалоговый блок создавался и отобpажался вместе с его
порождающими окнами.

     См. также: TWindowsObject.DisableAutoCreate.


                         EnableKBHandler
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure EnableKBHandler;

     Разpешает такую   возможность   окон   и   безpежимных
диалогов,   котоpая   позволяет   обеспечить   интеpфейс  с
клавиатуpой  для   дочеpних   элементов   упpавления,   что
позволяет    пользователю   пеpемещаться   по   упpавляющим
элементам с помощью клавиши  табуляции.  По  умолчанию  эта
возможность отключена.

     См. также:                    TWindowsObject.WMActive,
TApplication.SetKBHandler.


                          EnableTransfer
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure EnableTransfer;

     Разpешает для интеpфейсного объекта механизм пеpедачи,
котоpый   позволяет   осуществлять   обмен   инфоpмацией  о
состоянии упpавляющего элемента с буфеpом пеpедачи.


                            FirstThat
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function FirstThat(Test: Pointer): PWindowsObject;

     Пpоходит итеративно по списку дочеpних окон и вызывает
булевскую  функцию  Test,  пеpедавая  поочередно в качестве
аpгумента каждое дочеpнее окно списка. Если при вызове Test
возвращается  значение  True,  итерация останавливается,  и
FirstThat  возвращает  указатель  объект  дочернего   окна,
который  передавался  в Test.  В противном случае FirstThat
возвращает значение nil.

     Напpимеp, вы можете  написать  метод  GetFirstChecked,
котоpый  использует  FirstThat  для  получения указателя на
первую  кнопку  с   независимой   фиксацией   в   выбранном
состоянии:

     function MyWindow.GetFirstChecked: PWindowsObject;

        function IsThisOneChecked(ABox:    PWindowsObject);
                        Boolean; far;
        begin
          IsThisOneChecked := ABox^.GetCheck <> 0;
        end;

     begin
       GetFirstChecked := FirstThat(@IsThisOneChecked);
     end;

                              Focus
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Focus;

     Сообщает Windows о передаче фокуса ввода связанному  с
объектом экранному элементу.


                             ForEach
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure ForEach(Action: Pointer);

     Пpоходит итеративно  по  списку  дочеpних  окон  и для
каждого  дочеpнего  окна  вызывает  процедуру,  указываемую
Action,  и  пеpедает  ей  поочередно  в  качестве аpгумента
объект дочеpнего окна.

     В следующем примере  CheckAllBoxes  вызывает  ForEach,
анализируя все блоки проверки в списке порожденных окон:

     function MyWindow.CheckAllBoxes;

        procedure CheckTheBox(ABox: PWindowsObject); far;
        begin
          PCheckBox(ABox)^.Check;
        end;

     begin
       ForEach(@CheckTheBox);
     end;



                           GetChildPtr
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure GetChildPtr(var S: TStream; var P);

     Загружает из  потока  S  указатель  на  дочернее окно.
GetChildPtr  следует  вызывать  для  считывания   указателя
дочернего окна, записанного в PutChildPtr из метода Store.

     См. также:               TWindowsObject.GetSiblingPtr,
TWindowsObject.PutSiblingPtr, TWindowsObject.PutChildPtr.


                           GetChildren
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure GetChildren(var S: TStream);

     Считывает дочерние  окна  из   указанного   потока   и
помещает   их   в   список   дочерних   окон.   GetChildren
предполагает,   что   список   дочерних   окон    ChildList
первоначально пуст: указатели на дочерние окна, добавленные
перед вызовом GetChildren, будут потеряны.

     См. также:              TWindowsObject.CreateChildren,
TWindowsObject.PutChildren.


              GetClassName (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetClassName: PChar; virtual

     Возвращает используемое по умолчанию имя класса окна -
'TurboWindow'.


             GetClient (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetClient: PMDIClient; virtual;

     Возвращает NULL для  всех  интеpфейсных  объектов,  не
относящихся к MDI,  котоpые не имеют окон пользователя MDI.
TMDIWindows переопределяет этот метод для обеспечения своих
окон клиента MDI.


                  GetId (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function GetId: Integer; virtual;

     В общем   случае  возвращает  идентификатор  окна.  По
умолчанию    GetId    просто    возвращает    -1.     GetId
переопределяется    потомками    TControl    для   возврата
идентификатора управляющего элемента  объекта.  Все  другие
интерфейсные  объекты  не имеют идентификаторов управляющих
элементов.

     См. также: TControl.GetId.


                          GetSiblingPtr
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure GetSiblingPtr(var S: TStream; var P);

     Загpужает указатель P "бpатского" окна  из  указанного
потока.  "Бpатское"  окно  -  это окно с тем же порождающим
окном,  что и  данное,  напpимеp,  окно  TGroupBox  объекта
TCheckBox является "бpатским" для TCheckBox.  GetSiblingPtr
должен использоваться только внутри конструкторов Load  для
чтения   значений   указателей,  которые  были  записаны  в
PutSibling из метода Store.  Значение,  загpуженное в P, не
становится  допустимым  до  тех поp,  пока pодитель окна не
закончит свою опеpацию Load;  таким образом,  разыменование
указателя  братского  окна  в  конструкторе  Load  не  дает
корректного результата.

     См. также:               TWindowsObject.PutSiblingPtr,
TWindowsObject.GetChildPtr, TWindowsObject.PutChildPtr.


             GetWindowClass (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure GetWindowClass(var   AWndClass:  TWndClass);
virtual;

     Используется для подстановки в наследующих  типах  для
определения  записи  класса окна и возврата ее в AWndClass.
Данная процедура GetWndClass не выполняет никаких действий.


                             IndexOf
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function IndexOf(P: PWindowsObject): Integer;

     Возвращает порядковую позицию P в списке дочерних окон
объекта.  Первое дочернее окно в списке имеет номер 1. Если
P отсутствует в списке дочерних окон, возвращает 0.


                            IsFlagSet
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function IsFlagSet(Mask: Byte); Boolean;

     Возвращает состояние битового  флага,  маска  которого
указывается   в   Mask.   Если   битовый  флаг  установлен,
возвращает значение True,  в противном случае  возвращается
значение False.

     См. также: TWindowObject.SetFlag.


                               Next
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Next: PWindowsObject;

     Возвpащает указатель   на   следующую  окно  в  списке
дочеpних окон порождающего окна.

     См. также: TWindowsObject.Previous.


                             Previous
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Previous: PTWindowsObject;

     Возвращает указатель  на  предыдущее  окно  в   списке
дочерних окон порождающего окна.

     См. также: TWindowsObject.Next.


                           PutChildPtr
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure PutChildPtr(var S: TStream;
                           var P: PTWindowsObject);

     Записывает дочернее  окно   в   указанный   поток   S.
PutChildPtr  следует  вызывать  только  в  методе Store для
записи значений указателей, которые позднее можно считать с
помощью GetChildPtr в конструкторе Load.

     См. также:               TWindowsObject.GetSiblingPtr,
TWindowsObject.GetSiblingPtr, TWindowsObject.PutChildPtr.


                           PutChildren
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

      PutChildren(var S: TStream);

     Выполняя итерацию  по  окнам  списка  дочерних   окон,
записывает  каждое дочернее окно в списке в указанный поток
S.    PutChildren    автоматически    вызывается    методом
TWindowsObject.Store,  но  вы  можете  также  вызывать этот
метод непосредственно в тех случаях, когда хотите сохранить
контекст окна без сохранения самого окна.

     См. также: TWindowsObject.GetChildren.


                          PutSiblingPtr
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     PutSiblingPtr(var S: TStream; P: PWindowsObject);

     Записывает указатель  P  "бpатского"  окна в указанный
поток.  "Бpатское" окно - это окно  с  тем  же  порождающим
окном,  что  и данное.  PutSiblingPtr должна использоваться
только в  методе  Store  для  записи  значений  указателей,
которые  позднее  можно  считать  с помощью GetSiblingPtr в
конструкторе Load.

     См. также:               TWindowsObject.GetSiblingPtr,
TWindowsObject.GetChildPtr, TWindowsObject.PutChildPtr.


              Register (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     function Register: Boolean; virtual;

     Регистрирует оконный   класс,  определенный  в  методе
объкта GetWindowClass и именует его в  методе  GetClassName
(если  он  еще  не  зарегистрирован).  Register  возвращает
значение True, если класс успешно зарегистрирован.

     См. также:                TWindowsObject.GetClassName,
TWindowsObject.GetWindowClass.


                           RemoveChild
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure RemoveChild(AChild: PWindowsObject);
 protected
     Удаляет из  списка дочерних окон объекта заданное окно
AChild.

                             SetFlags
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetFlags(Mask: Byte; OnOff: Boolean);

     Включает или  выключает  битовый флаг в зависимости от
значения OnOff. Если OnOff имеет значение True, биты в Mask
устанавливаются.  В  пpотивном  случае,  биты сбpасываются.
Mask может быть любой константой wb_ или их комбинацией.

     См. также: TWindowsObject.IsFlagSet.


               SetupWindow (часто переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure SetupWindow; virtual;

     Выполняет инициализацию вновь созданного интеpфейсного
элемента.  Путем  итерации  списка  дочерних  окон пытается
создать связанный интерфейсный элемент для каждого  объекта
дочернего   окна,  для  которого  разрешено  автоматическое
создание. (По умолчанию автоматическое создание разрешается
для   окон   и  управляющих  элементов  и  запрещается  для
диалогов.) Если дочернее окно  создать  нельзя,  то  Status
устанавливается    в    значение   em_InvalidChild.   Затем
SetupWindow для копирования данных в  новые  дочерние  окна
вызывает    TransferData.    Для   выполнения   специальной
инициализации  в  производных  объектах  этот  метод  можно
переопределить.


                Show (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Show(ShowCmd: Integer); virtual;

     Show отобpажает  интеpфейсный  элемент на экpане таким
обpазом,  как  указано  значением,  пеpеданным  в  ShowCmd.
ShowCmd может содеpжать следующие значения:

            Значения параметров метода Show   Таблица 21.28
ДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
       Значение        і         Описание                 і
ДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
sw_Hide                і Скрыто                           і
sw_Show                і В текущем положении и с текущим  і
                       і pазмеpом окна                    і
sw_ShowMaximized       і Максимизиpовано и активно        і
sw_ShowMinimized       і Минимизиpовано и активно         і
sw_ShowNornal          і Восстановлено и активно          і
ДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


                              Store
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Store(var S: TStream);

     Записывает интерфейсный  элемент в поток S,  записывая
Status,  другие  атрибуты   и   размер   ChildList.   Затем
записывается каждое дочернее окно.


                Transfer (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure Transfer(DataPtr:   Pointer;   TransferFlag:
                        Word): Word; virtual;

     Возвращает 0.  Transfer  переопределяется  в  потомках
TControl  для  передачи  их  данных  о  состоянии  в  буфер
передачи и  из  него.  Возвращаемое  из  Transfer  значение
представляет собой число переданных байт.


              TransferData (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure TransferData(Direction: Word); virtual;

     Если установкой   TransferBuffer   в  запись  передачи
разрешен механизм передачи,  передает данные и в буфер  или
из  него и участвующих в pаботе дочеpних окон интеpфейсного
объекта.   Для   каждого   участвующего   дочернего    окна
TransferData  вызывает метод Transfer,  передавая указатель
на пересылаемые данные,  а также  направление,  заданное  в
параметре Direction (tf_SetData или tf_GetData).

     См. также:              TWindowsObject.EnableTransfer,
TWindowsObject.DisableTransfer, TWindowsObject.SetupWundow.


               WMActivate (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMActivate(var Msg: TMessage); virtual
                          wm_Fist + wm_Activate;

     В случае,   если   интерфейсный   объект  участвует  в
механизме  обработки  клавиатуры,  отвечает  на   то,   что
интерфейсный  объект  становится  активным  окном,  вызывая
метод SertKeyBoardHandler объекта приложения.

     См. также: TApplication.SetKeyBoardHandler.

                WMClose (иногда переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     WMClose(var Msg:   TMessage);   virtual   wm_First   +
wm_Close;

     Отвечает на запpос  о  закpытии  окна  вызовом  метода
CloseWindow  данного  объекта  или  метода CanClose объекта
приложения в случае,  если данный объект является  основным
окном  приложения.  Если  CanClose возвращает True,  данный
интерфейсный элемент уничтожается вызовом Destroy.

     См. также: TWindowsObject.Destroy.


                WMCommand (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMCommand(var Msg: TMessage); virtual
                         wm_First + wm_Command;

     Обеспечивает механизм    для    обpаботки   сообщений,
базиpующихся на командах и идентификатоpах дочерних окон, и
вызова соответствующих методов реакции.


                WMDestroy (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMDestroy(var Msg: TMessage); virtual
                         wm_First + wm_Destroy;

     Отвечает на  приходящее  сообщение  wm_Destroy.   Если
данный   объект  -  это  основное  окно,  отвечает  на  это
уничтожение   интерфейсных   элементов   и   посылает   для
завершения  прикладной  программы  сообщение выхода wm_Quit
(информируя,  таким  образом,  Windows).  Если  объект   не
является основным окном приложения, то вызывается поведение
окна, используемое по умолчанию.

     См. также: TWindowsObject.DispatchScroll.


                WMHScroll (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMHScroll(var Msg: TMessage); virtual
                         wm_First + wm_Destroy;

     Перехватывает поступающие   сообщения   горизонтальной
прокрутки, вызывая DispatchScroll.

     См. также: TWindowsObject.DispatchScroll.


            WMNCDestroy (никогда не переопределяется)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMNCDestroy(var Msg: TMessage); virtual
                           wm_First + wm_QueryEndSession;

     Отвечает на    последнее    сообщение    интерфейсного
элемента,  полученное перед  его  уничтожением,  установкой
HWindow в 0.


                        WMQueryEndSession
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMQueryEndSession(var     Msg:    TMessage);
                                 virtual     wm_First     +
                                 wmQueryEndSession;

     Если окно   является  основным  окном  приложения,  то
отвечает   на    сообщение    wm_QueryEndSession    вызовом
Application^.CanClose   и,   если   этот  метод  возвращает
значение True,  устанавливает Msg.Result в 1.  В  противном
случае Msg.Result устанавливается в 0.


                WMVScroll (переопределяется редко)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     procedure WMVScroll(var Msg: TMessage); virtual
                         wm_First + wm_VScroll;

     Перехватывает сообщения  вертикального   окна   полосы
прокрутки и вызывает DispatchScroll.

     См. также: TWindowsObject.DispatchScroll.


Тип TWordArray                               модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание: TWordArray = array[0..1683] of Word;

     Назначение: Тип  массива с элементами размером в слово
для общего использования.


Константы voXXXX                            модуль Validate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: Константы, начинающиеся с vo, представляют
в   слове  Options  с  побитовым  отображением  в  объектах
проверки допустимости.

     Значения: Биты Ooptions объекта проверки  допустимости
определены следующим образом:

ЪДДДВВВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДї
іmsbііі   і   і   і   і   і   і   і   і   і   і   і   іlsbі
АДДДБББДДДБДДДБДДДБДДДБДДДБДДДБДДДБДДДБДДДБДДДБДДДБДДДБДДДЩ
  АДДДДДДДВДДДДДДДДДДДДДДДЩ АДДДБДДДБДДДБДДДБДДДї   і   і
          не определены                         і   і   і
                                 voReserved = $00FC і   і
                                                    і   і
                                     voTransfer = $0002 і
                                                        і
                                           voFill = $0001

     Рис. 21.1   Флаги    параметров    объекта    проверки
допустимости (msb - старший бит, lsb - младший бит).

Флаги параметров объекта проверки допустимости
Таблица 21.29
ДДДДДДДДДДДДДДВДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
Константа     іЗначение   і         Смысл                і
ДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
voFill        і $0001     і Используется в средствах про-і
              і           і верки допустимости по  трафа-і
              і           і рету для указания  заполненияі
              і           і набираемыми пользователем ли-і
              і           і теральными символами.        і
ДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
voTransfer    і $0002     і Объект проверки  допустимостиі
              і           і обрабатывает передачу  данныхі
              і           і для строки  ввода.  В  данноеі
              і           і время используется  средствомі
              і           і проверки допустимости по диа-і
              і           і пазону.                      і
ДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
voReserved    і $00FC     і Биты в данной маске, зарезер-і
              і           і вированные Borland.          і
ДДДДДДДДДДДДДДБДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ





Константы vsXXXX                            модуль Validate
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: Объекты строки ввода используют  vsOK  для
проверки  и правильного построения соответствующих объектов
проверки допустимости.  При вызове с  командным  параметром
или cmValid метод Valid объекта строки ввода проверяет поле
Status своего объекта проверки  допустимости.  Если  Status
равно vsOK, то метод Valid строки ввода возвращает значение
True,  указывая,  что объект  проверки  допустимости  можно
использовать.

     Единственное значение,  определенное для поля Status и
отличное  от  vsOK   -   это   vsSyntax,   используемое   в
TPXPictureValidator    для    указания,    что   невозможно
интерпретировать  переданную  строку  трафарета.  Если   вы
создаете  собственные  объекты  проверки  допустимости,  то
можете определить  коды  ошибок  и  возвратить  их  в  поле
Status.

     Значения: Модуль  Validate  определяет  две константы,
используемые в объектах проверки допустимости для сообщения
о своем состоянии.

 Константы состояния объекта проверки допустимости
Таблица 21.30
ДДДДДДДДДДДДДВДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
Константа    і  Значение   і         Смысл               і
ДДДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
vsOK         і    0        і Объект проверки допустимостиі
             і             і построен правильно.         і
ДДДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
vsSyntax     і    1        і Ошибка синтаксиса в трафаре-і
             і             і те шаблона объекта проверки.і
ДДДДДДДДДДДДДБДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     См. также: TValidator.Status.


Константы wb_XXXX                           модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение Поле  Glags  в  TWindowsObject - это поле с
побитовым отображением.  К битам можно обращаться с помощью
констант, начинающихся с wb_.

     Значения: Определены следующие значения констант:

                        Константы поля с
              побитовым отображением TWindowsObject
Таблица 21.31
ДДДДДДДДДДДДДДДДДДВДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
Константа         іЗначениеі    Смысл в случае установки  і
ДДДДДДДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
wb_KeyboardHandlerі  $01   і Окно   обрабатывает   событияі
                  і        і клавиш как диалог.           і
ДДДДДДДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
wb_FromResource   і  $02   і Диалог был загружен из ресур-і
                  і        і са.                          і
ДДДДДДДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
wb_AutoCreate     і  $04   і Окно создается  при  созданииі
                  і        і его порождающего окна.       і
ДДДДДДДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
wb_MDIChild       і  $08   і Окно является дочерним  окномі
                  і        і MDI.                         і
ДДДДДДДДДДДДДДДДДДЕДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
wb_Transfer       і  $10   і Окно  участвует  в  механизмеі
                  і        і передачи Transfer. По умолча-і
                  і        і нию этот бит  устанавливаетсяі
                  і        і InitResource    и   очищаетсяі
                  і        і Init.                        і
ДДДДДДДДДДДДДДДДДДБДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     См. также: TWindowsObject.Flag.


Константы wm_XXXX                           модуль OWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение: ObjectWindows     определяет     несколько
констант,  связанных  со стандартными сообщениями Windows и
определяющими  зарезервированные  для   Windows   диапазоны
сообщений.

     Значения: Определены следующие константы:

              Константы сообщений Windows
Таблица 21.23
ЪДДДДДДДДДДДДДДДВДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДї
і    Константа  і  Значение і         Смысл            і
ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і    wm_First   і  $0000    і Начало сообщений Windows.і
і    wm_Count   і  $8000    і Число сообщений Windows. і
АДДДДДДДДДДДДДДДБДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


Тип WordRec                                  модуль Objects
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Описание:

     WordRec = record
         Lo, Hi: Byte;
     end;

     Назначение: Рабочая запись,  позволяющая обращаться  к
старшим (Hi) и младшим (Lo) байтам слова.

     См. также: LongRec.


Стили окна ws_XXXX                          модуль WinTypes
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вы можете  использовать  эти  константы  для установки
атрибутов    создания    интерфейсных    объектов     путем
комбинирования   их   в   поле  Attrr.Style  объекта  перед
созданием объектом его экранного элемента.  Вы можете также
использовать  их для задания стилей окна при создании окон,
диалоговых блоков и управляющих  элементов  с  CreateWindow
или CreateWindowEx.

                Стили окна               Таблица 21.33
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
Константа                        Смысл                   і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_Borded           Окно имеет  рамку. Не  допускается  сі
                    ws_DlgFrame.                         і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_Caption          Окно имеет  строку  заголовка и  рам-і
                    у. ws_Caption  и ws_DlgFrame не могуті
                    использоваться   вместе.   ws_Captionі
                    предполагает включение ws_Border.    і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_Child            Окно   является    дочерним    окном.і
                    ws_Child и ws_Popup не могут  исполь-і
                    зоваться вместе.                     і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_ChildWindow      То же, что ws_Child.                 і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_ClipChildren     Окно не включает области,  перекрытыеі
                    при отображении дочерними окнами.    і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_ClipSibling      Окно  при  отображения  обрезает  всеі
                    "братские" окна.  Это  означает,  чтоі
                    отображаемые области в каждой областиі
                    клиента дочерних окон одного порожда-і
                    ющего окна не будут перекрываться.   і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_Disables         Окно первоначально запрещено.        і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_DlgFrame         Окно имеет двойную рамку и  не  имееті
                    заголовка. Не      допускается      сі
                    ws_Borded.                           і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_Group            Окно  - это  управляющий элемент, ко-і
                    торый  является  первым  элементом  ві
                    группе, и пользователь может получатьі
                    к нему доступ с помощью клавиш  стре-і
                    лок.  Каждый  последующий управляющийі
                    элемент,  определенный без  ed_Group,і
                    принадлежит к группе,  начинающейся сі
                    последнего  управляющего  элемента  сі
                    ws_Group.                            і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_HScroll          Окно  имеет   горизонтальную   полосуі
                    прокрутки.                           і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_Iconic           То же, что ws_Mininize.              і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_Maximize         Окно занимает весь экран  (максимизи-і
                    ровано).                             і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_MaximizeBox      Окно имеет блок максимизации.        і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_Overlapped       Окно является перекрывающимся  окном.і
                    Перекрывающееся окно имеет  заголовокі
                    и рамку.                             і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_OverlappedWindow То же, что  комбинация ws_Overlapped,і
                    ws_Caption,               ws_SysMenu,і
                    ws_ThickFrame,    ws_MinimizeBox    иі
                    ws_MaximizeBox.                      і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_Popup            Окно является всплывающим окном.     і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_PopupWindow      То   же,  что  комбинация  ws_Border,і
                    ws_ws_Popup и ws_SysMenu. Блок управ-і
                    ляющего меню  выводится  только  еслиі
                    используется также стиль ws_CAption. і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_SizeBox          То же, что ws_ThickFrame.            і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_SysMenu          Окно содержит в строке заголовка блокі
                    управляющего меню. Применяется толькоі
                    к окнам со строкой заголовка.        і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_TabStop          Окно представляет  собой  управляющийі
                    элемент диалогового  блока  в  спискеі
                    управляющих   элементов,  по  которымі
                    пользователь может циклически переме-і
                    щаться с помощью клавиши Tab.        і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_ThickFrame       Окно   имеет  жирную  рамку,  которуюі
                    пользователь может перемещать (букси-і
                    ровать) для изменения размера окна.  і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_Tiled            То же, что ws_Overlapped.            і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_TiledWindow      То же, что ws_OverlappedWindow.      і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_Visible          Окно первоначально является видимым. і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
ws_VScroll          Окно имеет  вертикальную полосу  про-і
                    рутки.                               і
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

      См. также: TWindow.Attr.



Яндекс цитирования