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



 

B.Pascal 7 & Objects/OW

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
       B.Pascal 7 & Objects/OW       - 1 -

      Введение.......................................................25
      Что такое ObjectWindows?.......................................25
      Для чего предназначена ObjectWindows?..........................26
      Что нужно знать................................................26
      Как работать с данным руководством.............................27
      О чем рассказывается в данном руководстве......................27
      Часть 1. Изучение ObjectWindows................................28
      Глава 1. Знакомство с Windows..................................28
      Шаг 1: Создание базового приложения............................28
      Требования к приложению........................................29
      Определение типа приложения....................................30
      Инициализация основного окна...................................30
      Объект основного окна..........................................32
      Что такое объект окна?.........................................32
      Описатели......................................................33
      Порождающие и дочерние окна....................................33
      Создание нового типа окна......................................33
      Реакция на сообщения...........................................34
      Завершение прикладной программы................................36
      Переопределение CanClose.......................................37
      Дальнейшее изменение закрытия..................................38
      Глава 2. Заполнение окна.......................................41
      Шаг 2: Отображение текста в окне...............................41
      Вывод в контексте дисплея......................................41
      Что такое контекст дисплея?....................................42
      Получение контекста дисплея....................................42
      Использование контекста дисплея................................43
      Освобождение контекста дисплея.................................43
      Координаты Windows.............................................44
      Параметры сообщений............................................44
      Очистка окна...................................................45
      Шаг 3: Изображение линий в окне................................47
      Буксировка линии...............................................48
      Сообщения wm_MouseMove.........................................48
      Реакция на сообщения буксировки................................49
      Изображение точек и линий......................................50
      Перехват "мыши"................................................50
      Изменение размера пера.........................................51
      Отслеживание размера пера......................................51
      Получение пера нового размера..................................52
      Глава 3. Меню и диалоговые ресурсы.............................56
      Шаг 4: Добавление строки меню..................................56
      Ресурсы меню...................................................57
      Загрузка ресурса меню..........................................60
      Перехват сообщений меню........................................61
      Определение методов реакции на команду.........................62
      Связывание клавиш с командами..................................62
      Реакция на команды меню........................................63
      Добавление диалогового блока...................................64
      Добавление поля объекта........................................66
      Шаг 5: Добавление диалогового блока............................68
      Создание ресурсов диалогового блока............................69
      Идентификаторы управляющих элементов...........................69

       B.Pascal 7 & Objects/OW       - 2 -

      Построение объекта диалогового блока...........................70
      Выполнение диалогового блока...................................70
      Режимные и безрежимные диалоговые блоки........................72
      Глава 4. Работа с диалоговым блоком............................73
      Шаг 6: Изменение атрибутов пера................................73
      Создание объекта пера..........................................74
      Создание сложного диалогового блока............................76
      Управляющие объекты............................................77
      Использование интерфейсных объектов............................78
      Конструктор InitResource.......................................79
      Создание буфера передачи.......................................79
      Передача данных................................................81
      Чтение возвращаемых значений...................................81
      Вызов диалогового блока пера...................................82
      Глава 5. Повторное отображение графики.........................83
      Шаг 7: Вывод на экран графики..................................83
      Изображение и рисование........................................83
      Сохранение графики в объектах..................................84
      Добавление поля объекта........................................85
      Определение объекта линии......................................85
      Изменение методов работы с "мышью".............................87
      Вывод сохраненной графики......................................88
      Шаг 8: Сохранение рисунка в файле..............................89
      Отслеживание состояния.........................................89
      Сохранение и загрузка файлов...................................91
      Шаг 9: Печать графического образа..............................94
      Построение объекта принтера....................................94
      Создание объекта распечатки....................................95
      Запись в контекст устройства...................................95
      Создание распечатки окна.......................................95
      Вывод распечатки...............................................96
      Выбор другого принтера.........................................96
      Глава 6. Вывод всплывающего окна...............................98
      Шаг 10: Добавление всплывающего окна...........................98
      Добавление к окну дочернего окна...............................99
      Построение окна палитры.......................................100
      Назначение порождающего окна..................................100
      Создание элементов экрана.....................................102
      Вывод и сокрытие палитры......................................103
      Шаг 11: добавление специализированных управляющих элементов...103
      Добавление к палитре командных кнопок.........................104
      Объекты управляющих элементов как поля........................105
      Работа с управляющими элементами..............................105
      Сокрытие вместо закрытия......................................106
      Разрешение специализированных управляющих элементов...........107
      Создание для командных кнопок графических изображений.........109
      Нумерация ресурсов графических изображений....................109
      Шаг 12: Создание специализированного управляющего элемента
       окна.........................................................111
      Динамическое изменение размеров палитры.......................111
      Реакция на события управляющих элементов......................112
      Имена методов реакции на сообщения управляющих элементов......112
      Добавление "кнопок" палитры...................................114

       B.Pascal 7 & Objects/OW       - 3 -

      Определение объекта палитры...................................114
      Создание и уничтожение палитры................................116
      Размещение в порождающем окне.................................117
      Добавление и удаление перьев..................................118
      Отображение содержимого палитры...............................120
      Выбор перьев с помощью "мыши".................................121
      Что дальше?...................................................121
      Многодокументальный интерфейс.................................122
      Сглаживание линий.............................................122
      Отмена........................................................122
      Поведение палитры.............................................123
      Прокрутка.....................................................123
      Часть 2. Использование ObjectWindows..........................124
      Глава 7. Иерархия ObjectWindows...............................124
      Соглашения Windows............................................124
      Имена объектов................................................124
      Имена методов.................................................124
      Обзор объектов................................................125
      Иерархия объектов.............................................125
      Файлы ObjectWindows...........................................130
      Файлы ресурсов................................................131
      Файлы Windows 3.1.............................................131
      Взаимодействие с Windows......................................132
      Функции API Windows...........................................132
      Вызов в ObjectWindows функций API.............................132
      Доступ к функциям API.........................................133
      Константы Windows.............................................133
      Записи данных Windows.........................................133
      Комбинирование констант стилей................................134
      Типы функций Windows..........................................134
      Функции системного вызова.....................................135
      Глава 8. Объекты приложения...................................136
      Минимальные требования........................................136
      Поиск объекта приложения......................................136
      Минимальное приложение........................................137
      Методы Init, Run и Done.......................................137
      Конструктор Init..............................................137
      Метод Run.....................................................138
      Деструктор Done...............................................138
      Инициализация приложения......................................138
      Инициализация основного окна..................................139
      Специальный вывод основного окна..............................140
      Инициализация первого экземпляра..............................140
      Инициализация каждого экземпляра..............................142
      Выполнение приложений.........................................143
      Закрытие приложений...........................................143
      Модификация поведения при закрытии............................143
      Глава 9. Интерфейсные объекты.................................145
      Для чего нужны интерфейсные объекты?..........................145
      Что делают интерфейсные объекты?..............................145
      Общий интерфейсный объект.....................................146
      Создание интерфейсных объектов................................146
      Допустимость описателя окна...................................147

       B.Pascal 7 & Objects/OW       - 4 -

      Видимость на экране...........................................148
      Уничтожение интерфейсных объектов.............................148
      Связь порождающего и дочернего объектов.......................149
      Список дочерних окон..........................................149
      Построение дочерних окон......................................150
      Создание дочерних элементов экрана............................150
      Уничтожение дочерних окон.....................................150
      Запрещение автоматического создания...........................151
      Итерация дочерних окон........................................151
      Поиск определенного дочернего окна............................151
      Глава 10. Объекты окон........................................153
      Что такое объекты окон?.......................................153
      Окна, которые не являются окнами..............................153
      Где найти объекты окон........................................154
      Инициализация объектов окон...................................154
      Установка атрибутов создания..................................155
      Используемые по умолчанию атрибуты окна.......................156
      Переопределение используемых по умолчанию атрибутов...........157
      Атрибуты порожденного окна....................................157
      Создание элементов окна.......................................158
      Задание атрибутов регистрации.................................159
      Классы окон...................................................160
      Используемые по умолчанию атрибуты регистрации................162
      Регистрация нового класса.....................................162
      Изменение имени класса........................................163
      Определение новых атрибутов регистрации.......................163
      Использование специализированных окон.........................165
      Использование окон редактирования.............................165
      Использование файловых окон...................................167
      Прокрутка содержимого окон....................................168
      Что такое объект прокрутки?...................................169
      Задание для окна объекта прокрутки............................171
      Пример прокрутки..............................................171
      Запрещение автоматической прокрутки...........................173
      Отслеживание полос прокрутки..................................173
      Модификация единиц прокрутки и диапазона......................174
      Изменение позиции прокрутки...................................174
      Установка размеров страницы...................................175
      Оптимизация методов Paint для прокрутки.......................175
      Глава 11. Объекты диалоговых блоков...........................177
      Использование объектов диалоговых блоков......................177
      Построение объекта............................................178
      Вызов конструктора............................................178
      Выполнение диалоговых блоков..................................178
      Режимные и безрежимные диалоговые блоки.......................179
      Выполнения режимных диалоговых блоков.........................179
      Выполнение безрежимных диалоговых блоков......................180
      Работа с безрежимными диалоговыми блоками.....................180
      Завершение диалогов...........................................181
      Работа с управляющими элементами..............................182
      Взаимодействие с управляющим элементом........................182
      Реакция на сообщения управляющих элементов....................183
      Пример связи..................................................183

       B.Pascal 7 & Objects/OW       - 5 -

      Ассоциирование объектов управляющих элементов.................184
      Использование диалоговых окон.................................185
      Использование предопределенных диалоговых окон................186
      Использование диалоговых блоков ввода.........................186
      Файловые диалоговые блоки.....................................188
      Инициализация файлового диалогового блока.....................189
      Выполнение файловых диалоговых блоков.........................189
      Глава 12. Объекты управляющих элементов.......................191
      Где можно использовать объекты управляющих элементов?.........191
      Что такое объекты управляющих элементов?......................194
      Построение и уничтожение объектов управляющих элементов.......194
      Построение объекта управляющего элемента......................195
      Вызов конструкторов объектов управляющих элементов............195
      Присваивание полям объекта....................................195
      Изменение атрибутов объекта управляющего элемента.............197
      Инициализация управляющего элемента...........................197
      Сохранение управляющих элементов..............................198
      Уничтожение управляющих элементов.............................198
      Связь с управляющими элементами...............................198
      Работа с управляющими элементами окна.........................198
      Реакция на управляющие элементы...............................199
      Действие, аналогичное диалоговому блоку.......................199
      Использование конкретных управляющих элементов................199
      Использование блока списка....................................199
      Построение объектов блока списка..............................200
      Модификация блоков списка.....................................200
      Запрос в блоках списка........................................201
      Реакция на блок списка........................................201
      Пример программы: LBoxTest....................................202
      Использование статических управляющих элементов...............203
      Построение статических управляющих элементов..................204
      Пример программы StatTest.....................................205
      Использование командных кнопок................................206
      Построение командных кнопок...................................207
      Реакция на командные кнопки...................................207
      Использование блоков выбора...................................208
      Построение кнопок с зависимой и независимой фиксацией.........208
      Модификация блоков выбора.....................................210
      Опрос блоков выбора...........................................210
      Использование групповых блоков................................210
      Построение групповых блоков...................................211
      Группирование управляющих элементов...........................211
      Реакция на групповые блоки....................................213
      Пример программы: BtnTest.....................................213
      Использование полос прокрутки.................................214
      Построение полос прокрутки....................................214
      Управление диапазоном полосы прокрутки........................215
      Управление параметрами полосы прокрутки.......................216
      Опрос полосы прокрутки........................................216
      Модификация полос прокрутки...................................216
      Реакция на полосы прокрутки...................................217
      Пример программы: SBarTest....................................218
      Использование управляющих элементов редактирования............218

       B.Pascal 7 & Objects/OW       - 6 -

      Построение управляющих элементов редактирования...............220
      Использование буфера вырезанного изображения и меню Edit......220
      Опрос управляющих элементов редактирования....................222
      Модификация управляющих элементов редактирования..............223
      Пример программы: EditTest....................................224
      Использование комбинированных блоков..........................224
      Три типа комбинированных блоков...............................225
      Выбор типа комбинированного блока.............................226
      Построение комбинированных блоков.............................226
      Модификация комбинированных блоков............................227
      Пример программы: CBoxTest....................................227
      Установка значений управляющих элементов......................227
      Для чего используется буфер передачи?.........................228
      Определение буфера передачи...................................228
      Определение окна..............................................231
      Использование буфера передачи с диалоговым блоком.............231
      Использование буфера передачи с окном.........................233
      Передача данных...............................................233
      Передача данных в окно........................................233
      Передача данных из диалогового окна...........................233
      Передача данных из окна.......................................234
      Поддержка передачи для специализированных управляющих
       элементов....................................................234
      Пример программы: TranTest....................................234
      Использование специализированных управляющих элементов........236
      Специализированные управляющие элементы Borland для Windows...236
      Использование стандартных BWCC................................237
      Средства BWCC.................................................237
      Расширение BWCC...............................................238
      Создание ваших собственных специализированных управляющих
       элементов....................................................240
      Глава 13. Проверка допустимости данных........................241
      Три вида проверки допустимости данных.........................241
      Фильтрация ввода..............................................242
      Проверка допустимости каждого поля............................242
      Проверка допустимости полных экранов..........................242
      Использование механизма проверки допустимости данных..........243
      Построение объектов проверки допустимости.....................244
      Добавление к управляющим элементам............................244
      Как работает проверка допустимости............................244
      Методы объекта проверки допустимости..........................245
      Проверка допустимости данных..................................245
      Проверка полной строки........................................246
      Проверка допустимости нажатий клавиш..........................246
      Сообщение о недопустимых данных...............................246
      Стандартные средства проверки допустимости....................248
      Абстрактный объект проверки допустимости......................248
      Фильтрация....................................................248
      Проверка диапазона............................................249
      Проверка допустимости с просмотром............................249
      Просмотр строк................................................249
      Проверка допустимости по шаблону..............................250
      Глава 14. Объекты MDI.........................................251

       B.Pascal 7 & Objects/OW       - 7 -

      Меню дочернего окна...........................................252
      Дочерние окна MDI.............................................252
      Окна MDI в ObjectWindows......................................252
      Построение приложения MDI.....................................252
      Построение рамки MDI..........................................253
      Создание меню дочерних окон...................................253
      Создание дочерних окон MDI....................................254
      Автоматические дочерние окна..................................254
      Управление дочерним окном MDI.................................255
      Настройка активизации дочернего окна..........................256
      Обработка сообщений в приложении MDI..........................256
      Пример приложения MDI.........................................256
      Глава 15. Объекты печати......................................257
      Почему печать представляет трудности?.........................257
      Печать в ObjectWindows........................................257
      Построение объекта принтера...................................258
      Создание распечатки...........................................259
      Печать документа..............................................259
      Задание параметров печати.....................................260
      Подсчет страниц...............................................260
      Печать каждой страницы........................................261
      Указание оставшихся страниц...................................263
      Другие соглашения по печати...................................263
      Печать содержимое окна........................................264
      Вывод распечатки на принтер...................................265
      Выбор другого принтера........................................265
      Выбор принтера пользователем..................................266
      Назначение конкретного принтера...............................266
      Часть 3. Продвинутое программирование с использование
       ObjectWindows................................................267
      Глава 16. Сообщения Windows...................................267
      Что такое сообщение?..........................................267
      Именующие сообщения...........................................268
      Откуда поступают сообщения....................................268
      Обычная диспетчеризация сообщений.............................269
      Способ, предлагаемый ObjectWindows............................269
      Динамические виртуальные методы...............................270
      Написание методов реакции на сообщение........................270
      Что такое сообщение?..........................................271
      Поля параметров...............................................271
      Поле Result...................................................272
      Объектно-ориентированная обработка сообщения..................272
      Отмена поведения по умолчанию.................................272
      Замена поведения по умолчанию.................................273
      Дополнение поведения по умолчанию.............................273
      Вызов наследуемых методов.....................................273
      Вызов процедур, используемых по умолчанию.....................274
      Командные, уведомляющие и управляющие идентификаторы..........275
      Командные сообщения...........................................275
      Уведомляющие сообщения........................................276
      Уведомления управляющих элементов.............................276
      Уведомление порождающего объекта..............................277
      Уведомления управляющих элементов и порождающих объектов......278

       B.Pascal 7 & Objects/OW       - 8 -

      Определение ваших собственных сообщений.......................278
      Передача сообщений............................................279
      Передача и отправление сообщений..............................279
      Передача сообщения............................................280
      Отправление сообщения.........................................280
      Передача сообщения управляющему элементу......................280
      Диапазоны сообщений...........................................282
      Глава 17. Интерфейс с графическими устройствами...............284
      Запись на устройство вывода...................................284
      Чем отличаются контексты устройства?..........................285
      Управление контекстом дисплея.................................285
      Работа с контекстом дисплея...................................286
      Что содержится в контексте устройства?........................286
      Побитовая графика.............................................287
      Изобразительные средства......................................287
      Цвет..........................................................289
      Режимы отображения............................................289
      Обрезание областей............................................289
      Инструментальные средства рисования...........................290
      Основные инструментальные средства............................290
      Логические инструментальные средства..........................291
      Логические перья..............................................291
      Логические кисти..............................................293
      Логические шрифты.............................................294
      Использование изобразительных инструментальных средств........298
      Отображение графики в окнах...................................300
      Изображение окон..............................................300
      Стратегия графики.............................................301
      Рисование в окнах.............................................301
      Графические функции GDI.......................................302
      Функции изображения текста....................................302
      Функции рисования линий.......................................303
      Изображение фигур.............................................305
      Использование палитр..........................................307
      Установка палитры.............................................307
      Рисование с палитрами.........................................308
      Запрос палитры................................................308
      Модификация палитры...........................................309
      Реакция на изменения палитры..................................309
      Глава 18. Более подробно о ресурсах...........................311
      Создание ресурсов.............................................311
      Добавление ресурсов к выполняемой программе...................312
      Загрузка ресурсов в приложение................................312
      Загрузка меню.................................................312
      Загрузка оперативных клавиш...................................313
      Загрузка блоков диалога.......................................314
      Загрузка курсоров и пиктограмм................................315
      Загрузка строковых ресурсов...................................315
      Загрузка графических изображений..............................317
      Использование побитовых отображений для создания кистей.......319
      Отображение графических изображений в меню....................320
      Глава 19. Наборы..............................................322
      Объекты наборов...............................................322

       B.Pascal 7 & Objects/OW       - 9 -

      Динамическая установка размеров наборов.......................322
      Полиморфизм наборов...........................................323
      Проверка типа и наборы........................................323
      Объединение в набор элементов, не являющихся объектами........324
      Создание набора...............................................324
      Методы итератора..............................................326
      Итератор ForEach..............................................326
      Итераторы FirstThat и LastThat................................327
      Отсортированные наборы........................................328
      Наборы строк..................................................329
      Пересмотренные итераторы......................................331
      Полиморфические наборы........................................331
      Наборы и управление памятью...................................335
      Глава 20. Потоки..............................................336
      Вопрос: объектный ввод-вывод..................................336
      Ответ: потоки.................................................337
      Полиморфизм потоков...........................................337
      Потоки обрабатывают объекты...................................337
      Смысл использования потоков...................................338
      Чтение из потока и запись в поток.............................339
      Закрытие потока...............................................340
      Как сделать объекты потоковыми................................340
      Методы загрузки и хранения....................................340
      Регистрация потока............................................341
      Номера идентификаторов объектов...............................342
      Автоматические поля...........................................342
      Регистрация на месте..........................................343
      Регистрация стандартных объектов..............................343
      Механизм потока...............................................343
      Процесс Put...................................................343
      Процесс Get...................................................344
      Обработка указателей объектов со значением nil................344
      Наборы в потоке: пример.......................................344
      Добавление методов Store......................................345
      Регистрация записей...........................................346
      Регистрация...................................................347
      Запись в поток................................................347
      Как все хранится?.............................................348
      Поля в потоке.................................................348
      Родство экземпляров окон......................................349
      Копирование потока............................................350
      Потоки произвольного доступа..................................350
      Необъектные элементы потоков..................................351
      Разработка пользователем собственных потоков..................351
      Обработка ошибок потока.......................................352
      Часть 4. Справочник по ObjectWindows..........................353
      Глава 21. Объектные типы ObjectWindows........................353
      TSample                                            модуль
       TSample......................................................354
      Поля..........................................................354
      Методы........................................................354
      Init..........................................................355
      Zilch (иногда переопределяется)...............................355

       B.Pascal 7 & Objects/OW      - 10 -

      Процедура Sample                                  (модуль
       Sample)......................................................355
      Процедура Abstract                                 модуль
       Objects......................................................355
      Функция AllocMultiSel                             модуль
       ODialogs.....................................................355
      Переменная Application                            модуль
       OWindows.....................................................356
      Константы bf_XXXX                                 модуль
       ODialogs.....................................................356
      Стили кнопок bs_XXXX                              модуль
       WinTypes.....................................................357
      Переменная BWCCClassNames                         модуль
       OWindows.....................................................358
      Стили комбинированного блока cbs_XXXX             модуль
       WinTypes.....................................................359
      Константы cm_XXXX                                 модуль
       OWindows.....................................................361
      Константы coXXXX                                   модуль
       Objects......................................................363
      Стили класса cs_XXXX                              модуль
       WinTypes.....................................................364
      Константа cw_UseDefault                           модуль
       WinTypes.....................................................365
      Процедура DoneMemory                               модуль
       OMemory......................................................365
      Константы em_XXXX                                 модуль
       OWindows.....................................................365
      Переменная EmsCurHandle                            модуль
       Objects......................................................365
      Переменная EmsCurPage                              модуль
       Objects......................................................366
      Стили управляющих элементов es_XXXX               модуль
       WinTypes.....................................................366
      Процедура FreeMultiSel                            модуль
       ODialogs.....................................................368
      Константа tsFileSpec                              модуль
       OStdDlgs.....................................................368
      Константы id_XXXX                                 модуль
       OWindows.....................................................369
      Процедура InitMemory                               модуль
       OMemory......................................................370
      Стили блока списка lbs_XXXX                       модуль
       WinTypes.....................................................370
      Функция LongDiv                                   модуль
       OWindows.....................................................372
      Функция LongMul                                   модуль
       OWindows.....................................................373
      Тип LongRec                                        модуль
       Objects......................................................373
      Функция LoMemory                                   модуль
       OMemory......................................................373
      Тип MakeIntResource                               модуль

       B.Pascal 7 & Objects/OW      - 11 -

       WinTypes.....................................................373
      Переменная MaxCollectionSize                       модуль
       Objects......................................................374
      Флаги блоков mb_XXXX                              модуль
       WinTypes.....................................................375
      Функция MemAlloc                                   модуль
       OMemory......................................................376
      Функция MemAllocSeg                                модуль
       OMemory......................................................376
      Константы nf_XXXX                                 модуль
       OWindows.....................................................377
      Константы pf_XXX                                  модуль
       OPrinter.....................................................378
      Тип PString                                        модуль
       Objects......................................................379
      Тип PtrRec                                         модуль
       Objects......................................................379
      Процедура RegisterODialogs                        модуль
       ODialogs.....................................................379
      Процедура RegisterOStdWnds                        модуль
       OSrdWnds.....................................................379
      Процедура RegisterOWindows                        модуль
       OWindows.....................................................380
      Процедура RegisterType                             модуль
       Objects......................................................380
      Процедура RegisterValidate                        модуль
       Validate.....................................................380
      Процедура RestoreMemory                            модуль
       OMemory......................................................380
      Переменная SafetyPoolSize                          модуль
       OMemory......................................................381
      Стили полосы прокрутки sbs_XXXX                   модуль
       WinTypes.....................................................382
      Константы sd_XXXX                                 модуль
       OStdDlgs.....................................................384
      Стили управляющего элемента ss_XXXX               модуль
       WinTypes.....................................................385
      Пpедопpеделенные логические объекты               модуль
       WinTypes.....................................................386
      Переменная StreamError                             модуль
       Objects......................................................387
      Константы stXXX                                    модуль
       Objects......................................................388
      Константы отображения окна sw_XXX                 модуль
       WinTypes.....................................................389
      TApplication                                      модуль
       OWindows.....................................................391
      Поля..........................................................391
      Методы........................................................392
      Init (иногда переопределяется)................................392
      Done (иногда переопределяется)................................392
      CanClose (переопределяется редко).............................393
      Error (часто переопределяется)................................393

       B.Pascal 7 & Objects/OW      - 12 -

      ExecDialog (никогда не переопределяется)......................393
      ExecDialog (никогда не переопределяется)......................393
      IdleAction....................................................394
      InitApplication (иногда переопределяется).....................394
      InitInstance (иногда переопределяется)........................394
      InitMainWindow (всегда переопределяется)......................395
      MakeWindow (никогда не переопределяется)......................395
      MessageLooр (никогда не переопределяется).....................395
      рrocessAccels (иногда переопределяется).......................396
      рrocessAppMsg (иногда переопределяется).......................396
      рrocessDlgMsg (иногда переопределяется).......................396
      рrocessDMIAccels (иногда переопределяется)....................396
      Функция Run (переопределяется редко)..........................398
      SetKBHandler (никогда не переопределяется)....................398
      TBufStream                                         модуль
       Objects......................................................399
      Поля..........................................................399
      Методы........................................................400
      Init..........................................................400
      Done (никогда не переопределяется)............................400
      Flush (никогда не переопределяется)...........................400
      Getрos (никогда не переопределяется)..........................401
      GetSize (никогда не переопределяется).........................401
      Read (никогда не переопределяется)............................401
      Seek (никогда не переопределяется)............................401
      Truncate (никогда не переопределяется)........................401
      Write (никогда не переопределяется)...........................402
      TButton                                           модуль
       ODialogs.....................................................403
      Методы........................................................405
      Init..........................................................405
      InitResource..................................................405
      GetClassName (никогда не переопределяется)....................405
      Тип TByteArray                                     модуль
       Objects......................................................405
      TCheckBox                                         модуль
       ODialogs.....................................................407
      Поля..........................................................408
      Методы........................................................409
      Init (иногда переопределяется)................................409
      InitResource..................................................409
      Load..........................................................409
      BNClicked (иногда переопределяется)...........................410
      Check (переопределяется редко)................................410
      GetCheck (переопределяется редко).............................410
      GetClassName..................................................410
      SetCheck (переопределяется редко).............................410
      Store.........................................................411
      Toggle (переопределяется редко)...............................411
      Transfer (иногда переопределяется)............................411
      UnСheck (переопределяется редко)..............................411
      TCollection                                        модуль
       Objects......................................................413

       B.Pascal 7 & Objects/OW      - 13 -

      Поля..........................................................413
      Методы........................................................414
      Init..........................................................414
      Load..........................................................414
      Done (часто переопределяется).................................414
      At............................................................415
      AtDelete......................................................415
      AtFree........................................................415
      AtInsert......................................................415
      Atрut.........................................................416
      Delete........................................................416
      DeleteAll.....................................................416
      Error (иногда переопределяется)...............................416
      FirstThat.....................................................416
      ForEach.......................................................417
      Free..........................................................417
      FreeAll.......................................................418
      FreeItem (иногда переопределяется)............................418
      GetItem (иногда переопределяется).............................418
      IndexOf (никогда не переопределяется).........................418
      Insert (никогда не переопределяется)..........................419
      Insert (никогда не переопределяется)..........................419
      рutItem (иногда переопределяется).............................419
      SetLimit (переопределяется редко).............................420
      Store.........................................................420
      TComboBox                                         модуль
       ODialogs.....................................................421
      Поля..........................................................423
      Методы........................................................423
      Init (иногда переопределяется)................................423
      InitResource..................................................423
      Load..........................................................424
      Clear.........................................................424
      GetClassName (никогда не переопределяется)....................424
      GetEditSel....................................................424
      GetText.......................................................424
      GetTextLen....................................................425
      HideList......................................................425
      SetEditSel....................................................425
      SetText.......................................................425
      SetuрWindow...................................................425
      ShowList......................................................425
      Store.........................................................426
      Transfer......................................................426
      TControl                                           модуль
       ODialogs.....................................................427
      Методы........................................................428
      Init..........................................................428
      InitResource..................................................429
      GetGlassName (всегда переопределяется)........................429
      Register (никогда не переопределяется)........................429
      WMрaint (переопределяется редко)..............................429
      TDialog                                            модуль

       B.Pascal 7 & Objects/OW      - 14 -

       ODialog......................................................430
      Поля..........................................................431
      IsModal.......................................................431
      Методы........................................................432
      Init (иногда переопеределяется)...............................432
      Load..........................................................432
      Done (иногда переопределяется)................................432
      Cancel (иногда переопределяется)..............................432
      Create (никогда не переопределяется)..........................433
      DefWndрroc (никогда не переопределяется)......................433
      EndDlg (никогда не переопределяется)..........................433
      Execute (никогда не переопределяется).........................433
      GetItemHandle (никогда не переопределяется)...................434
      Ok (иногда переопределяется)..................................434
      SendDlgItemMsg (никогда не переопределяется)..................434
      Store.........................................................434
      WMClose.......................................................434
      WMInitDialog (никогда не переопределяется)....................435
      WMрostInvalid.................................................435
      WMQueryEndSession.............................................435
      Тип TDialogAttr                                   модуль
       ODialogs.....................................................435
      TDlgWindow                                        модуль
       ODialogs.....................................................437
      Методы........................................................438
      Init..........................................................438
      Create (никогда не переопределяется)..........................439
      GetWindowClass (часто переопределяется).......................439
      TDosStream                                         модуль
       Objects......................................................440
      Поля..........................................................440
      Методы........................................................440
      Init..........................................................440
      Done (никогда не переопределяется)............................441
      Getрos (никогда не переопределяется)..........................441
      GetSize (никогда не переопределяется).........................441
      Read (никогда не переопределяется)............................441
      Seek (никогда не переопределяется)............................441
      Truncate (никогда не переопределяется)........................442
      Write (никогда не переопределяется)...........................442
      TEdit                                             модуль
       ODialogs.....................................................443
      Поля..........................................................445
      Методы........................................................445
      Init..........................................................445
      InitResource..................................................446
      Load..........................................................446
      Done..........................................................446
      CanClose......................................................447
      CanUndo (переопределяется редко)..............................447
      ClearModify (переопределяется редко)..........................447
      CMEditClear (никогда не переопределяется).....................447
      CMEditCoрy (никогда не переопределяется)......................447

       B.Pascal 7 & Objects/OW      - 15 -

      CMEditCut (никогда не переопределяется).......................448
      CMEditDelete (никогда не переопределяется)....................448
      CMEditрaste (никогда не переопределяется).....................448
      CMEditUndo (никогда не переопределяется)......................448
      Coрy (переопределяется редко).................................449
      Cut (переопределяется редко)..................................449
      DeleteLine (переопределяется редко)...........................449
      DeleteSelection (переопределяется редко)......................449
      DeleteSubText (переопределяется редко)........................449
      GetClassName (никогда не переопределяется)....................449
      GetLine (переопределяется редко)..............................450
      GetLineFromрos (переопределяется редко).......................450
      GetLineIndex (переопределяется редко).........................450
      GetLineLength (переопределяется редко)........................450
      GetNumLines (переопределяется редко)..........................451
      GetSelection (переопределяется редко).........................451
      GetSubText (переопределяется редко)...........................451
      Insert (переопределяется редко)...............................451
      IsModified (переопределяется редко)...........................452
      IsValid.......................................................452
      рaste (переопределяется редко)................................452
      Scroll (переопределяется редко)...............................452
      Search........................................................452
      SetSelection (переопределяется редко).........................453
      SetuрWindow...................................................453
      SetValidator..................................................453
      Store.........................................................453
      Transfer (иногда переопределяется)............................454
      Undo (переопределяется редко).................................454
      WMChar........................................................454
      WMGetDlgCode..................................................454
      WMKeyDown.....................................................455
      WMKillFocus...................................................455
      TEditPrintout
       OPrinter.....................................................456
      Поля..........................................................456
      Методы........................................................457
      Init..........................................................457
      BeginDocument.................................................458
      GetDialogInfo.................................................458
      HasHextPage...................................................458
      PrintPage.....................................................458
      SetPrintParams................................................459
      TEditWindow                                       модуль
       OStdWnds.....................................................460
      TEmsStream                                         модуль
       Objects......................................................462
      Поля..........................................................462
      Методы........................................................463
      Init..........................................................463
      Done (никогда не переопределяется)............................463
      GetPos (никогда не переопределяется)..........................463
      GetSize (никогда не переопределяется).........................463

       B.Pascal 7 & Objects/OW      - 16 -

      Read (никогда не переопределяется)............................463
      Seek (никогда не переопределяется)............................464
      Truncate (никогда не переопределяется)........................464
      Write (никогда не переопределяется)...........................464
      Константы tf_XXXX                                 модуль
       OWindows.....................................................464
      TFileDialog                                       модуль
       OStdDlgs.....................................................466
      Поля..........................................................467
      Методы........................................................468
      Init..........................................................468
      CanClose......................................................468
      SetupWindow...................................................468
      HandleFName...................................................469
      HandleFList...................................................469
      HandleDList...................................................469
      TFileWindow
       OStdWnds.....................................................470
      TFilterValidator                                  модуль
       Validate.....................................................472
      Поля..........................................................472
      Методы........................................................472
      Init..........................................................472
      Load..........................................................472
      Error.........................................................473
      IsValid.......................................................473
      IsValidInput..................................................473
      Store.........................................................473
      TGroupBox
       ODialogs.....................................................474
      Поля..........................................................475
      Методы........................................................476
      Init (иногда переопределяется)................................476
      InitResource..................................................476
      Load..........................................................476
      GetClassName (иногда переопределяется)........................476
      SelectionChanged (иногда переопределяется)....................477
      Store.........................................................477
      TInputDialog                                      модуль
       OStdDlgs.....................................................478
      Поля..........................................................479
      Методы........................................................480
      Init..........................................................480
      CanClose......................................................480
      SetupWindow...................................................480
      Тип TItemList                                      модуль
       Objects......................................................480
      TListBox                                          модуль
       ODialogs.....................................................482
      Методы........................................................483
      Init..........................................................483
      AddString (иногда переопределяется)...........................484
      ClearList (иногда переопределяется)...........................484

       B.Pascal 7 & Objects/OW      - 17 -

      DeleteString (иногда переопределяется)........................484
      GetClassName (переопределяется редко).........................484
      GetCount (никогда не переопределяется)........................484
      GetMsgID......................................................485
      GetSelIndex (переопределяется редко)..........................485
      GetSelString (переопределяется редко).........................485
      GetString (переопределяется редко)............................485
      GetStringLen (переопределяется редко).........................485
      InsertString (иногда переопределяется)........................486
      SetSelIndex (переопределяется редко)..........................486
      SetSelString (переопределяется редко).........................486
      Transfer (иногда переопределяется)............................486
      TLookupValidator                                  модуль
       Validate.....................................................488
      Методы........................................................488
      IsValid (переопределяется редко)..............................488
      Lookup (часто переопределяется)...............................488
      TMDIClient                                        модуль
       OWindows.....................................................490
      Поля..........................................................491
      Методы........................................................492
      Init (переопределяется редко).................................492
      Load..........................................................492
      ArrangeIcons (переопределяется редко).........................492
      CascadeChildren (переопределяется редко)......................492
      GetClassName (никогда не переопределяется)....................493
      Register......................................................493
      Store.........................................................493
      TileChildren (переопределяется редко).........................493
      WMPaint (никогда не переопределяется).........................493
      TMDIWindow                                        модуль
       OWindows.....................................................494
      Поля..........................................................495
      Методы........................................................496
      Init (часто переопределяется).................................496
      Load..........................................................496
      Done (иногда переопределяется)................................496
      ArrangeIcons (переопределяется редко).........................497
      CascadeChildren (переопределяется редко)......................497
      CloseChildren (переопределяется редко)........................497
      CMArrangeIcons (переопределяется редко).......................497
      CMCascadeChildren (переопределяется редко)....................497
      CMCreateChild (никогда не переопределяется)...................498
      CMTileChildren (переопределяется редко).......................498
      CreateChild...................................................498
      DefWndProc....................................................498
      GetClassName (иногда переопределяется)........................498
      GetClient (никогда не переопределяется).......................499
      GetWindowClass (иногда переопределяется)......................499
      InitChild (часто переопределяется)............................499
      InitClientWindow (иногда переопределяется)....................499
      SetupWindow (часто переопределяется)..........................499
      Store.........................................................500

       B.Pascal 7 & Objects/OW      - 18 -

      TileChildren (переопределяется редко).........................500
      Тип TMessage                                      модуль
       OWindows.....................................................501
      Тип TMultiSelRec                                  модуль
       ODialogs.....................................................501
      TObject                                            модуль
       Objects......................................................502
      Методы........................................................502
      Init..........................................................502
      Free..........................................................502
      Done..........................................................502
      Тип TPaintStruct                                  модуль
       WinTypes.....................................................502
      Тип TPicResult                                    модуль
       Validate.....................................................503
      TPrintDialog                                      модуль
       OPrinter.....................................................504
      Поля..........................................................505
      Методы........................................................507
      Init..........................................................507
      Тип TPrintDialogRec                               модуль
       OPrinter.....................................................508
      TPrinter                                          модуль
       OPrinter.....................................................510
      Поля..........................................................510
      Методы........................................................512
      Init..........................................................512
      Done (переопределяется редко).................................512
      ClearDevice...................................................512
      Configure.....................................................512
      GetDC (переопределяется редко)................................512
      InitAbortDialog (переопределяется редко)......................513
      InitPrintDialog (переопределяется редко)......................513
      InitSetupDialog (переопределяется редко)......................513
      Print.........................................................513
      ReportError (иногда переопределяется).........................514
      SetDevice.....................................................514
      Setup.........................................................514
      TPrinterAbortDlg                                  модуль
       OPrinter.....................................................515
      Методы........................................................516
      Init..........................................................516
      SetupWindow (переопределяется редко)..........................516
      WMCommand (переопределяется редко)............................517
      TPrinterSetupDlg                                  модуль
       OPrinter.....................................................518
      Поля..........................................................519
      Методы........................................................519
      Init..........................................................519
      Done (переопределяется редко).................................520
      Cancel (никогда не переопределяется)..........................520
      IDSetup (никогда не переопределяется).........................520
      TransferData (никогда не переопределяется)....................520

       B.Pascal 7 & Objects/OW      - 19 -

      TPrintout                                         модуль
       OPrinter.....................................................521
      Поля..........................................................521
      Методы........................................................522
      Init..........................................................522
      Done..........................................................522
      BeginPrinting.................................................523
      EndDocument...................................................523
      EndPrinting...................................................523
      GetDialogInfo.................................................523
      GetSelection..................................................524
      HasNextPage...................................................524
      PrintPage.....................................................524
      SetPrintParams................................................524
      TPXPictureValidator                                модуль
       Validate.....................................................526
      Поля..........................................................526
      Методы........................................................526
      Init..........................................................526
      Load..........................................................527
      Done..........................................................527
      Error.........................................................527
      ISValidInput..................................................527
      IsInvalid.....................................................527
      Picture.......................................................528
      Store.........................................................529
      TRadioButton                                      модуль
       ODialogs.....................................................530
      Методы........................................................531
      Init (иногда переопределяется)................................531
      GetGlassName..................................................532
      TRangeValidator                                   модуль
       Validate.....................................................533
      Поля..........................................................533
      Методы........................................................533
      Init..........................................................534
      Load..........................................................534
      Error.........................................................534
      IsValid.......................................................534
      Store.........................................................535
      Transfer......................................................535
      TScrollBar                                        модуль
       ODialogs.....................................................536
      Поля..........................................................538
      Методы........................................................538
      Init..........................................................538
      InitResource..................................................538
      Load..........................................................539
      DeltaPos (переопределяется редко).............................539
      GetClassName (никогда не переопределяется)....................539
      GetPosition (переопределяется редко)..........................539
      GetRange (переопределяется редко).............................539
      SBBottom (переопределяется редко).............................540

       B.Pascal 7 & Objects/OW      - 20 -

      SBLineDown (переопределяется редко)...........................540
      SBLineUp (переопределяется редко).............................540
      SBPageDown (переопределяется редко)...........................540
      SBPageUp (переопределяется редко).............................540
      SBThumbPosition (переопределяется редко)......................541
      SBThumbTrack (иногда переопределяется)........................541
      SBTop (переопределяется редко)................................541
      SetPosition (переопределяется редко)..........................541
      SetRange (переопределяется редко).............................541
      SetupWindow (иногда переопределяется).........................542
      Store.........................................................542
      Transfer (иногда переопределяется)............................542
      TScroller                                          модуль
       OWindow......................................................543
      Поля..........................................................543
      Методы........................................................546
      Init..........................................................546
      Load..........................................................546
      Done..........................................................546
      AutoScroll (иногда переопределяется)..........................547
      BeginView.....................................................547
      EndView (иногда переопределяется).............................547
      HScroll (никогда не переопределяется).........................547
      IsVisibleRect (переопределяется редко)........................547
      ScrollBy (переопределяется редко).............................547
      ScrollTo (иногда переопределяется)............................548
      SetPageSize (иногда переопределяется).........................548
      SetRange (никогда не переопределяется)........................548
      SetBarRange (никогда не переопределяется).....................548
      SetUnits......................................................548
      Store.........................................................548
      VScroll (никогда не переопределяется).........................549
      TSortedCollection                                  модуль
       Objects......................................................550
      Поля..........................................................550
      Методы........................................................551
      Load..........................................................551
      Compare (всегда переопределяется).............................551
      IndexOf (никогда не переопределяется).........................551
      Insert (никогда не переопределяется)..........................552
      KeyOf (иногда переопределяется)...............................552
      Search (переопределяется редко)...............................552
      Store.........................................................553
      TStatic                                           модуль
       ODialogs.....................................................554
      Поля..........................................................555
      Методы........................................................555
      Init..........................................................556
      InitResource..................................................556
      Load..........................................................556
      Clear (переопределяется редко)................................556
      GetClassName (переопределяется редко).........................556
      GetText (переопределяется редко)..............................557

       B.Pascal 7 & Objects/OW      - 21 -

      SetText (переопределяется редко)..............................557
      Store.........................................................557
      Transfer (иногда переопределяется)............................557
      TStrCollection                                     модуль
       Objects......................................................558
      Методы........................................................558
      Compare (иногда переопределяется).............................558
      FreeItem (переопределяется редко).............................559
      GetItem (переопределяется редко)..............................559
      PutItem (переопределяется редко)..............................559
      TStream                                             метод
       Objects......................................................560
      Поля..........................................................560
      ErrorInfo (чтение/запись).....................................560
      Методы........................................................561
      CopyFrom......................................................561
      Error (иногда переопределяется)...............................561
      Flush (иногда переопределяется)...............................561
      Get...........................................................562
      GetPos (всегда переопределяется)..............................562
      GetSize (всегда переопределяется).............................562
      Put...........................................................562
      Read (всегда переопределяется)................................563
      ReadStr.......................................................563
      Reset.........................................................563
      Seek (всегда переопределяется)................................563
      StrRead.......................................................564
      Truncate (всегда переопределяется)............................564
      Write (всегда переопределяется)...............................564
      WriteStr......................................................564
      Тип TStreamRec                                     модуль
       Objects......................................................565
      TStringLookupValidator                            модуль
       Validate.....................................................567
      Поля..........................................................567
      Методы........................................................567
      Init..........................................................567
      Load..........................................................568
      Done..........................................................568
      Error.........................................................568
      Lookup........................................................568
      NewStringList.................................................568
      Store.........................................................569
      TValidator                                        модуль
       Validate.....................................................570
      Поля..........................................................570
      Status........................................................570
      Методы........................................................570
      Init..........................................................570
      Load..........................................................571
      Error.........................................................571
      IsValid.......................................................571
      IsValidInput..................................................571

       B.Pascal 7 & Objects/OW      - 22 -

      Store.........................................................572
      Transfer......................................................572
      Valid.........................................................573
      Тип TVTransfer                                    модуль
       Validate.....................................................574
      Тип TWndClass                                     модуль
       WinTypes.....................................................574
      TWindow                                           модуль
       OWindows.....................................................576
      Поля..........................................................577
      Методы........................................................578
      Init (часто переопределяется).................................578
      InitResource..................................................579
      Load..........................................................579
      Done (часто переопределяется).................................579
      Create........................................................579
      DefWndProc (никогда не переопределяется)......................580
      FocusChild....................................................580
      GetID (переопределяется редко)................................580
      GetWindowClass (часто переопределяется).......................580
      Paint (часто переопределяется)................................580
      SetCaption....................................................581
      SetupWindow (часто переопределяется)..........................581
      Store.........................................................581
      UpdateFocusChild..............................................581
      WMActivate (иногда переопределяется)..........................582
      WMCreate......................................................582
      WMHScroll (иногда переопределяется)...........................582
      WMLButtonDown (иногда переопределяется).......................582
      WMMDIActivate.................................................583
      WMMove........................................................583
      WMPaint (переопределяется редко)..............................583
      WMSize (иногда переопределяется)..............................583
      WMSysCommand..................................................583
      WMVScroll (иногда переопределяется)...........................584
      Тип TWindowAttr                                   модуль
       OWindows.....................................................585
      TWindowPrintout                                   модуль
       OPrinter.....................................................586
      Поля..........................................................586
      Методы........................................................586
      Init..........................................................586
      GetDialogInfo.................................................587
      PrintPage.....................................................587
      TWindowsObject                                     модуль
       OWindows.....................................................588
      Поля..........................................................588
      Методы........................................................590
      Init (часто переопределяется).................................590
      Load..........................................................590
      Done (часто переопределяется).................................590
      AddChild......................................................591
      At............................................................591

       B.Pascal 7 & Objects/OW      - 23 -

      CanClose (иногда переопределяется)............................591
      ChildWithID (никогда не переопределяется).....................591
      CloseWindow...................................................591
      CMExit........................................................591
      Create (никогда не переопределяется)..........................592
      CreateChildren................................................592
      DefChildProc (иногда переопределяется)........................592
      DefCommandProc (иногда переопределяется)......................592
      DefNotificationProc (иногда переопределяется).................593
      DefWndProc....................................................593
      Destroy (никогда не переопределяется).........................593
      Disable.......................................................593
      DisableAutoCreate.............................................594
      DisableTransfer...............................................594
      DispatchScroll (никогда не переопределяется)..................594
      Enable........................................................594
      EnableAutoCreate..............................................594
      EnableKBHandler...............................................595
      EnableTransfer................................................595
      FirstThat.....................................................595
      Focus.........................................................596
      ForEach.......................................................596
      GetChildPtr...................................................596
      GetChildren...................................................596
      GetClassName (иногда переопределяется)........................597
      GetClient (никогда не переопределяется).......................597
      GetId (переопределяется редко)................................597
      GetSiblingPtr.................................................597
      GetWindowClass (иногда переопределяется)......................598
      IndexOf.......................................................598
      IsFlagSet.....................................................598
      Next..........................................................598
      Previous......................................................598
      PutChildPtr...................................................599
      PutChildren...................................................599
      PutSiblingPtr.................................................599
      Register (никогда не переопределяется)........................599
      RemoveChild...................................................600
      SetFlags......................................................600
      SetupWindow (часто переопределяется)..........................600
      Show (никогда не переопределяется)............................600
      Store.........................................................601
      Transfer (иногда переопределяется)............................601
      TransferData (иногда переопределяется)........................601
      WMActivate (иногда переопределяется)..........................601
      WMClose (иногда переопределяется).............................602
      WMCommand (переопределяется редко)............................602
      WMDestroy (переопределяется редко)............................602
      WMHScroll (переопределяется редко)............................602
      WMNCDestroy (никогда не переопределяется).....................602
      WMQueryEndSession.............................................603
      WMVScroll (переопределяется редко)............................603
      Тип TWordArray                                     модуль

       B.Pascal 7 & Objects/OW      - 24 -

       Objects......................................................603
      Константы voXXXX                                  модуль
       Validate.....................................................604
      Константы vsXXXX                                  модуль
       Validate.....................................................605
      Константы wb_XXXX                                 модуль
       OWindows.....................................................606
      Константы wm_XXXX                                 модуль
       OWindows.....................................................606
      Тип WordRec                                        модуль
       Objects......................................................606
      Стили окна ws_XXXX                                модуль
       WinTypes.....................................................608

         B.Pascal 7 & Objects/OW      - 25 -

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

             В данном  руководстве  вы  найдете  полную  документацию  по
        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);

             * реорганизованные главы, посвященные иерархии и объектам;

         B.Pascal 7 & Objects/OW      - 26 -


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

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

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

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

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

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

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

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

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

        вателя".

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

             "Руководство по     программированию     с    использованием
        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.



         B.Pascal 7 & Objects/OW      - 28 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                         Часть 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 і Специализированные элементы
             АДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW      - 29 -

             Отправным пунктом для всех программ,  которые  вы  пишете  с
        применением 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.  Он позволяет также задать имя приложения (поле объек-

         B.Pascal 7 & Objects/OW      - 30 -

        та) '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;


         B.Pascal 7 & Objects/OW      - 31 -

             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.



         B.Pascal 7 & Objects/OW      - 32 -

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

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

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

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

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

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

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

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



         B.Pascal 7 & Objects/OW      - 33 -

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

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

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

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

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

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

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

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

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

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

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

             Теперь у вас есть некоторое представление о том,  что содер-

         B.Pascal 7 & Objects/OW      - 34 -

        жит оконный объект, и вы можете создать новый оконный тип, произ-
        водный от  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.

             Аналогично, когда пользователь щелкает правой  кнопкой  "мы-

         B.Pascal 7 & Objects/OW      - 35 -

        ши", основной  оконный  объект получает сообщение 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;

         B.Pascal 7 & Objects/OW      - 36 -


                   Примечание: Программы, которые вызывают 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) принимается объектом ос-
        новного окна.



         B.Pascal 7 & Objects/OW      - 37 -

                            Переопределение 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;


         B.Pascal 7 & Objects/OW      - 38 -


             Теперь когда пользователи попытаются закрыть 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;

         B.Pascal 7 & Objects/OW      - 39 -


             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);

         B.Pascal 7 & Objects/OW      - 40 -

             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.



         B.Pascal 7 & Objects/OW      - 41 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                               Глава 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 для отображения в  окне  любого

         B.Pascal 7 & Objects/OW      - 42 -

        текста или графики.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

             DragDC := GetDC(HWindow);

         B.Pascal 7 & Objects/OW      - 43 -

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

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

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

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

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

             ReleaseDC(HWindow, DragDC);

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

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

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



         B.Pascal 7 & Objects/OW      - 44 -

                                  Координаты 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,

         B.Pascal 7 & Objects/OW      - 45 -

        поля которой  содержат  параметр  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, которая  приводит  к повторному отображению всего

         B.Pascal 7 & Objects/OW      - 46 -

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

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

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



         B.Pascal 7 & Objects/OW      - 47 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                           Шаг 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, а затем реализуем простую графическую программу.



         B.Pascal 7 & Objects/OW      - 48 -

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

             Мы уже видели,  что щелчок левой кнопкой "мыши" дает  в  ре-
        зультате сообщение 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
        она реагирует завершением процесса рисования (освобождая контекст
        дисплея).



         B.Pascal 7 & Objects/OW      - 49 -

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

             Нужно помнить о том, что после 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;



         B.Pascal 7 & Objects/OW      - 50 -

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

             В 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.



         B.Pascal 7 & Objects/OW      - 51 -

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

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

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

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

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

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

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

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

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


         B.Pascal 7 & Objects/OW      - 52 -

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

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

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

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

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

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

             program Steps;

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

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

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

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

             Так как  диалоговое окно ввода появляется только на короткое
        время, а вся обработка выполняется одним методом, вам нет необхо-
        димости определять его как поле TStepWindows. Оно может существо-
        вать в виде локальной переменной метода WMRButtonDown.  Все пост-
        роение и  отмену  объекта  диалогового окна вы можете выполнять в

         B.Pascal 7 & Objects/OW      - 53 -

        рамках метода 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;

         B.Pascal 7 & Objects/OW      - 54 -

                 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);

         B.Pascal 7 & Objects/OW      - 55 -

                    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 вы создадите  собственное  диалоговое  окно  и
        объект пера  и используете их для более эффективного графического
        отображения.



         B.Pascal 7 & Objects/OW      - 56 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                          Глава 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 і
                            АДДДДДДДДДДДДДДДДДДДДДДДЩ

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

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

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

             * Загрузка файла ресурса из программы.

         B.Pascal 7 & Objects/OW      - 57 -


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

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

             Меню прикладной программы - это не отдельный объект, а атри-
        бут основного  окна.  Все  оконные объекты имеют набор атрибутов,
        записанных в поле записи 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.


         B.Pascal 7 & Objects/OW      - 58 -

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

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

             {$R STEPS.RES}

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

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


         B.Pascal 7 & Objects/OW      - 59 -


             На Рис.  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 с ресурсом меню.



         B.Pascal 7 & Objects/OW      - 60 -

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

             Получить ресурс  меню можно с помощью вызова функции 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. Однако, чтобы при выборе элементов меню вы-
        полнялись какие-либо действия,  вы должны перехватывать сообщения
        меню и  реагировать на них.  Если вы не определили реакцию на ко-
        манду меню,  то можете выбирать элемент меню,  но при этом ничего
        не происходит.



         B.Pascal 7 & Objects/OW      - 61 -

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

             Когда пользователь выбирает элемент меню,  окно,  к которому
        присоединено меню,    получает   командное   сообщение   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 - это специальное  смещение,  ис-
        пользуемое только для определения методов реакции для команд меню
        и командных клавиш.



         B.Pascal 7 & Objects/OW      - 62 -

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

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

             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.


         B.Pascal 7 & Objects/OW      - 63 -

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

             Теперь для  каждого выбора в меню у вас есть метод,  который
        будет вызываться в ответ на соответствующую команду. Выбор коман-
        ды 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);

         B.Pascal 7 & Objects/OW      - 64 -

             end;

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

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

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

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


         B.Pascal 7 & Objects/OW      - 65 -


             Вы будете выводить файловое диалоговое окно в ответ на выбор
        пользователем команды 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  файлового  диалогового  блока
        требует трех шагов:

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



         B.Pascal 7 & Objects/OW      - 66 -

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

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

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

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

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

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

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

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

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

             StrCopy(FileName, '*.PTS');


         B.Pascal 7 & Objects/OW      - 67 -

             Расширение .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.



         B.Pascal 7 & Objects/OW      - 68 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                         Шаг 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 использует для представления
        диалогового блока объект.

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

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



         B.Pascal 7 & Objects/OW      - 69 -

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

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

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

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

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

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



         B.Pascal 7 & Objects/OW      - 70 -

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

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

             Конструктор объекта диалогового блока выглядит как конструк-
        тор оконного объекта,  воспринимающий два параметра. В обоих слу-
        чаях первый параметр - это указатель на объект порождающего окна.
        Второй параметр (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')));

             Естественно, нужно определить команду для вывода диалогового

         B.Pascal 7 & Objects/OW      - 71 -

        блока 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 мы создадим более сложное диалоговое  окно  с  нес-
        колькими управляющими элементами.



         B.Pascal 7 & Objects/OW      - 72 -

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

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

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



         B.Pascal 7 & Objects/OW      - 73 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                         Глава 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 предохраняют вас от мелких де-

         B.Pascal 7 & Objects/OW      - 74 -

        талей, связанных с созданием окна.

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

             Хотя 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 позволяют

         B.Pascal 7 & Objects/OW      - 75 -

        сохранять объекты пера в потоке.

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

             Наиболее интересную  работу  выполняют  процедуры  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 объекта пера, поскольку объект пера может управ-
        лять цветом и стилем наряду с размером).



         B.Pascal 7 & Objects/OW      - 76 -

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

             До сих  пор  вы  использовали  достаточно простой диалоговый
        блок (см. блок 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;

         B.Pascal 7 & Objects/OW      - 77 -

             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 управляющие  объекты  поясняются  в
        следующем разделе.

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

             Если вашей программе  требуется непосредственно  взаимодейс-
        твовать с  управляющими  объектами  в  диалоговом окне (например,
        чтобы поместить элементы в блок списка или определить выбор кноп-
        ки с независимой фиксацией),  с этими управляющими элементами по-

         B.Pascal 7 & Objects/OW      - 78 -

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

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

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

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

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

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



         B.Pascal 7 & Objects/OW      - 79 -

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

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

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

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

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

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

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

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

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


         B.Pascal 7 & Objects/OW      - 80 -

             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;

         B.Pascal 7 & Objects/OW      - 81 -

             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;

         B.Pascal 7 & Objects/OW      - 82 -

             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.



         B.Pascal 7 & Objects/OW      - 83 -

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

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

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

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

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

                            Шаг 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 сообщает своим оконным объектам, ког-

         B.Pascal 7 & Objects/OW      - 84 -

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

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

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

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

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

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

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

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

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

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


         B.Pascal 7 & Objects/OW      - 85 -

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

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

             Чтобы сохранить рисунок в  виде  набора  линий,  добавьте  в
        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;

         B.Pascal 7 & Objects/OW      - 86 -

                  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 нужно отобра-
        зить каждую его точку.



         B.Pascal 7 & Objects/OW      - 87 -

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

             Чтобы сохранять  линии  в виде объектов,  вы должны изменить
        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 модификации не требует.  Вам не нужно уничтожать
        все объекты линий при очистке отображаемого окна, поэтому добавь-

         B.Pascal 7 & Objects/OW      - 88 -

        те в 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;

         B.Pascal 7 & Objects/OW      - 89 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                          Шаг 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.


         B.Pascal 7 & Objects/OW      - 90 -

             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
                  if 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;

         B.Pascal 7 & Objects/OW      - 91 -


             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;

         B.Pascal 7 & Objects/OW      - 92 -


             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);

         B.Pascal 7 & Objects/OW      - 93 -

               TheFile.Done;
               IsNewFile := False;
               HasChanged := False;
             end;



         B.Pascal 7 & Objects/OW      - 94 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                          Шаг 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.

             Это все, что обычно приходится делать для инициализации объ-

         B.Pascal 7 & Objects/OW      - 95 -

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


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

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

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

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

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

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

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

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

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

             Обычно при печати документа вашей прикладной программе нужно
        выполнять итерации процесса печати для каждой страницы документа.
        Так как окно имеет только один образ,  при печати окна это не яв-
        ляется необходимым.

         B.Pascal 7 & Objects/OW      - 96 -


             Таким образом,  печать также проста,  как ориентация  метода
        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  и  обеспечивает
        доступ к диалоговому окну конфигурации устройства.

         B.Pascal 7 & Objects/OW      - 97 -


             Чтобы вывести диалоговое окно установки принтера, ваша прик-
        ладная программа вызывает метод 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.  Это дает пользователю возможность доступа ко
        всем установленным принтерам.



         B.Pascal 7 & Objects/OW      - 98 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                           Глава 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 і
                            АДДДДДДДДДДДДДДДДДДДДДДДЩ

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

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

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


         B.Pascal 7 & Objects/OW      - 99 -

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

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

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

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

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

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

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

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

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


             Так как  основное окно должно посылать команды окну палитры,
        потребуется указатель на это окно, поэтому добавьте в 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);
                 .
                 .
                 .
               PenPalette := New(PPenPalette, Init(@Self, 'Pan Palette');
             end;

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

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

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

             Каждый оконный  объект  имеет  список  своих  дочерних окон,

         B.Pascal 7 & Objects/OW     - 101 -

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



         B.Pascal 7 & Objects/OW     - 102 -

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

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

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

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

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

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

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

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

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

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



         B.Pascal 7 & Objects/OW     - 103 -

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

             Дочерние окна, отличные от тех, которые были созданы и выве-
        дены по умолчанию их порождающими окнами (этот процесс управляет-
        ся с помощью 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 вы добавили к основному окну независимое  дочернее
        окно. Теперь вы добавите зависимые дочерние окна, которые называ-
        ются управляющими элементами. Порождающим окном этих  управляющих
        элементов является  окно палитры пера.  Нужно помнить о том,  что

         B.Pascal 7 & Objects/OW     - 104 -

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

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

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

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

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

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

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

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


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

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

             Управляющие элементы окон задаются определением объекта. По-
        рождающее окно управляет их поведением через методы, определенные
        объектами управляющих  элементов ObjectWindows.  Например,  чтобы

         B.Pascal 7 & Objects/OW     - 105 -

        получить следующий элемент,  который пользователь выбрал в  блоке
        списка, вызовите  метод  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 порождающего окна, можно получить доступ к объек-
        там управляющих элементов дочерних окон,  не записанных в  полях,
        но гораздо удобнее делать это с помощью полей.


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

             Любой тип окна,  который имеет объекты управляющих элементов

         B.Pascal 7 & Objects/OW     - 106 -

        (или другое дочернее окно) должен определять для построения своих
        объектов управляющих элементов конструктор 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 мы определим реакцию на события уп-
        равляющего элемента.


                               Сокрытие вместо закрытия
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         B.Pascal 7 & Objects/OW     - 107 -


             Если вы дважды щелкните "мышью" в блоке системного меню  па-
        литры пера,  оно  исчезнет.  Выбор  команды 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 вы  можете  перекомпилировать  программу и получить доступ к
        диалоговым блокам.  Без  каких-либо  других усилий вы существенно

         B.Pascal 7 & Objects/OW     - 108 -

        улучшите внешний вид программы и ее интерфейса.

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



         B.Pascal 7 & Objects/OW     - 109 -

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

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

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

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

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

                      Нумерация ресурсов графических изображений
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         B.Pascal 7 & Objects/OW     - 110 -


             Единственная сложная часть в определении графических изобра-
        жений для командных кнопок - это присваивание идентификаторов ре-
        сурсов. Управляющие элементы 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}



         B.Pascal 7 & Objects/OW     - 111 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         Шаг 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;

         B.Pascal 7 & Objects/OW     - 112 -

             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 "Сообщения окон".

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

             Как и  в случае методов реакции на сообщения,  имена которым
        присваиваются по сообщениям, методы, основанные на дочерних иден-
        тификаторах, также  должны именоваться по идентификаторам сообще-
        ний. Так как две командные кнопки,  на которые вы хотите реагиро-

         B.Pascal 7 & Objects/OW     - 113 -

        вать, имеют идентификаторы 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.



         B.Pascal 7 & Objects/OW     - 114 -

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

             Теперь, когда у вас есть окно палитры,  вам необходим просто
        способ вывода на экран и выбора перьев в палитре.  Для  этого  вы
        можете использовать  относительно простой потомок 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 интерпретирует  щелчки

         B.Pascal 7 & Objects/OW     - 115 -

        "мышью" для  выбора  перьев  из  палитры.  Наконец,  Paint рисует
        "кнопки", представляющие перья в наборе.

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



         B.Pascal 7 & Objects/OW     - 116 -

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

             Построение и  уничтожение объекта палитры выполняется доста-
        точно просто. Конструктор 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;

         B.Pascal 7 & Objects/OW     - 117 -

             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.



         B.Pascal 7 & Objects/OW     - 118 -

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

             В последнем разделе вы отвечали на сообщения от 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 на об-
        ратные. При наличии выбранного в палитре пера  оно  удаляется  из
        набора, а  набор уплотняется таким образом,  чтобы перья размеща-
        лись непрерывно.  Затем он указывает, что в данный момент выбран-

         B.Pascal 7 & Objects/OW     - 119 -

        ных перьев  нет (поскольку  выбранное  перо только что удалено) и
        запрещает командную кнопку 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,  то объекту палитры пришлось бы искать  их
        по идентификаторам  и  посылать им сообщения,  либо нужно было бы
        послать сообщение порождающему окну, которое в свою очередь долж-
        но каким-то образом связываться с командными кнопками.



         B.Pascal 7 & Objects/OW     - 120 -

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

             За все,  что мы насоздавали в  объекте  палитры,  приходится
        расплачиваться, когда приходит  момент  отображать  ее на экране.
        Поскольку перья хранятся в наборе,  для отображения каждого  пера
        вы легко  можете  выполнять итерацию.  В самом деле,  метод 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 позволяет создавать кон-

         B.Pascal 7 & Objects/OW     - 121 -

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

             Метод 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;

                                     Что дальше?

         B.Pascal 7 & Objects/OW     - 122 -

        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

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

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

             * Отмена.

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

             * Прокрутка.

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

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

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

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

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

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

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

        ний, либо даже в другой рисунок.


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

             Вы можете  также отметить,  что при щелчке "мышью" между па-
        литрой и основным окном, окно, где вы нажимаете кнопку, становит-
        ся активным  (получает активную рамку),  а другие окна становятся
        неактивными. Если вы часто перемещаетесь между двумя окнами  (что
        может иметь  место  при работе с палитрой),  это может показаться
        весьма раздражающим.  Чтобы предотвратить это явление,  вам нужно
        перехватывать  передачу  в окна сообщений 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 прокручивает изображение,  так что вы
        будете видеть другие части рисунка.



         B.Pascal 7 & Objects/OW     - 124 -

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


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

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

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

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

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

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

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

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

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



         B.Pascal 7 & Objects/OW     - 125 -

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

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

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

             ЪДДДДДДДДДДДДДДДДї
             і    TObject     і
             АДДДДДДДВДДДДДДДДЩ
                ЪДДДДБДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДї
        ЪДДДДДДДБДДДДДДДДї ЪДДДДДДДДБДДДДДДДї      ЪДДДДДДДБДДДДДДДДї   і
        і   TPrintout    і і    TPrinter    і      і TWindowsObject і   і
        АДДДДДДДВДДДДДДДДЩ АДДДДДДДДДДДДДДДДЩ      АДДДДДДДВДДДДДДДДЩ   і
                ГДДДДДДДДДДДДДДДДДДДї                      і            і
        ЪДДДДДДДБДДДДДДДДї ЪДДДДДДДДБДДДДДДДї  ЪДДДДДДДДДДДЩ            і
        і TEditPrintout  і і TWindowPrintoutі  і           ЪДДДДДДДДДДДДґ
        АДДДДДДДДДДДДДДДДЩ АДДДДДДДДДДДДДДДДЩ  і           і            і
                                               і   ЪДДДДДДДБДДДДДДДДї   і
               ЪДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДЩ   і  TApplication  і   і
               і                    і              АДДДДДДДДДДДДДДДДЩ   і
        ЪДДДДДДБДДДДДДДДДї ЪДДДДДДДДБДДДДДДДї              ЪДДДДДДДДДДДДЩ
        і    TDialog     і і   TWindow      і              і
        АДДДДДДВДДДДДДДДДЩ АДДДДДДДДВДДДДДДДЩ      ЪДДДДДДДБДДДДДДДДї
               і                    і              і   TScroller    і
               і                    і              АДДДДДДДДДДДДДДДДЩ
               і                    АДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
               ГДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДї                 і
        ЪДДДДДДБДДДДДДДДДї ЪДДДДДДДБДДДДДДДДї  і                 і
        і  TFileDialog   і і TInputDialog   і  і                 і
        АДДДДДДДДДДДДДДДДЩ АДДДДДДДДДДДДДДДДЩ  і                 і
               ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДЩ                 і
        ЪДДДДДДБДДДДДДДДДДДДї         і                          і
        іTPrinterAbortDialogі         ГДДДДДДДДДДДДї             і
        АДДДДДДДДДДДДДДДДДДДЩ         і            і             і
                                      і   ЪДДДДДДДДБДДДДДДДї     і
                ЪДДДДДДДДДДДДДДДДДДДДДґ   і  TPrintDialog  і     і
        ЪДДДДДДДБДДДДДДДДї            і   АДДДДДДДДДДДДДДДДЩ     і
        іTPrinterSetupDlgі            АДДДДДДДДДДДДї             і
        АДДДДДДДДДДДДДДДДЩ                         і             і
                                          ЪДДДДДДДДБДДДДДДДї     і
                                          і   TDlgWindow   і     і
                                          АДДДДДДДДДДДДДДДДЩ     і


         B.Pascal 7 & Objects/OW     - 126 -


                                                                 і
                ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДВДДДДДДДДДДґ
        ЪДДДДДДДБДДДДДДДДї ЪДДДДДДДБДДДДДДДДї ЪДДДДДДДБДДДДДДДДї і
        і    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.


         B.Pascal 7 & Objects/OW     - 127 -


             ЪДДДДДДДДДДДДДДДДї
             і    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,  которое вы
        пишете, будет определять объектный тип приложения, производный от

         B.Pascal 7 & Objects/OW     - 128 -

        TApplication. Объекты  приложения  подробно описываются в Главе 8
        "Объекты приложения".

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

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

                                 Объекты Windows

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

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

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

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

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

                                   Объекты MDI

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

                          Объекты проверки допустимости

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

                                Объекты принтера


         B.Pascal 7 & Objects/OW     - 129 -

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

                            Объекты наборов и потоков

             Модуль Object включает в себя многочисленные объекты, реали-
        зующие гибкие структуры данных и потоки,  позволяющие считывать и
        записывать объекты.  Наборы описываются в Главе 19,  а потоки - в
        Главе 20.



         B.Pascal 7 & Objects/OW     - 130 -

                                 Файлы 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.                                         і
        АДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ



         B.Pascal 7 & Objects/OW     - 131 -

                                    Файлы ресурсов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Модули 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.                      і
        АДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ



         B.Pascal 7 & Objects/OW     - 132 -

                               Взаимодействие с 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.



         B.Pascal 7 & Objects/OW     - 133 -

                                Доступ к функциям 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.



         B.Pascal 7 & Objects/OW     - 134 -

                            Комбинирование констант стилей
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Функции Windows, позволяющие получить интерфейсные элементы,
        требуют обычно некоторого параметра типа Word или Longint.  Иден-
        тификаторы констант стилей состоят из двухбуквенного  мнемоничес-
        кого префикса,  за  которым  следует подчеркивание и описательное
        имя. Например,  ws_Popup - это константа стиля окна (ws_ означает
        стиль окна - window  style").

                   Примечание: В  Windows  определены сотни констант сти-
              лей,  которые  перечислены  в  Главе  21   "Справочник   по
              ObjectWindows".

             Часто эти  стили  комбинируются  для  получения другого сти-
        ля. Например,  в случае функции MessageBox вы можете  передать  в
        качестве параметра стиля mb_YesNo или mb_IconQuestion. Этот стиль
        дает окно сообщений с двумя командными кнопками Yes и No  и  пик-
        торгаммой вопросительного  знака.  Поразрядная операция or факти-
        чески комбинирует две константы бит за битом.  Полученный  в  ре-
        зультате стиль представляет собой комбинацию обоих стилей.

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

                                 Типы функций Windows
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Ниже перечислены виды функций Windows, которые вы можете ис-
        пользовать в своих программах ObjectWindows.

                  Функции интерфейса с администратором Windows

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

                               Функции интерфейса
                        с графическими устройствами (GDI)

             Эти функции выводят на разнообразные устройства (включая эк-
        ран и принтер) текст, графику и битовые массивы. Они не привязаны
        к конкретному устройству и являются независимыми от устройства.

               Функции интерфейса со служебными функциями системы

             Эти функции  работают  с  широким  диапазоном системных уст-
        ройств, включая управление памятью, взаимодействие с операционной
        системой, администрирование ресурсов и коммуникации.



         B.Pascal 7 & Objects/OW     - 135 -

                              Функции системного вызова
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             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.



         B.Pascal 7 & Objects/OW     - 136 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                             Глава 8. Объекты приложения
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             При разработке приложения ObjectWindows  вам  нужно  сначала
        определить объект  приложения,  производный от типа ObjectWindows
        TApplication. Этот объект инкапсулирует следующее поведение  при-
        ложения ObjectWindows:

             * Создание и вывод основного окна приложения.

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

             * Инициализацию  каждого  экземпляра  приложения,  например,
               загрузку таблицы оперативных клавиш.

             * Обработку сообщений Windows.

             * Закрытие приложения.

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

                                Минимальные требования
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Чтобы ваше программа ObjectWindows стала рабочим приложением
        Windows, она должна в своем основном блоке begin..end делать сле-
        дующее:

             - выполнять инициализацию;

             - обрабатывать сообщения;

             - по требованию завершать работу.

             Используемый по  умолчанию объект выполняет эти задачи путем
        вызова трех его методов:  Init,  Run и Done.  Основной блок любой
        программы ObjectWindows содержит обычно эти три метода. Чтобы из-
        менить поведение по умолчанию, методы нужно переопределить.

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

             Когда программа выполняется, ObjectWindows поддерживает гло-
        бальную переменную Application - указатель на объект  приложения.
        Этот указатель позволяет подпрограммам вне объекта приложения об-
        ращаться к его полям и методам. По умолчанию Application устанав-
        ливается  в  @Self конструктором объекта приложения и в nil дест-

         B.Pascal 7 & Objects/OW     - 137 -

        руктором объекта.

                                Минимальное приложение
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Приведем пример минимального приложения 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.

         B.Pascal 7 & Objects/OW     - 138 -

                                      Метод Run
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             MessageLoop вызывает несколько методов, обрабатывающих конк-
        ретные поступающие сообщения (см. далее).

                                   Деструктор Done
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Done - это деструктор объекта приложения.  Перед завершением
        работы приложения он освобождает память объекта приложения.

         ЪДДДДДДДДДДДДДДДДї     ЪДДДДДДДДДДДДДДДДДї
         і     Init       ГДДВД>і InitApplication і
         АДДДДДДДДДДДДДДДДЩ  і  АДДДДДДДДДДДДДДДДДЩ
                             і
                             і  ЪДДДДДДДДДДДДДДДДДї    ЪДДДДДДДДДДДДДДДДї
                             АД>і   InitInstance  ГДДД>і InitMainWindow і
                                АДДДДДДДДДДДДДДДДДЩ    АДДДДДДДДДДДДДДДДЩ

         ЪДДДДДДДДДДДДДДДДї     ЪДДДДДДДДДДДДДДДДДї
         і     Run        ГДДДД>і   MessageLoop   і
         АДДДДДДДДДДДДДДДДЩ     АДДДДДДДДДДДДДДДДДЩ

         ЪДДДДДДДДДДДДДДДДї
         і     Done       і
         АДДДДДДДДДДДДДДДДЩ

             Рис. 8.1 Вызовы методов, управляющие работой приложения.

                               Инициализация приложения
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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



         B.Pascal 7 & Objects/OW     - 139 -

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

             Вы должны определить метод 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 - это полнофункциональ-
        ный "скелет"  приложения,  оснащенный  только простейшим основным
        окном.



         B.Pascal 7 & Objects/OW     - 140 -

                           Специальный вывод основного окна
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Начальный вывод  основного   окна   управляется   переменной
        CmdShow модуля  System.  CmdShow  содержит одну из констант sw_ и
        передается в качестве параметра функции API  Windows  ShowWindow,
        когда приложение создает свое основное окно.

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

                           Инициализация первого экземпляра
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             Если текущим экземпляром является первый экземпляр, то конс-
        труктор Init вызывает  InitApplication.  TApplication  определяет
        заместитель метода InitApplication,  который вы можете для выпол-
        нения специальной инициализации  первого  экземпляра  переопреде-
        лить.


         B.Pascal 7 & Objects/OW     - 141 -


             Например, вы  можете  модифицировать  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;

         B.Pascal 7 & Objects/OW     - 142 -

             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).



         B.Pascal 7 & Objects/OW     - 143 -

                                Выполнение приложений
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Метод 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.

         B.Pascal 7 & Objects/OW     - 144 -


             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. Например, для проверки того, что пользователь собирает-
        ся закрыть окно, он может проверять открытые файлы.



         B.Pascal 7 & Objects/OW     - 145 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                            Глава 9. Интерфейсные объекты
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

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

                         Для чего нужны интерфейсные объекты?
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Для чего нужны интерфейсные объекты, если в Windows уже есть
        окна, диалоговые блоки и управляющие элементы?

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

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

                           Что делают интерфейсные объекты?
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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



         B.Pascal 7 & Objects/OW     - 146 -

                              Общий интерфейсный объект
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Все интерфейсные объекты ObjectWindows наследуют  из  единс-
        твенного  абстрактного  объектного  типа TWindowsObject,  который
        определяет поведение, общее для окна, диалога и объектов управля-
        ющих элементов,  видоизменяемых  и специализируемых в производных
        объектных типах TDialog, TWindow и TControl.

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

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

                            Создание интерфейсных объектов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Задание полного интерфейсного объекта с соответствующими ин-
        терфейсными элементами требует двух шагов:

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

             * Создания элемента экрана.

             Первым шагом является вызов конструктора Init, который стро-
        ит интерфейсный  объект  и устанавливает его атрибуты,  такие как
        стиль и меню.

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

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

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



         B.Pascal 7 & Objects/OW     - 147 -

                             Допустимость описателя окна
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Обычно в 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 Когда окно имеет допустимый описатель.



         B.Pascal 7 & Objects/OW     - 148 -

                                 Видимость на экране
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Создание интерфейсного объекта и соответствующего визуально-
        го элемента не обязательно означает,  что вы что-то видите на эк-
        ране.  Когда метод Create указывает Windows на создание  элемента
        экрана, Windows проверяет, включает ли стиль окна ws_Visible. Ес-
        ли да, то интерфейсный элемент будет выводиться. В противном слу-
        чае он будет скрытым.

             ws_Visible и  другие  стили  окна обычно устанавливаются или
        сбрасываются конструктором Init в поле Attr.Style объекта.

             В любой момент после создания элемента экрана вы можете  вы-
        вести или скрыть его, вызвав метод Show интерфейсного объекта.

                          Уничтожение интерфейсных объектов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Как и в случае создания интерфейсный объектов,  их уничтоже-
        ние предполагает выполнение двух шагов:

             * Уничтожение визуального интерфейсного элемента (Destroy).

             * Уничтожение интерфейсного объекта (Dispose).

             Уничтожением экранного элемента занимается метод Destroy ин-
        терфейсного объекта,  который делает следующее: он вызывает функ-
        цию Windows DestroyWindow, чтобы избавиться от элемента экрана, и
        устанавливает поле HWindow объекта в 0.  Таким образом,  проверив
        указатель, вы  можете сообщить,  связан ли еще объект с элементом
        экрана.

             Уничтожить элемент экрана вы можете без уничтожения  объекта
        (если хотите создавать и выводить его снова).

                   Примечание: Уничтожение самого окна обычно не требует-
              ся. Это делается автоматически при закрытии окна.

             Когда пользователь закрывает на экране  окно,  ObjectWindows
        обнаруживает, что данный элемент экрана уничтожен,  устанавливает
        поле HWindow соответствующего объекта в 0 и  вызывает  деструктор
        объекта Done.



         B.Pascal 7 & Objects/OW     - 149 -

                       Связь порождающего и дочернего объектов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

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

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

                                 Список дочерних окон
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Когда вы строите объект дочернего окна, то можете в качестве
        параметра конструктора Init можете задать порождающее окно  (при-
        мер вы можете найти в Главе 10). Объект дочернего окна отслежива-
        ет свое порождающее окно через указатель на его поле  Parent.  Он
        отслеживает также  объекты его дочерних окон,  сохраненные в поле
        ChildList. Дочернее окно,  на которое в данный момент  установлен
        ChildList, является последним созданным дочерним окном.



         B.Pascal 7 & Objects/OW     - 150 -

                               Построение дочерних окон
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Как и в случае интерфейсных объектов,  объекты дочерних окон
        создаются в два этапа (построение объекта и создание элемента эк-
        рана).  Объекты порожденного окна следует строить с помощью конс-
        труктора 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;

                              Уничтожение дочерних окон
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Вызов деструктора порождающего окна приводит к вызову  дест-
        рукторов всех его дочерних окон, так что вашей программе не нужно

         B.Pascal 7 & Objects/OW     - 151 -

        явно вызывать деструкторы дочернего окна.  Это же справедливо для
        метода 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

         B.Pascal 7 & Objects/OW     - 152 -

                 IsThisOneChecked := (ABox^.GetCheck = bf_Checked);
               end;

             begin
               GetFirstChecked := FirstThat(@IsThisOneChecked);
             end;



         B.Pascal 7 & Objects/OW     - 153 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                                Глава 10. Объекты окон
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             * Инициализацию оконных объектов.

             * Установку атрибутов создания.

             * Создание экранных элементов окна.

             * Установку атрибутов регистрации.

             * Использование специализированных окон.

             * Прокрутку окон.

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

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


                           Окна, которые не являются окнами
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             TWindow имеет   три  типа-потомка:  TMDIWindow,  TControl  и
        TEditWindow, так что все они также являются  оконными  объектами,
        хотя на  самом  деле это не окна в полном смысле слова.  Типы MDI
        используются в приложениях ObjectWindows,  которые  соответствуют
        стандарту многодокументального интерфейса Windows.  Об MDI и этих
        типах рассказывается в Главе 14.  TControl определяет управляющие
        элементы, такие  как командные кнопки и блоки списков (см.  Главу
        12). Чаще всего  новые  оконные  типы  являются  производными  от
        TWindow.

             Эта глава  охватывает  типы TWindow и TEditWindow и содержит
        примеры регистрации новых классов окон.



         B.Pascal 7 & Objects/OW     - 154 -

                                Где найти объекты окон
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Каждое приложение 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.



         B.Pascal 7 & Objects/OW     - 155 -

                             Установка атрибутов создания
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             Атрибуты создания оконного объекта, такие как стиль, заголо-
        вок и меню,  записываются в  поле  Attr  объекта  -  записи  типа
        TWindowAttr. TWindowAttr содержит следующие поля:

                             Атрибуты создания окна          Таблица 10.1
        ЪДДДДДДДДДДДДВДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і    Поле    і Тип          і           Использование           і
        ГДДДДДДДДДДДДЕДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і    Title   і PChar        і Строка заголовка.                 і
        і            і              і                                   і
        і    Style   і Longint      і Комбинированная константа стиля.  і
        і            і              і                                   і
        і    Menu    і HMenu        і Описатель ресурса меню.           і
        і            і              і                                   і
        і    X       і Integer      і Горизонтальная  координата  экранаі
        і            і              і верхнего левого угла окна.        і
        і            і              і                                   і
        і    Y       і Integer      і Вертикальная   координата   экранаі
        і            і              і верхнего левого угла окна.        і
        і            і              і                                   і
        і    W       і Integer      і Начальная ширина окна в  координа-і
        і            і              і тах экрана.                       і
        і            і              і                                   і
        і    H       і Integer      і Начальная высота окна в  координа-і
        і            і              і тах экрана.                       і
        і            і              і                                   і
        АДДДДДДДДДДДДБДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 156 -


        ^±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
        ±(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 вы
        обычно устанавливаете сами.




         B.Pascal 7 & Objects/OW     - 157 -

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

             При создании новых оконных типов, производных от 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  порождающего  ок-

         B.Pascal 7 & Objects/OW     - 158 -

        на):

             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 динамически на этапе выполне-

         B.Pascal 7 & Objects/OW     - 159 -

        ния.

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

             В общем  случае  порождающие  окна обычно вызывают для своих
        дочерних окон методы Init и MakeWindow. Атрибуты оконного объекта
        обычно устанавливаются  их  методами  объекта  порождающего окна.
        Поскольку основное окно приложения не  имеет  порождающего  окна,
        объект приложения строит и создает его при запуске приложения.

                            Задание атрибутов регистрации
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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



         B.Pascal 7 & Objects/OW     - 160 -

                                     Классы окон
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             С каждым  типом оконного объекта связан список атрибутов ре-
        гистрации, которые называются классом окна.  Список атрибутов ре-
        гистрации во  многом напоминает список атрибутов создания,  запи-
        санных в поле записи 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 дает окну контекст дисплея порождающего окна.

                                Поле пиктограммы

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

                                  Поле курсора


         B.Pascal 7 & Objects/OW     - 161 -

             Поле hCursor содержит описатель курсора, который использует-
        ся для представления указателя "мыши" при позиционировании его  в
        окне.

                               Поле фонового цвета

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

                      Поле используемого по умолчанию меню

             Это поле  указывает на имя ресурса меню,  которое служит ис-
        пользуемым по умолчанию меню для данного класса.  Например,  если
        вы определите  тип  EditWindow,  который всегда имеет стандартное
        меню редактирования,  то можете задать здесь это меню. Это устра-
        нит необходимость задания меню в методе Init.  Если данный ресурс
        меню имеет идентификатор 'MyMenu',  вы можете установить это поле
        следующим образом:

             AWndClass.IpszMenuName := 'MyMenu';



         B.Pascal 7 & Objects/OW     - 162 -

                    Используемые по умолчанию атрибуты регистрации
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Тип TWindow определяет класс  окна  'TurboWindow'  с  пустой
        пиктограммой, курсором-стрелкой  и  стандартным цветом окна.  Ис-
        пользуемый по умолчанию класс ObjectWindows  (TurboWindow)  имеет
        следующие атрибуты:

             * стиль:  cs_HRedraw  or  cs_VRedraw  (повторное отображение
               после каждого изменения размера);

             * пиктограмма: idi_Application (пустой прямоугольник);

             * курсор: idc_Arrow (стандартная стрелка Windows);

             * фоновый цвет: HBrush(color_Window + 1);

             * меню по умолчанию: nil.

                              Регистрация нового класса
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Чтобы изменить  атрибут  регистрации,  такой  как курсор или
        пиктограмму, вам  нужно  написать  два  метода  -  GetClassName и
        GetWindowClass - и определить новый класс окна. Каждый раз, когда
        вы изменяете атрибуты регистрации, вам нужно изменить имя класса.
        Если класс регистрации с  данным  именем  уже  зарегистрирован  в
        Windows, другие классы с тем же именем класса регистрироваться не
        будут - они получат атрибуты уже зарегистрированного класса.



         B.Pascal 7 & Objects/OW     - 163 -

                                Изменение имени класса
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             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  - это константа,  представляющая

         B.Pascal 7 & Objects/OW     - 164 -

              один из курсоров Windows.

             Кроме окон,  диалоговым окнам (не диалоговым блокам) необхо-
        димо регистрировать классы окна (см. Главу 11). Диалоговым блокам
        и управляющим элементам классы окон не требуются.



         B.Pascal 7 & Objects/OW     - 165 -

                        Использование специализированных окон
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             ObjectWindows предусматривает два потомка TWindow, являющих-
        ся специализированными окнами для редактирования текста.  Объект-
        ный тип TEditWindow обеспечивает простой текстовый  редактор,  не
        обладающий  возможностями чтения из файла или записи в него.  Тип
        TFileWindow,  наследующий из TEditWindow,  обеспечивает текстовый
        редактор с возможностями чтения/записи файлов.

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

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

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

             Метод WMSize  обеспечивает  изменение  размера  управляющего
        элемента редактирования при изменении  размера  его  окна.  Метод
        WMSetFocus обеспечивает,  что  управляющий элемент редактирования
        получает фокус ввода при получении окном сообщения wm_SetFocus.


         B.Pascal 7 & Objects/OW     - 166 -


             Показанная ниже программа 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);

         B.Pascal 7 & Objects/OW     - 167 -

             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 таким образом, чтобы оно указыва-
        ло на файловый диалоговый объект.


         B.Pascal 7 & Objects/OW     - 168 -


             Для работы с файлами 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 может прокручивать окна, когда пользователь переме-
        щает "мышь"  за область клиента окна (это называется автоматичес-
        кой прокруткой и действует даже для окон,  которые не имеют полос
        прокрутки).



         B.Pascal 7 & Objects/OW     - 169 -

                             Что такое объект прокрутки?
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             TScroller содержит значения,  определяющие, насколько должно
        прокручивается окно.  Эти  значения  записываются  в полях XUnit,
        YUnit,  XLine,  YLine,  XRange,  YRange,  XPage и  YPage  объекта
        TScroller.  Поля,  начинающиеся с буквы X,  представляют горизон-
        тальные значения, а начинающиеся с буквы Y - вертикальные.

                                Единицы прокрутки

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

             Например, если вы выводите текст с шириной символа 8 элемен-
        тов изображения и высотой 15,  то в  качестве  значений  XUnit  и
        YUnit полезно задать, соответственно, 8 и 15.

                           Строки, страницы и диапазон

             Другие атрибуты  прокрутки  - строка,  страница и диапазон -
        выражаются в единицах прокрутки.  Значения Line (строка)  и  Page
        (страница) - это число единиц, на которые выполняется прокрутка в
        ответ на запрос пользователя.  Запрос может  иметь  форму  щелчка
        кнопкой "мыши" на концах полосы прокрутки (построчная прокрутка).
        Щелчок "мышью" в самой полосе прокрутки (но не на маркере  полосы
        прокрутки) позволяет  выполнять постраничную прокрутку.  Атрибуты
        диапазона (XRange,  YRange) представляют общее число  единиц,  на
        которое можно выполнять прокрутку. Обычно этот диапазон определя-
        ется на основе размера редактируемого документа.


         B.Pascal 7 & Objects/OW     - 170 -


                            Типичный объект прокрутки

             В качестве примера рассмотрим текстовое окно редактирования.
        Если вы хотите вывести на экран текстовый файл, имеющий 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, так что без яв-
        ной необходимости  устанавливать  их  в другие значения не нужно.
        Для установки значений прокрутки на страницу также существует ис-
        пользуемая по умолчанию схема, согласно которой страница прокрут-
        ки будет соответствовать текущей высоте или ширине области клиен-
        та окна (в зависимости от направлений прокрутки).  Если вы не хо-
        тите переопределить данный механизм, переустанавливать эти значе-
        ния не требуется.



         B.Pascal 7 & Objects/OW     - 171 -

                          Задание для окна объекта прокрутки
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Чтобы задать для окна объект прокрутки,  постройте  в  конс-
        трукторе своего оконного объекта объект 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;


         B.Pascal 7 & Objects/OW     - 172 -

             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.



         B.Pascal 7 & Objects/OW     - 173 -

                         Запрещение автоматической прокрутки
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Объект TScroller может по умолчанию выполнять автоматическую
        прокрутку, но установка поля AutoMode TScroller в значение  False
        отключает это  средство.  Окно-владелец может сделать это в конс-
        трукторе после построения объекта TScroller:

             Scroller := New(PScroller, Init(@Self, 8, 15, 80, 60));
             Scroller^.AutoMode :=False;

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

                             Отслеживание полос прокрутки
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

             Scroller^.TrackMode:=False;

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



         B.Pascal 7 & Objects/OW     - 174 -

                       Модификация единиц прокрутки и диапазона
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             В приведенных  выше примерах мы предполагали,  что к моменту
        построения 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);


         B.Pascal 7 & Objects/OW     - 175 -

             Метод 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) и его высота

         B.Pascal 7 & Objects/OW     - 176 -

        (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;



         B.Pascal 7 & Objects/OW     - 177 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                         Глава 11. Объекты диалоговых блоков
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             ObjectWindows всегда  предоставляет два типа диалогов наибо-
        лее общего типа,  ввод текста  и  диалог  файла.  Кроме  того,  в
        ObjectWindows имеется тип TDlgWindow,  который позволяет вам соз-
        давать диалоги, поведение которых более похоже на окно.

             Данная глава охватывает следующие темы:

             * Использование объектов диалоговых блоков.
             * Работа с управляющими элементами в диалоговых блоках.
             * Связь объектов с управляющими элементами.
             * Связь окон с ресурсами.

                       Использование объектов диалоговых блоков
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             Подобно всплывающим окнам и управляющим элементам,  диалого-
        вые блоки являются дочерними окнами и при конструировании  добав-
        ляются к списку ChildList порождающих окон.

             Использование объекта диалогового блока предусматривает сле-
        дующие шаги:

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

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

             * Закрытие диалогового окна.



         B.Pascal 7 & Objects/OW     - 178 -

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

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

             Каждый ресурс диалогового блока имеет идентификатор, который
        может быть  номером  идентификатора  (Word)  или строкой (PChar).
        Этот идентификатор позволяет объекту диалогового блока  задавать,
        какой ресурс используется для определения его внешнего вида.

                                  Вызов конструктора
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Чтобы построить объект диалогового блока, вызовите конструк-
        тор Init.  Init воспринимает в качестве своих  параметров  указа-
        тель на порождающее окно и параметр  типа  PChar,  представляющий
        имя ресурса диалога:

             ADlg:=New(PSampleDialog, Init(@Self, 'EMPLOYEEINFO'));

             Если идентификатор задается номером,  его требуется привести
        с помощью MakeIntResource к PChar:

             Dlg := New(PSampleDialog, Init(@Self, PChar(120)));

             Так как диалоговые блоки обычно строятся внутри метода окон-
        ного объекта,  порождающее окно почти всегда задается  как  Self.
        Объекты диалоговых  блоков,  не  создаваемые  оконными объектами,
        должны иметь  в  качестве  порождающего  Applicartion^.MainWindow
        (поскольку это единственный оконный объект, всегда присутствующий
        в каждой программе ObjectWindows).

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

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



         B.Pascal 7 & Objects/OW     - 179 -

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

             Режимные диалоговые  блоки  являются наиболее общими блоками
        диалога. Аналогично генерируемым функцией 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
                   { кодирование для выборки данных и обработки диалога }

         B.Pascal 7 & Objects/OW     - 180 -

             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;

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

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

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

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


         B.Pascal 7 & Objects/OW     - 181 -

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

                                 Завершение диалогов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Каждый блок диалога должен иметь способ его закрытия пользо-
        вателем.  Чаще всего это кнопки OK и/или Cancel.  Потомки TDialog
        автоматически отреагируют на нажатие одной из этих кнопок вызовом
        метода EndDlg,  который заканчивает диалог. Вы можете разработать
        новые средства завершения диалога, если только они приводят к вы-
        зову EndDlg. Для изменения поведения при закрытии вы можете пере-
        определить методы OK и Cancel.

             Например, вы можете переопределить метод OK  таким  образом,
        что введенные данные будут копироваться в буфер, который находит-
        ся вне объекта блока диалога.  Если ввод был  осуществлен  некор-
        ректно, вы можете вывести блок сообщения или сгенерировать звуко-
        вой сигнал. Если ввод был сделан верно, вы можете вызвать EdnDlg.
        Переданное  в  EndDlg  значение становится возвращаемым значением
        ExecDialog.

             Как и в случае оконных  объектов,  объект  диалога  вызывает
        CanClose до закрытия блока диалога,  как это имело место для объ-
        ектов окна.  Вы можете переписать CanClose для учета условий зак-
        рытия,  как для блока диалога, который проверяет ввод пользовате-
        ля.  При переписывании CanClose нужно быть уверенным в  том,  что
        вызывается унаследованный от него метод,  т.к. он вызывает методы
        CanClose дочерних окон.



         B.Pascal 7 & Objects/OW     - 182 -

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

             Все блоки диалога, кроме самых простейших, имеют (как дочер-
        ние окна) несколько управляющих элементов  (например,  управления
        редактированием,  блоки списка и командные кнопки). Обратите вни-
        мание на то,  что эти управляющие элементы являются не  объектами
        управляющих  элементов,  а только управляющими интерфейсными эле-
        ментами,  без методов и полей объекта. Эта глава кроме того пока-
        зывает  альтернативные методы,  позволяющие связывать объекты уп-
        равления с элементами управления диалоговых блоков с  использова-
        нием 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, основное окно име-

         B.Pascal 7 & Objects/OW     - 184 -

        ет режимный диалог,  определенный типом диалога TTestDialog.  Эта
        программа обеспечивает двухстороннюю связь между объектом диалога
        и его управляющими элементами. Два метода - IDBN1 и IDLB1 - явля-
        ются методами реакции, основанными на дочерних идентификаторах, и
        вызываются при выборе пользователем управляющих элементов (дочер-
        них окон).  Например, при выборе пользователем кнопки диалога BN1
        ('Fill List Box') вызывается метод IDBN1. Аналогично, когда поль-
        зователь делает выбор в блоке списка,  вызывается IDLB1. С другой
        стороны, для заполнения блока списка элементами текста код метода
        IDBN1 посылает в диалог управляющее сообщение,  lb_AddString, ис-
        пользуя метод диалога SendDlgItemMsg,

             Эта программа также показывает как путем создания нового ти-
        па диалога и связывания его с ресурсом диалога в вызове конструк-
        тора Init метода TestWindow.RunDialog  создаются  новые  диалоги.
        Полный текст программы вы можете найти на дистрибутивных дисках.

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

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

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

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

             Обратите внимание,  что в отличие от задания оконного объек-

         B.Pascal 7 & Objects/OW     - 185 -

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

                            Использование диалоговых окон
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

             TDglWindow является потомком TDialog и наследует его методы,
        такие как Execute,  Create,  Ok и EndDlg. Как и диалоговые блоки,
        диалоговые окна имеют соответствующий ресурс диалогового блока. С
        другой стороны, как и окна, диалоговые окна имеют соответствующий
        класс окон,  определяющий среди всего прочего пиктограмму, курсор
        и меню. Из-за связи с оконным классом в потомке TDlgWindow следу-
        ет переопределять  методы  GetClassName  и  GetWindowClass.  Этот
        класс должен быть тем же, что и перечисленный в диалоговом ресур-
        се.

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

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



         B.Pascal 7 & Objects/OW     - 186 -

                    Использование предопределенных диалоговых окон
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Для выполнения двух типов общих функций  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;

         B.Pascal 7 & Objects/OW     - 187 -


             В данном примере 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;



         B.Pascal 7 & Objects/OW     - 188 -

                              Файловые диалоговые блоки
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Файловые диалоговые  блоки  являются  другим типом диалогов,
        поставляемых с 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 автоматически включа-
        ет файл ресурса.

         B.Pascal 7 & Objects/OW     - 189 -

                      Инициализация файлового диалогового блока
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             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, то файловый
        диалоговый блок будет блоком сохранения файла.


         B.Pascal 7 & Objects/OW     - 190 -


             Дополнительным средством    файлового    диалогового   блока
        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;



         B.Pascal 7 & Objects/OW     - 191 -

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

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

                   Примечание: Об  интерфейсных объектах рассказывается в
              Главе 9.

             Данная глава охватывает следующие темы:

             * Задачи, общие для всех управляющих объектов:

               - построение и уничтожение объектов управляющих элементов;

               - взаимодействие с другими управляющими объектами.

             * Установка и чтение значений управляющих элементов.

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

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

                Где можно использовать объекты управляющих элементов?
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

                   Примечание: Диалоговые блоки и их управляющие элементы
              описываются в Главе 11 "Объекты диалоговых блоков".

             Возможно вы захотите использовать управляющие элементы в ок-
        нах, поэтому в данной главе описывается использование управляющих
        элементов вне диалоговых блоков.  Следующая таблица описывает уп-

         B.Pascal 7 & Objects/OW     - 192 -

        равляющие  элементы  Windows,  поддерживаемые   типами   объектов
        ObjectWindows:

                          Управляющие элементы Windows,
                         поддерживаемые в ObjectWindows      Таблица 12.1
        ЪДДДДДДДДДДДДДДДВДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і Управляющий   і Тип объектаі          Использование           і
        і    элемент    і            і                                  і
        ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і блок списка   іTListBox    іПрокручиваемый  список  элементов,і
        і               і            іиз которых можно сделать выбор.   і
        ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і полоса        іTScrollBar  іПолоса   прокрутки,    аналогичнаяі
        і прокрутки     і            ітем,  которые выводятся в  прокру-і
        і               і            ічиваемых окнах и блоках списка.   і
        ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і "нажимаемая"  іTButton     іКнопка для "нажатия" со  связаннымі
        і кнопка        і            іс ней текстом.                    і
        ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і кнопка с      іTCheckBox   іСостоящая из блока кнопка, котораяі
        і независимой   і            іможет выбираться или нет, со  свя-і
        і фиксацией     і            ізанным текстом.                   і
        ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і кнопка с      іTRadioButtonіКнопка,  которая может  выбиратьсяі
        і зависимой     і            іили   нет.   Обычно   используетсяі
        і фиксацией     і            іво взаимоисключающих группах.     і
        ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і блок группы   іTGroupBox   іСтатический  прямоугольник с текс-і
        і               і            ітом в левом верхнем углу.         і
        ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і управляющий   іTEdit       іПоле  для ввода текста пользовате-і
        і элемент       і            ілем.                              і
        і редактированияі            і                                  і
        ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і статический   іTStatic     іФрагмент   отображаемого   текста і
        і управляющий   і            ікоторый  не  может  быть  изменен і
        і элемент       і            іпользователем.                    і
        ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і Комбиниро-    іTComboBox   іКомбинация блока списка и управля-і
        і ванный блок   і            іющего элемента редактирования.    і
        АДДДДДДДДДДДДДДДБДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 193 -


                            ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
          Командная строка: і                                  і
                            АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                                     ^
                                     А редактируемый упрвляющий элемент

         ЪДДДДДДДДДДї            ЪДДДДДДДДДДї
         і±±±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.

         B.Pascal 7 & Objects/OW     - 194 -

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

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

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

             Тип TControl,  как и  TWindowsObject,  является  абстрактным
        объектным типом.  Вы  можете  создать  экземпляры  его  потомков -
        TListBox, TButton и другие  -  но  не  можете  создать  экземпляр
        TControl.

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

               Построение и уничтожение объектов управляющих элементов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             * Построение объекта управляющего элемента.

             * Вывод управляющего элемента.

             * Уничтожение управляющего элемента.



         B.Pascal 7 & Objects/OW     - 195 -

                       Построение объекта управляющего элемента
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

                   Примечание: Уведомления  описываются в Главе 16 "Сооб-
                               щения Windows".
             Чтобы построить и инициализировать объект управляющего  эле-
        мента, нужно сделать следующее:

             * добавить в объект порождающего окна поле (не обязательно);
             * вызвать конструктор объекта управляющего элемента;
             * изменить атрибуты управляющего элемента;
             * инициализировать управляющий элемент в SetupWindows.

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

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

             - объекта порождающего окна;
             - идентификатора управляющего элемента;
             - координату x верхнего левого угла;
             - координату y верхнего левого угла;
             - ширину;
             - высоту.

             TListBox.Init описывается следующим образом:

             constructor TListBox.Init(AParent: PWindowsObject;
                                     AnID: Integer; X, Y, W, H: Integer);

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

                              Присваивание полям объекта
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
             Часто при построении управляющего элемента в окне желательно

         B.Pascal 7 & Objects/OW     - 196 -

        сохранять указатель на управляющий элемент в поле оконного объек-
        та. Например,  чтобы  добавить   в   окно,   определенное   типом
        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;



         B.Pascal 7 & Objects/OW     - 197 -

                  Изменение атрибутов объекта управляющего элемента
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Все управляющие объекты, кроме 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 не создается,  попытки инициализации управляющих эле-
        ментов до этого момента завершится неудачно.



         B.Pascal 7 & Objects/OW     - 198 -

                           Сохранение управляющих элементов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

                          Уничтожение управляющих элементов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

                           Связь с управляющими элементами
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

             Диалоговые окна  работают с их управляющими элементами путем
        передачи им сообщений с помощью метода SendDlgItemMsg с  констан-
        той управляющего  сообщения  (такой  как lb_AddString) в качестве
        параметра (см.  Главу 11).  Объекты управляющих элементов  сильно
        упрощают этот  процесс  путем  использования  методов (таких  как
        TListBox.AddString) для непосредственной  работы  с  управляющими
        элементами на экране.

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

             TheListBox^.AddString('Scotts Valley');



         B.Pascal 7 & Objects/OW     - 199 -

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

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

                       Действие, аналогичное диалоговому блоку
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

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

                              Использование блока списка
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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



         B.Pascal 7 & Objects/OW     - 200 -

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

             Конструктор 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.        і
        АДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

         B.Pascal 7 & Objects/OW     - 202 -


             Приведем пример  метода порождающего окна по обработке сооб-
        щений блока списка:

             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 на ваших
        дистрибутивный дискетах.


         B.Pascal 7 & Objects/OW     - 203 -

                   Использование статических управляющих элементов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Статические управляющие  элементы  - это обычно неизменяемые
        модули текста или простые изображения,  которые могут  появляться
        на экране  в окне или блоке диалога.  Пользователь не взаимодейс-
        твует со статическими управляющими элементами,  хотя программа  и
        может  изменять их текст.  Рис.  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 Стили статических управляющих элементов.


         B.Pascal 7 & Objects/OW     - 204 -

                     Построение статических управляющих элементов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Пользователь никогда  не  взаимодействует непосредственно со
        статическими управляющими элементами,  поэтому  приложение  будет
        очень редко,  если вообще будет, принимать уведомляющие сообщения
        управляющих элементов относительно статического управляющего эле-
        мента. Следовательно, большин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). Для уточ-
        нения текущего текста, который хранится в статическом управляющем

         B.Pascal 7 & Objects/OW     - 205 -

        элементе, используется метод GetText.

                 Модификация статического управляющего элемента

             Для изменения  текста  статического  управляющего   элемента
        TStatic  имеет  два  метода.  SetText  устанавливает  статический
        текст,  передаваемый аргументом PChar.  Clear удаляет статический
        текст.  Однако, вы не можете сменить текст статического управляю-
        щего элемента, созданный со стилем ss_Simple.

                     Опрос статических управляющих элементов

             Чтобы считать текст,  содержащийся в статическом управляющем
        элементе, используйте метод GetText.

                              Пример программы StatTest
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Программа StatTest  создает статическое тестовое приложение,
        показанное на  Рис.12.2.  Обратите  внимание  на  то,  что  метки
        ('Default  Static' и 'ss_Simple') представляют собой статистичес-
        кие управляющие элементы, также как и 'Sample Text', черные и се-
        рые прямоугольники.  Полный текст программы  содержится  в  файле
        STATTEST.PAS на ваших дистрибутивных дискетах.



         B.Pascal 7 & Objects/OW     - 206 -

                            Использование командных кнопок
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Управляющие элементы  типа  командных кнопок (которые иногда
        называют "нажимаемыми" кнопками) выполняют некоторое действие при
        "нажатии"  такой кнопки.  Есть два стиля командных кнопок,  и оба
        они  имеют  тип  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, использующая командные кнопки.



         B.Pascal 7 & Objects/OW     - 207 -

                             Построение командных кнопок
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Кроме обычных 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,  которую  вы  можете найти на
              дистрибутивных дисках.


         B.Pascal 7 & Objects/OW     - 208 -

                             Использование блоков выбора
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Тип 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));

         B.Pascal 7 & Objects/OW     - 209 -

             ChBox1 := New(PCheckBox, Init(@Self, id_Check1,
                         'Check Box Text', 235, 12, 150, 26, GroupBox1));

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

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



         B.Pascal 7 & Objects/OW     - 210 -

                              Модификация блоков выбора
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Модификация (выбор или отмена выбора) блоков выбора выглядит
        задачей пользователя программы, а не вашей. Но в некоторых случа-
        ях программе  требуется  явно управлять состоянием блоков выбора.
        Одним из таких случаев является вывод на экран параметров,  кото-
        рые  были  выбраны  и сохранены ранее.  Для модификации состояния
        кнопки с независимой фиксацией 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 на ваших дистрибутивных дисках.

                            Использование групповых блоков
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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



         B.Pascal 7 & Objects/OW     - 211 -

                             Построение групповых блоков
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Конструктор 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;


         B.Pascal 7 & Objects/OW     - 212 -

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



         B.Pascal 7 & Objects/OW     - 213 -

                              Реакция на групповые блоки
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

                              Пример программы: BtnTest
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

                   Примечание: Полный  текст программы содержится в файле
              BTNTEST.PAS на ваших дистрибутивных дискетах.

        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
        і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫButton TesterЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
        ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
        і                                                               і
        і         ЪДДДї                                                 і
        і         і X і Текст кнопки с независимой фиксацией            і
        і         АДДДЩ                                                 і
        і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї  і
        і і±±±±±±±±±±±Состояние кнопки с независимой фиксацией±±±±±±±і  і
        і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ  і
        і                                                               і
        і             ЪДГрупповой блокДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї  і
        і             і ( ) Кнопка с зависимой фиксацией 1           і  і
        і             і (*) Кнопка с зависимой фиксацией 2           і  і
        і             АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ  і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

             Рис. 12.4 Окно с различными видами кнопок.


         B.Pascal 7 & Objects/OW     - 214 -

                            Использование полос прокрутки
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Полосы прокрутки являются важнейшим механизмом изменения об-
        зора пользователем окна приложения,  блока списка или  комбиниро-
        ванного блока. Однако, может возникнуть ситуация, когда нужна от-
        дельная полоса прокрутки для выполнения  некоторой  специализиро-
        ванной задачи (например, управление температурой в программе тер-
        мостата или цветом в программе рисования).  Когда нужна отдельная
        специализированная полоса    прокрутки,    используются   объекты
        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 для горизон-
        тальной или вертикальной полосы прокрутки соответственно.  Разно-

         B.Pascal 7 & Objects/OW     - 215 -

        образные полосы прокрутки показаны на Рис. 12.6.

        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
        і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫScroll Bar TesterЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
        ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
        і          ЪДДї                                     ЪДї         і
        і    ЪДДВДДі/\іДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДї      і^і         і
        і    і/Ыі±±ГДДґ±±±±±±±±±±±Ы±±±±±±±±±±±±±±±іЫ\і      ГДґ         і
        і    і\Ыі±±і±±і±±±±±±±±±±±Ы±±±±±±±±±±±±±±±іЫ/і      і±і         і
        і    АДДБДДіЫЫіДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДЩ      іЫі         і
        і          і±±і                                     і±і         і
        і          і±±і                                     і±і         і
        і          і±±і                                     ГДґ         і
        і          ГДДґ                                     іvі         і
        і          і\/і                                     АДЩ         і
        і          АДДЩ                                                 і
        і ЪДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДї  і
        і і<Ыі±±±±±±±±±±±±±±±±±Ы±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±іЫ>і  і
        і АДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДЩ  і
        і                                                               і
        і                                                               і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

             Рис. 12.6 Окно с разнообразными полосами прокрутки.

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

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

             Положению маркера в "самой верхней" позиции (вершина  верти-
        кальной полосы прокрутки или крайнее левое положение горизонталь-
        ной полосы прокрутки) соответствует позиция 1. "Самой нижней" по-
        зиции маркера соответствует позиция 100. Для установки иного диа-
        пазона  нужно  использовать  метод SetRange,  описанный в разделе
        "Модификация полосы прокрутки".



         B.Pascal 7 & Objects/OW     - 216 -

                       Управление параметрами полосы прокрутки
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Два других  атрибута объекта полосы прокрутки - это его при-
        ращение по строкам и страницам.  Приращение по строкам,  установ-
        ленное в 1, это расстояние в единицах диапазона, на которое пере-
        местится указатель при нажатии пользователем  стрелок  на  полосе
        прокрутки. Приращение по страницам, установленное в 10, это расс-
        тояние в единицах диапазона,  на которое  переместится  указатель
        при нажатии пользователем в области прокрутки. Эти значения можно
        изменить непосредственной модификацией полей объекта  TScrollBar,
        LineSize и PageSize.

                                Опрос полосы прокрутки
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             TScrollBar определяет  два  метода  опроса полосы прокрутки:
        GetRange и GetPosition. Метод GetRange - это процедура, использу-
        ющая два  целочисленных переменных аргумента. Процедура заносит в
        эти целые  значения  верхнюю и нижнюю позиции из диапазона полосы
        прокрутки. Этот метод очень удобен, когда нужно, чтобы ваша прог-
        рамма переместила указатель в его верхнюю или нижнюю позицию.

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

                             Модификация полос прокрутки
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

                      Методы модификации полос прокрутки    Таблица 12.6
        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДї
        і       Выполняемое действие           і    Вызываемый метод    і
        ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
        і    Задание диапазона прокрутки       і   SetRange             і
        і    Установка позиции маркера         і   SetPosition          і
        і    Перемещение позиции маркера       і   DeltaPos             і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДЩ

             SetRange - это процедура,  которая воспринимает два целочис-
        ленных аргумента,  наименьшую и наибольшую позицию диапазона.  По
        умолчанию новая полоса прокрутки имеет диапазон от 1 до  100.  Вы
        можете  изменить этот диапазон для наилучшего расположения управ-
        ляющих элементов полос прокрутки.  Например,  полоса прокрутки  в
        приложении  для термостата может иметь диапазон от 32 до 120 гра-
        дусов Фаренгейта:

             ThermScroll^.SetRange(32, 120);

         B.Pascal 7 & Objects/OW     - 217 -



             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;

             Часто альтернатива  состоит  в том,  чтобы не реагировать на
        перемещение  указателя до тех пор,  пока пользователь не  выберет

         B.Pascal 7 & Objects/OW     - 218 -

        его нового местоположения. В этом случае нужно реагировать на со-
        общение с кодом 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 на ваших дистрибутивных дискетах.

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

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

             - Ввод текста пользователем.
             - Динамическое отображение текста приложением.
             - Вырезание, копирование и вставка в буфер вырезанного изоб-
               ражения.
             - Многострочное  редактирование (удобно для текстовых редак-
               торов).


         B.Pascal 7 & Objects/OW     - 219 -

             На Рис.  12.7  показано окно с двумя управляющими элементами
        редактирования.

        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
        і±=±ІІІІІІІІІІІІІІІІІEdit Control TesterІІІІІІІІІІІІІІІІІІІІі^іvі
        ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
        і                                                               і
        і   Оригинал:                     Копия:                        і
        і  ЪДДДДДДДДДДДДДДДДДДДДДДї ЪДДДї ЪДДДДДДДДДДДДДДДДДДДДДДї      і
        і  іDefault Text          і і±>±і іDEFAULT.TEXT          і      і
        і  АДДДДДДДДДДДДДДДДДДДДДДЩ АДДДЩ АДДДДДДДДДДДДДДДДДДДДДДЩ      і
        і                                                               і
        і                                                               і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

             Рис. 12.7 Окно с управляющими элементами редактирования.



         B.Pascal 7 & Objects/OW     - 220 -

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

             Конструктор 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.


         B.Pascal 7 & Objects/OW     - 221 -


             Следующая таблица содержит список методов, которые вызывают-
        ся в ответ на выбор пункта меню:

           Управляющие элементы редактирования и меню 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,  который определяет, можно ли отменить последнюю
        операцию редактирования.



         B.Pascal 7 & Objects/OW     - 222 -

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

             Иногда нужно организовать опрос управляющих элементов редак-
        тирования  для  проверки  допустимости введенного текста,  записи
        ввода для его последующего использования или копирования ввода  в
        другой управляющий элемент.  TEdit поддерживает несколько методов
        опроса.  Многие из опросов управляющих элементов редактирования и
        методов  модификации  возвращают или требуют от вас указать номер
        строки или позицию символа в строке. Все эти индексы начинаются с
        нуля. Другими словами, первая строка - это нулевая строка, а пер-
        вый символ в любой строке это нулевой символ.  Самыми важными ме-
        тодами запроса являются GetText, GetLine, NumLines и LineLength.

          Методы опроса управляющих элементов редактирования  Таблица12.8
        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДї
        і    Выполняемое действие                  і Вызываемый метод   і
        ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДґ
        і    Определение изменения текста          і IsModified         і
        і    Считывание всего текста               і GetText            і
        і    Считывание строки                     і GetLine            і
        і    Получение числа строк                 і GetNumLines        і
        і    Получение длины данной строки         і GetLineLength      і
        і    Получение индекса выделенного текста  і GetSelection       і
        і    Получение диапазона символов          і GetSubText         і
        і    Подсчет символов перед строкой        і LineIndex          і
        і    Поиск строки, содержащей индекс       і GetLineFromProc    і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДЩ

             Вы можете заметить, что методы запросов TEdit, которые возв-
        ращают  текст из управляющего элемента редактирования,  сохраняют
        форматирование текста.  Это важно только для многострочных управ-
        ляющих элементов редактирования, которые допускают появление нес-
        кольких строк текста.  В этом случае возвращаемый текст,  который
        занимает  несколько  строк  в управляющем элемента редактирования
        содержит в конце каждой строки два дополнительных символа:  возв-
        рат каретки (#13) и смена строки (#10). Если этот текст снова по-
        мещается в управляющий элемент редактирования, вставляется из бу-
        фера  вырезанного изображения,  записывается в файл или выводится
        на принтер, то строки разбиваются так, как это было в управляющем
        элемента редактирования.

             Следовательно, при  использовании метода запроса для получе-
        ния определенного числа символов,  нужно учитывать эти два симво-
        ла,  которые заканчивают строку. GetText ищет текст в управляющем
        элементе редактирования. Он заполняет строку, на которую указыва-
        ет переданный  аргумент  PChar,  содержимым управляющего элемента
        редактирования,  включая перевод строки. Общее число символов за-
        дается вторым параметром.  Он возвращает значение False, если уп-
        равляющий элемент редактирования пуст,  или содержит текста боль-
        ше,  чем помещается в предоставленную строку. Следующая процедура
        считывает из управляющего элемента редактирования строку и  выде-
        ленный текст:

         B.Pascal 7 & Objects/OW     - 223 -


            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      і

         B.Pascal 7 & Objects/OW     - 224 -

        і    Удаление диапазона символов         і 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 предоставляет методы по манипулированию
        списком, находящемся в комбинированном блоке, который в некоторых
        случаях может раскрываться по запросу.



         B.Pascal 7 & Objects/OW     - 225 -

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

             Имеются три типа комбинированных блоков: простые, раскрываю-
        щиеся  и  раскрывающиеся со списком.  На Рис.  12.8 показан вывод
        трех типов комбинированных блоков с блоком списка.

        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
        і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫStatic Control TesterЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
        ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
        і                                                               і
        і  Блок списка                 Простой комбинированный блок     і
        і  ЪДДДДДДДДДДДДДДДДї          ЪДДДДДДДДДДДДДДДДДДДДДДДДДДї     і
        і  іa               і          і                          і     і
        і  іb               і          АВДДДДДДДДДДДДДДДДДДДДДДДДДґ     і
        і  іc               і           іa                        і     і
        і  іd               і           іb                        і     і
        і  іe               і           іc                        і     і
        і  іf               і           іd                        і     і
        і  АДДДДДДДДДДДДДДДДЩ           АДДДДДДДДДДДДДДДДДДДДДДДДДЩ     і
        і                                                               і
        і  Раскрывающийся комбинированный Комбинированный блок с        і
        і  блок                           раскрывающимся списком        і
        і  ЪДДДДДДДДДДДДДДДДДДДДДДДїЪДДДї ЪДДДДДДДДДДДДДДДДДДДДДДВДДДї  і
        і  і                       іі v і іc±±±±±±±±±±±±±±±±±±±±±і v і  і
        і  АДДДДДДДДДДДДДДДДДДДДДДДЩАДДДЩ АДДДДДДДДДДДДДДДДДДДДДДБДДДЩ  і
        і                                                               і
        і                                                               і
        і                                                               і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

             Рис. 12.8 Три типа комбинированных блоков и блок списка.

                    Перечень стилей комбинированного блока  Таблица 12.10
        ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДї
        і    Стиль            іВозможность скрытого іСоответствие текстаі
        і                     і     списка          і     списку        і
        ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДґ
        і   Простой           і      нет            і      нет          і
        і   Раскрывающийся    і      есть           і      нет          і
        і   Раскрывающийся со і      есть           і      да           і
        і   списком           і                     і                   і
        АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДЩ

             С точки зрения пользователя между различными стилями  комби-
        нированных блоков существуют следующие различия:

             * Простые комбинированные блоки.

               Простой комбинированный блок не может делать область спис-
               ка скрытой.  Его область редактирования ведет себя  анало-
               гично  управляющему элементу редактирования.  Пользователь
               может вводить и редактировать текст,  и  текст  не  обязан

         B.Pascal 7 & Objects/OW     - 226 -

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

             * Раскрывающиеся комбинированные блоки.

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

             * Раскрывающиеся комбинированные блоки списка.

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

                          Выбор типа комбинированного блока
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

                          Построение комбинированных блоков
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Кроме обычных  6  параметров  объектов управляющих элементов
        конструктор Init для TComboBox воспринимает в качестве аргументов

         B.Pascal 7 & Objects/OW     - 227 -

        стиль и максимальную длину текста. Конструктор 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 содержится
              на ваших дистрибутивных дискетах.

                       Установка значений управляющих элементов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         B.Pascal 7 & Objects/OW     - 228 -


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

                        Для чего используется буфер передачи?
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

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

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

             Чтобы использовать механизм передачи, вы можете сделать сле-
        дующее:

             * Определить буфер передачи.
             * Определить соответствующее окно.
             * Передать данные.

                             Определение буфера передачи
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Буфер передачи - это запись с одним полем для каждого управ-

         B.Pascal 7 & Objects/OW     - 229 -

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

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

             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;


         B.Pascal 7 & Objects/OW     - 230 -


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

                             Поля буфера передачи
                    для каждого типа управляющего элемента  Таблица 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;

         B.Pascal 7 & Objects/OW     - 231 -

              Position : Integer;
             end;

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

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

                  Использование буфера передачи с диалоговым блоком
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Для случая  окон с управляющими элементами объекты управляю-
        щих элементов конструируются с использованием Init.  Для диалогов
        и окон диалогов нужно использовать конструктор InitResource. Нап-
        ример (используется определенный ранее тип TSampleRecord):

             type
              TSampleTransferRecord = record
                .
                .
                .
              PParentWindow = ^TParentWindow;
              TParentWindow = object(TWindow)
               TheDialog: PDialog;
               TheBuffer: SampleTransferRecord;
                .
                .

         B.Pascal 7 & Objects/OW     - 232 -

                .
                .
             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, механизм передачи разрешается автоматически.


         B.Pascal 7 & Objects/OW     - 233 -

                        Использование буфера передачи с окном
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Для случая окна с управляющими  элементами  используйте  для
        конструирования  объектов  управления в надлежащей последователь-
        ности 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 воспроизводит режимный диа-

         B.Pascal 7 & Objects/OW     - 235 -

        лог с полями, в которые пользователь вводит данные об имени и ад-
        ресе.  Буфер передачи используется для хранения этой информации и
        отображения ее в управляющих элементах диалога при повторном  его
        выполнении.  Обратите внимание на то, что нам не нужно определять
        новый тип объекта диалога для установки и поиска данных  диалога.
        Также обратите ваше внимание на то,  что мы непосредственно мани-
        пулируем данными буфера передачи,  поэтому статическое управление
        при  первом  выводе  диалога гласит "First Mailing Label" (первая
        почтовая этикетка),  а при всех остальных появлениях  "Subsequent
        Mailing Label" (следующая почтовая этикетка).

                   Примечание: Полный  текст программы содержится в файле
              TRANTEST.PAS на ваших дистрибутивных дискетах.



         B.Pascal 7 & Objects/OW     - 236 -

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

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

             Специализированные управляющие элементы Borland для Windows
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Специализированные управляющие  элементы Borland для Windows
        (BWCC) обеспечивают выразительный внешний вид приложений  Borland
        для Windows. Основными средствами BWCC являются:

             * командные кнопки с графическими изображениями;

             * серый "рельефный" фон диалоговый блоков;

             * трехмерные кнопки с зависимой и независимой фиксацией.

             ObjectWindows дает  вам возможность простого доступа к BWCC,
        так что вы можете  придать  своим  приложениями  стандартный  для
        Borland вид.



         B.Pascal 7 & Objects/OW     - 237 -

                            Использование стандартных BWCC
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             ObjectWindows позволяет легко добавлять BWCC в ваши приложе-
        ния Windows.  Нужно просто добавить модуль BWCC в  оператор  uses
        программы:

             uses BWCC;

             Использование BWCC автоматически позволяет вам делать следу-
        ющее:

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

             * создавать в вашей программе BWCC.

             Например, с  помощью  пакета  разработчика ресурсов Resource
        WorkShop вы можете создать ресурсы диалоговых блоков,  использую-
        щие специализированные управляющие элементы Borland.  Включение в
        оператор uses программы модуля BWCC обеспечивает для вашей  прог-
        раммы информацию о том, где искать динамически компонуемую библи-
        отеку (BWCC.DLL),  содержащую код,  который  обеспечивает  работу
        BWCC.

             Кроме того, после добавления модуля BWCC любые создаваемые в
        программе объекты управляющих элементов будут иметь вид и  харак-
        теристики управляющих элементов Borland.

                                    Средства BWCC
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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



         B.Pascal 7 & Objects/OW     - 238 -

                                   Расширение 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  элементов
        изображения.

         B.Pascal 7 & Objects/OW     - 239 -


             Для текста следует использовать шрифт 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.

         B.Pascal 7 & Objects/OW     - 240 -

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

             Простейший способ создания специализированного  управляющего
        элемента состоит  в фактическом создании окна,  которое действует
        как управляющий элемент,  но вовсе не является окном. Этот подход
        используется в программе Steps в Части 1 данного руководства. Тот
        же используемый в программе Steps метод применяется для ее объек-
        та палитры,  который можно использовать,  например,  для создания
        объекта инструментальной полосы. Таким "управляющие элементы" яв-
        ляются наследниками TWindow,  а не TControl,  поскольку  TControl
        имеет   дело   только  со  стандартными  управляющими  элементами
        Windows.

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

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



         B.Pascal 7 & Objects/OW     - 241 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                        Глава 13. Проверка допустимости данных
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             Данная глава  охватывает следующие темы,  относящиеся к про-
        верке допустимости:

             * Три вид проверки допустимости данных.

             * Использование объектов проверки допустимости.

             * Как работает проверка допустимости.

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

                        Три вида проверки допустимости данных
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Существует три  различных типа проверки допустимости данных,
        и ObjectWindows поддерживает их по-разному.  Этими  тремя  видами
        являются:

             * Фильтрация ввода.

             * Проверка допустимости каждого элемента.

             * Проверка допустимости полных экранов.

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

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


         B.Pascal 7 & Objects/OW     - 242 -

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

                                   Фильтрация ввода
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

                          Проверка допустимости каждого поля
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

                         Проверка допустимости полных экранов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Проверить допустимость полных экранов вы можете  тремя  раз-
        личными способами:

             * Проверкой допустимости режимных окон.
             * Проверкой допустимости при изменении фокуса.
             * Проверкой допустимости по запросу.

                       Проверка допустимости режимных окон

             Когда пользователь закрывает режимное окно, оно перед закры-
        тием автоматически проверяет допустимость всех своих  подобластей
        просмотра (если закрывающей командой не была cmCancel).  Для про-
        верки допустимости всех подобластей окно вызывает метод  CanClose

         B.Pascal 7 & Objects/OW     - 243 -

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

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

                        Проверка допустимости по запросу

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

             Вызов CanClose  не  обязывает вас фактически закрывать окно.
        Например, вы можете вызвать CanClose, когда пользователь "нажима-
        ет" командную кнопку Save (Сохранение),  обеспечивая проверку до-
        пустимости данных перед их сохранением.

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

                 Использование механизма проверки допустимости данных
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Использование объекта проверки допустимости данных с  управ-
        ляющим элементом редактирования требует двух шагов:

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

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



         B.Pascal 7 & Objects/OW     - 244 -

                      Построение объектов проверки допустимости
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             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 предусмотрено несколько видов объектов  про-
        верки допустимости,  которые  должны охватывать большинство ваших
        потребностей по проверке данных.  Из абстрактных  типов  проверки
        допустимости вы  можете  также  построить свои собственные произ-
        водные типы.

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

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


         B.Pascal 7 & Objects/OW     - 245 -

                         Методы объекта проверки допустимости
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             Этими четырьмя методами являются следующие:

             * Valid

             * IsValid

             * IsValidInput

             * Error

             Единственными методами,  вызываемыми вне  объекта,  являются
        Valid и IsValidInput.  Error и IsValid - единственные методы, вы-
        зываемые другими методами объекта проверки допустимости.

                             Проверка допустимости данных
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             При использовании  средств проверки допустимости с управляю-
        щими элементами редактирования вам никогда не требуется  вызывать
        или переопределять метод Valid объекта проверки допустимости.  По
        умолчанию Valid  возвращает  True,  если  возвращает  True  метод
        IsValid. В противном случае для уведомления пользователя об ошиб-
        ке и возврата значения False вызывается Error.

         B.Pascal 7 & Objects/OW     - 246 -

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

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

             Заметим, что метод IsValid не вызывается вами явно.  Исполь-
        зуйте для вызова IsValid метод Valid,  так  как  для  уведомления
        пользователя в  случае  возврата  методом  IsValid значения False
        Valid вызывает метод Error. Не путайте также проверку допустимос-
        ти сообщением об ошибке.

                         Проверка допустимости нажатий клавиш
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Когда объект управляющего элемента  редактирования  получает
        имеющее  для  него значение событие нажатия клавиши,  он вызывает
        метод IsValidInput объекта проверки  допустимости.  По  умолчанию
        методы IsValid всегда возвращают True.  Это означает, что воспри-
        нимаются все нажатия клавиш. Однако, наследующие объекты проверки
        допустимости  могут переопределять метод IsValidInput,  чтобы от-
        фильтровывать нежелательные нажатия клавиш.

             Например, средства проверки допустимости диапазона,  которые
        используются для числового ввода, возвращают из IsValidInput True
        только для цифр и символов '+' и '-'.

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

                           Сообщение о недопустимых данных
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             Например, метод Error для  проверки  допустимости  диапазона
        создает блок сообщения,  указывающий,  что значение в управляющем
        элементе редактирования не находится между указанными минимальным
        и максимальным значениями.

         B.Pascal 7 & Objects/OW     - 247 -


             Хотя большинство  объектов проверки допустимости переопреде-
        ляют Error,  вам не следует вызывать его  непосредственно.  Метод
        Error вызывается  методом  Valid,  если  IsValid возвращает False
        (что является единственным моментом,  когда  необходимо  вызывать
        Error).



         B.Pascal 7 & Objects/OW     - 248 -

                      Стандартные средства проверки допустимости
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             ObjectWindows включает в себя шесть стандартных типов объек-
        тов проверки  допустимости,  включая  абстрактный объект проверки
        допустимости и следующие пять специальных типов таких объектов:

             * Фильтрация.
             * Проверка диапазона.
             * Проверка допустимости с просмотром.
             * Проверка допустимости с просмотром строк.
             * Проверка допустимости с просмотром шаблонов.

                       Абстрактный объект проверки допустимости
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Абстрактный тип TValidator  служит базовым  типом  для  всех
        объектов проверки допустимости, но сам по себе он не делает ниче-
        го полезного.  По существу,  TValidator - это объект проверки до-
        пустимости,  для которого всегда допустим любой ввод:  IsValid  и
        IsValidInput возвращают True,  а Error не выполняет никаких функ-
        ций.  Наследующие типы переопределяют IsValid и/или  IsValidInput
        для фактического определения того, какие значения являются допус-
        тимыми.

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

                                      Фильтрация
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             constructor TFilterValidator.Init(AValidChars: TCharSet);

             TFilterValidator переопределяет  IsValidInput  для  возврата
        True только в том случае, если все символы в текущей строке ввода
        содержатся в наборе символов,  переданных конструктору. Управляю-
        щие элементы редактирования включают символы только в том случае,
        если IsValidInput возвращает True,  так что нет необходимости пе-
        реопределять IsValid.  Поскольку  символы  проходят  через фильтр
        ввода, полная строка допустима по определению.

             Потомки TFilterValidator,  такие как TRAngeValidator,  могут
        сочетать фильтрацию  ввода с другими проверками завершенной стро-
        ки.


         B.Pascal 7 & Objects/OW     - 249 -

                                  Проверка диапазона
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Объект проверки  допустимости диапазона 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, сравнивающий переданную
        из управляющего элемента редактирования  строку  с  элементами  в

         B.Pascal 7 & Objects/OW     - 250 -

        списке строк.  Если переданная строка содержится в списке,  метод
        объекта проверки  допустимости  с  просмотром  строки  возвращает
        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  пытается сформатировать заданную строку ввода
        в соответствии с шаблоном формата и возвращает  значение,  указы-
        вающее степень успеха: полный, неполный или ошибка.


         B.Pascal 7 & Objects/OW     - 251 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                                Глава 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.

         B.Pascal 7 & Objects/OW     - 252 -

                                 Меню дочернего окна
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Строка меню окна-рамки содержит меню,  управляющее дочерними
        окнами 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.

         B.Pascal 7 & Objects/OW     - 253 -


             * Установка меню дочернего окна.

             * Предоставление  основному окну возможности создания дочер-
               них 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

         B.Pascal 7 & Objects/OW     - 254 -

        первоначально устанавливает 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

         B.Pascal 7 & Objects/OW     - 255 -

              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 не подходит реаги-
        рование  на  основанные на командах сообщения,  генерируемые меню
        дочернего окна.



         B.Pascal 7 & Objects/OW     - 256 -

                         Настройка активизации дочернего окна
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

                         Обработка сообщений в приложении MDI
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

                                Пример приложения MDI
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Программа MDITest  создает  приложение  MDI,  показанное  на
        Рис. 14.1.  Полный текст файла MDITEST.PAS  содержится  на  ваших
        дистрибутивных дискетах.



         B.Pascal 7 & Objects/OW     - 257 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                               Глава 15. Объекты печати
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             Данная глава  описывает  основы процесса печати,  после чего
        описываются следующие задачи:

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

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

               - Печать документа.

               - Печать содержимого окна.

             * Передача распечатки на принтер.

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

             * Настройка конфигурации принтера.

                        Почему печать представляет трудности?
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             С одной стороны печать в Windows достаточно проста. Вы може-
        те использовать для генерации распечатки те же функции  GDI,  что
        используются для  вывода образов на экран.  Для вывода текста ис-
        пользуется функция TextOut,  а для вычерчивания прямоугольника  -
        Rectangle.

             С другой стороны,  процесс осложняется, так как Windows тре-
        бует непосредственного "общения" с драйверами принтера через  вы-
        зовы Escape  или  получения  адреса DeviceMode или ExtDeviceMode.
        Это еще более осложняется требованием Windows,  чтобы  приложение
        считывало имя  драйвера устройства из файла WIN.INI.  Кроме того,
        устройства печати обладают большими возможностями проверки допус-
        тимости и возможностями разрешения, чем видеоустройства.

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

                                Печать в ObjectWindows
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Модуль ObjectWindows OPrinter предусматривает для  упрощения
        печати два объекта - TPrinter и TPrintout. TPrinter инкапсулирует
        доступ к устройствам печати.  Он предоставляет возможность конфи-
        гурирования принтера, выводя диалог, в котором пользователь может

         B.Pascal 7 & Objects/OW     - 258 -

        выбрать нужный принтер,  а также установить параметры печати, та-
        кие как  графическое  разрешение или ориентация (горизонтальная и
        вертикальная) печати.

             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 для использования принтера,  отличного от заданного
        в системе по умолчанию, рекомендуемой процедурой является исполь-
        зование конструктора  по  умолчанию,  а  затем смена связанного с
        объектом устройства. См. раздел "Выбор другого принтера".



         B.Pascal 7 & Objects/OW     - 259 -

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

             Единственной "хитрой" частью процесса печати в ObjectWindows
        являются создание распечатки.  Этот процесс аналогичен  написанию
        метода Paint для объекта окна: вы используете графические функции
        Windows для генерации в контексте устройства нужного графического
        образа.  Контекст  устройства  оконного объекта обрабатывает ваши
        взаимодействия с устройством экрана; аналогичным образом контекст
        устройства распечатки изолирует вас от устройства печати.

                   Примечание: Графические  функции  Windows поясняются в
              Главе 17.

             Чтобы создать объект распечатки, постройте новый тип, произ-
        водный от  TPtintout,  который переопределяет PrintPage.  В очень
        простых случаях это все,  что требуется  сделать.  Если  документ
        имеет размер более одной страницы, то вам нужно также переопреде-
        лить HasNextPage для возврата True.  Текущий номер страницы пере-
        дается в качестве параметра PrintPage.

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

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

                                   Печать документа
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             ObjectWindows предусматривает абстрактный объект  распечатки
        TPrintout, из которого вы можете создать производные объекты рас-
        печатки. Вам нужно переопределить в  TPrintout  только  несколько
        методов.

             Ваши объекты распечатки должны делать следующее:

             * Устанавливать параметры принтера.


         B.Pascal 7 & Objects/OW     - 260 -

             * Подсчитывать страницы.

             * Отображать каждую страницу в контексте устройства.

             * Указывать, есть ли еще страницы.

             Остальная часть  этой  главы  ссылается  на пример программы
        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 объект печати вызывает булевскую

         B.Pascal 7 & Objects/OW     - 261 -

        функцию 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 объекта  распечатки.  Процесс  распечатки  только
        части документа, которому принадлежит данная страница, аналогичен
        определению того,  какую часть прокручиваемого окна нужно отобра-

         B.Pascal 7 & Objects/OW     - 262 -

        жать на экране.  Например, можно отметить подобие методов отобра-
        жения окна и отображения страницы:

             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 следует иметь в виду следую-
        щее:

         B.Pascal 7 & Objects/OW     - 263 -


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

             * Возможности  устройств.  Хотя  большинство  видеоустройств
               поддерживают все операции 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.


         B.Pascal 7 & Objects/OW     - 264 -

             Печать страниц выполняется  последовательно.  То  есть,  для
        каждой страницы   в  последовательности  принтер  вызывает  метод
        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 не предусматривает разбивки на страницы. При

         B.Pascal 7 & Objects/OW     - 265 -

        печати документа вам нужно печатать каждую страницу отдельно,  но
        так как окна не имеют страниц,  вам нужно напечатать только  один
        образ. Окно уже знает,  как создать  этот образ - оно имеет метод
        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).

             Существует два способа задания альтернативного принтера: не-
        посредственно в программе и через диалоговое окно пользователя.



         B.Pascal 7 & Objects/OW     - 266 -

                             Выбор принтера пользователем
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Наиболее общим способом назначения другого принтера является
        вывод диалогового окна, предоставляющего пользователю возможность
        выбора из списка установленных устройств печати.  TPtinter делает
        это автоматически при вызове его метода Setup.  Как  показано  на
        Рис.  15.1,  Setup  использует  для этого диалогового окна объект
        TPrinterSetupDlg.

        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫSelectPrinterЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі
        ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і                                                               і
        і      Printer and port:                                        і
        і      ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДї         і
        і      іPostScript Printer on LPT1:                 іvі         і
        і      АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДЩ         і
        і   ЪДДДДДДДДДДДї         ЪДДДДДДДДДДДї         ЪДДДДДДДДДДДї   і
        і   і±±±±OK±±±±±і         і±±Setup±±±±і         і±±Cancel±±±і   і
        і   АДДДДДДДДДДДЩ         АДДДДДДДДДДДЩ         АДДДДДДДДДДДЩ   і
        і                                                               і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

             Рис. 15.1 Диалоговое окно задания принтера.

                         Настройка конфигурации принтера

             Одна из командных кнопок в диалоге выбора принтера позволяет
        пользователям изменить конфигурацию конкретного принтера.  Кнопка
        Setup выводит диалоговый блок конфигурации,  определенной в драй-
        вере принтера.  Ваше приложение не может управлять внешним  видом
        или функциями диалогового блока конфигурации драйвера.

                           Назначение конкретного принтера
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             SetDevice воспринимает в качестве параметров три строки: имя
        устройства, имя драйвера и имя порта.



         B.Pascal 7 & Objects/OW     - 267 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                              Часть 3. Продвинутое
                 программирование с использование ObjectWindows
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


                             Глава 16. Сообщения Windows
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             Данная глава охватывает ряд тем,  связанных с передачей, по-
        лучением и обработкой сообщений, включая следующие вопросы:

             * что такое сообщение?

             * как выполняется диспетчеризация сообщений?

             * обработка сообщений Windows;

             * определение ваших собственных сообщений;

             * передача и адресация сообщений;

             * диапазоны сообщений.

                                 Что такое сообщение?
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

             type
               TMsg = record
                 hwnd: HWnd;
                 message: Word;
                 wParam: Word;
                 lParam: Longint;

         B.Pascal 7 & Objects/OW     - 268 -

                 time: Longint;
                 pt: TPoint;
             end;

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

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

                                 Именующие сообщения
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Наиболее важным полем сообщений является поле message, кото-
        рое содержит  одну из констант сообщений Windows,  начинающихся с
        wm_. Каждое сообщение Windows уникальным образом идентифицируется
        16-битовым числом  с  соответствующим мнемоническим идентификато-
        ром. Например, сообщение, являющееся результатом нажатия клавиши,
        содержит в поле сообщения wm_KeyDown ($0100). На сообщения обычно
        ссылаются по их мнемоническим именам.

                              Откуда поступают сообщения
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Генерировать сообщения позволяют несколько различных событий:

             * взаимодействия с пользователем,  такие как нажатия клавиш,
               щелчок кнопкой "мыши" или ее буксировка;
             * вызовы функций Windows, которым нужно информировать об из-
               менениях другие окна;
             * ваша программа явно посылает сообщение;
             * другое приложение посылает сообщение через DDE (динамичес-
               кий обмен данными);
             * сообщение генерируется самой Windows (например,  сообщение
               об останове системы).

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



         B.Pascal 7 & Objects/OW     - 269 -

                          Обычная диспетчеризация сообщений
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Обычные приложения  Windows   (то   есть   не   использующие
        ObjectWindows) имеют цикл сообщения, в котором выполняется выбор-
        ка и диспетчеризация сообщения.  По существу,  в цикле  сообщения
        вызывается связанная с окном функция,  заданная описателем окна в
        поле hwnd записи сообщения.

             Каждое окно имеет функцию окна,  заданную при его  создании.
        Когда Windows находит сообщение для конкретного окна, она переда-
        ет сообщение функции данного окна.  Функция окна  отсортировывает
        сообщения на основе типа сообщения, а затем вызывает подпрограмму
        реакции на конкретное сообщение.

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

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

                          Способ, предлагаемый ObjectWindows
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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



         B.Pascal 7 & Objects/OW     - 270 -

                           Динамические виртуальные методы
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Ключем к автоматической диспетчеризации  сообщений  является
        расширение описаний  в  объектах виртуальных методов,  называемых
        динамическими виртуальными методами.  По существу вы связываете с
        методом целочисленный номер (такой как константа сообщения). Ваша
        программа 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. Добавив для каж-
        дого метода это смещение,  вы создадите уникальный индекс динами-

         B.Pascal 7 & Objects/OW     - 271 -

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

                                 Что такое сообщение?
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Теперь, когда вы знаете, как написать метод реакции на сооб-
        щение, можно рассмотреть,  какая информация содержится в  сообще-
        нии. Запись 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 содержит описатель окна, в котором находится курсор.
        Уведомляющие сообщения    управляющего    элемента,   такие   как

         B.Pascal 7 & Objects/OW     - 272 -

        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) является обработка сообщений объектно-ориентированным
        способом. То есть, ваши оконные объекты наследуют возможность оп-
        ределенной реакции  на сообщения, и вам нужно только изменить ре-
        акцию на  конкретные  сообщения,  которые ваш объект обрабатывает
        по-другому.

                            Отмена поведения по умолчанию
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


         B.Pascal 7 & Objects/OW     - 273 -

             Иногда, когда  вы  переопределяете используемую по умолчанию
        реакцию на сообщение,  это делается потому что  данное  поведение
        просто нежелательно.  Простейшим случаем является ситуация, когда
        объект должен игнорировать сообщение,  а не отвечать на него. Для
        этого  вы  можете просто написать пустой метод реакции на сообще-
        ние. Например, следующий метод сообщает управляющему элементу ре-
        дактирования, что  нужно  игнорировать  передаваемые  в сообщении
        wm_Char символы:

             procedure TNonEdit.WMChar(var Msg: TMessage);
             begin
             end;

                            Замена поведения по умолчанию
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             procedure TBeepEdit.WMChar(var Msg: TMessage);
             begin
               MessageBeep(0);
             end;

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

                          Дополнение поведения по умолчанию
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

                              Вызов наследуемых методов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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


         B.Pascal 7 & Objects/OW     - 274 -

             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  вы  можете  рассматривать как используемый

         B.Pascal 7 & Objects/OW     - 275 -

        вместо всех не определенных конкретно наследуемых методов реакции
        на сообщения. Отметим, однако, что это применяется только к сооб-
        щениям 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
               { реакция на команду }

         B.Pascal 7 & Objects/OW     - 276 -

             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;


         B.Pascal 7 & Objects/OW     - 277 -

             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  уведомляющее  сообщение  по-
        рождающему объекту.



         B.Pascal 7 & Objects/OW     - 278 -

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

             Возможно, иногда вам потребуется,  чтобы одновременно на не-
        которое взаимодействие пользователя с управляющим элементом  реа-
        гировали и управляющий элемент, и порождающее окно. 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)

         B.Pascal 7 & Objects/OW     - 279 -

                 .
                 .
                 .
               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, особенно при вызове в методе
        реакции  на сообщение,  может вызвать бесконечный цикл или клинч,
        приводящие к сбою программ.  Вам следует не только избегать  оче-

         B.Pascal 7 & Objects/OW     - 280 -

        видных циклов,  таких как методы реакции на сообщения, генерирую-
        щих то же сообщение,  которое его вызывает, но избегать также пе-
        редачи  сообщений  с побочными эффектами.  Например,  метод 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 не следует использовать для пе-
        редачи сообщений управляющим элементам.

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

             Возможно, единственным случаем,  когда вам потребуется пере-

         B.Pascal 7 & Objects/OW     - 281 -

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

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

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



         B.Pascal 7 & Objects/OW     - 282 -

                                 Диапазоны сообщений
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Сообщение определяется  полем   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.                   і                і
            АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 283 -


                             ЪДДДДДДДДДДДДДДДДДДДДДДДДї
         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 Диапазоны сообщений и команд.



         B.Pascal 7 & Objects/OW     - 284 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                   Глава 17. Интерфейс с графическими устройствами
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             Для предоставления  приложениям  графических  функциональных
        возможностей Windows имеет набор функций,  называемый интерфейсом
        с  графическим устройством - GDI.  GDI можно представить себе как
        графическую машину,  которую используют  приложения  Windows  для
        отображения и манипулирования графикой. Функции GDI предоставляют
        вашему приложению возможности рисования,  которые не  зависят  от
        используемого дисплея. Например, вы можете использовать одни и те
        же функции для организации вывода на дисплей EGA,  на дисплей VGA
        и даже на принтер PostScript.

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

                             Запись на устройство вывода
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

             Контекст дисплея можно представить себе как холст для  рисо-
        вания. Окно это - картинка, включающая рамку. Вместо рисования на
        картине в рамке вы рисуете на холсте,  а уже затем устанавливаете
        его в рамку. Аналогично этому, вы рисуете в контексте дисплея ок-
        на.  Контекст дисплея обладает рядом инструментов рисования, нап-
        ример, ручки,  кисти и шрифты. Контекст дисплея - это управляемый

         B.Pascal 7 & Objects/OW     - 285 -

        Windows элемент,  похожий на элемент окна с тем исключением,  что
        контекст    дисплея    не    имеет    соответствующего   элемента
        ObjectWindows.

             Нужно помнить  о  том,  что контекст устройства представляет
        собой только часть устройства, на котором вы реально рисуете. Хо-
        тя вы  можете  рассматривать  вывод в терминах всего окна (рамки,
        меню, области клиента) или печатаемой страницы, контекст устройс-
        тва охватывает только ту часть,  где вы рисуете - область клиента
        окна или печатаемую часть страницы.

             Контекст устройства - это элемент, управляемый Windows (ана-
        логично оконному  элементу,  только  контекст устройства не имеет
        соответствующего объекта ObjectWindows).

                         Чем отличаются контексты устройства?
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

                            Управление контекстом дисплея
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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



         B.Pascal 7 & Objects/OW     - 286 -

                             Работа с контекстом дисплея
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Обычно нужно  определять  поле  оконного  объекта для записи
        описателя текущего контекста  дисплея,  аналогично  тому,  как  в
        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.

             Хотя обычно  вам не нужно будет изменять большинство атрибу-

         B.Pascal 7 & Objects/OW     - 287 -

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

                                  Побитовая графика
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Действительная поверхность контекста дисплея называется  по-
        битовым отображением  (битовым  массивом).  Побитовые отображения
        представляют конфигурацию памяти конкретного устройства. Следова-
        тельно,  они зависят от вида адресуемого устройства.  Это создает
        проблему, поскольку охраненные для  одного  устройства  побитовые
        отображения  будут  несовместимы с другим устройством.  GDI имеет
        ряд средств для разрешения этой проблемы, включая аппаратно-неза-
        висимые побитовые отображения. Имеются следующие функции GDI, ко-
        торые создают    побитовые    отображения:    CreateCompatibleDC,
        CreateCompatibleBitmap и CreateDIBitmap.  Имеются следующие функ-
        ции GDI  по  манипулированию  побитовыми  отображениями:  BitBlt,
        StretchBlt, StretchDIBits и SetDIBitsToDevice.

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

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

                                      Перья

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

                                      Кисти

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

                                     Шрифты

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

             Все три  инструментальных средства используют для заполнения

         B.Pascal 7 & Objects/OW     - 288 -

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



         B.Pascal 7 & Objects/OW     - 289 -

                                         Цвет
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

                                  Режимы отображения
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Очень трудно выбрать устройство рисования, когда заранее не-
        известно,  какое устройство будет использоваться для отображения.
        Большинство приложений игнорируют эту  проблему  и  предполагают,
        что  вполне удовлетворительно будет работать единица рисования по
        умолчанию (один элемент изображения).  Однако, некоторые приложе-
        ния требуют,  чтобы отображение точно воспроизводило размеры нуж-
        ного образа.  Для таких приложений GDI допускает различные режимы
        отображения,  некоторые из которых не зависят от аппаратуры. Каж-
        дый из методов распределения имеет  свою  единицу  размерности  и
        систему координатной ориентации. Режим распределения по умолчанию
        устанавливает начало координат в  левом  верхнем  углу  контекста
        дисплея с положительным направлением оси X вправо и положительным
        направлением оси Y вниз.  Каждый контекст дисплея имеет  атрибуты
        распределения для интерпретации задаваемых вами координат.

             Иногда нужно транслировать логические координаты, используе-
        мые вами для рисования,  в физические координаты побитового отоб-
        ражения. Для большинства приложений начало координат для экрана -
        это его левый верхний угол,  но для окна началом  координат будет
        левый  верхний угол области клиента.  Некоторые окна прокручивают
        свою поверхность клиента так,  что начало координат не будет даже
        находиться  в  области  клиента.  Некоторые  функции GDI работают
        только в конкретной системе координат, поэтому преобразование ко-
        ординат просто необходимо. В GDI имеется ряд функций для подобно-
        го пересчета координат:  ScreenToClient, ClientToScreen, DPToLP и
        LPToDP.

                                  Обрезание областей
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Для предотвращения рисования  вне  заданной  области  каждый
        контекст  дисплея  имеет атрибут области вырезанного изображения.
        Область вырезанного изображения может быть сложным  многоугольни-
        ком  или  эллипсом,  внутри которого и может происходить действи-
        тельное рисование на виртуальной поверхности  контекста  дисплея.
        Для  большинства приложений выделяемая по умолчанию область выре-
        занного изображения будет вполне достаточной.  Изменять  эту  об-
        ласть придется только для приложений, которые воспроизводят неко-
        торые специальные визуальные эффекты.

         B.Pascal 7 & Objects/OW     - 290 -


                         Инструментальные средства рисования
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Контекст дисплея  управляет  отображением графики на экране.
        Для иного способа отображения графики можно  изменить  инструмен-
        тальные средства,  с помощью которых создается изображение. Атри-
        буты инструментальных средств задают проявление изображений с по-
        мощью функций 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    і                  і                        і
        АДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДЩ

             В отличие  от  логических  инструментальных средств основные

         B.Pascal 7 & Objects/OW     - 291 -

        инструментальные средства не удаляются после использования.

                         Логические инструментальные средства
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Записи логических   инструментов,   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,  содержит константу,  задающую стиль
        линии.


         B.Pascal 7 & Objects/OW     - 292 -


        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
             Константа                     Результат
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
            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) возвратит красный и т.д.



         B.Pascal 7 & Objects/OW     - 293 -

                                   Логические кисти
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Вы можете  создавать  логические  кисти  с  помощью  функций
        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 содержит описатель побитового отображе-
        ния.


         B.Pascal 7 & Objects/OW     - 294 -


        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
              Константа                      Результат
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                              //////////////////////////////////////
            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;

         B.Pascal 7 & Objects/OW     - 295 -

                 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

         B.Pascal 7 & Objects/OW     - 296 -

              ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
              і  Константы шага     і     Константы семейства    і
              ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
              і   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);

         B.Pascal 7 & Objects/OW     - 297 -

                 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;



         B.Pascal 7 & Objects/OW     - 298 -

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

             Контекст дисплея позволяет вам рисовать в окне и, кроме это-
        го,  он содержит инструментальные средства рисования: перья, кис-
        ти, шрифты и палитры, которые вы используете для рисования текста
        и изображений.  При рисовании линии в контексте дисплея линия вы-
        водится со следующими атрибутами текущего пера: цвет, стиль (неп-
        рерывная,  пунктирная и т.п.) и толщина. При закрашивании области
        она выводится со следующими атрибутами текущей кисти:  образец  и
        цвет. При рисовании текста в контексте дисплея он выведется с ат-
        рибутами текущего шрифта:  шрифт (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.  Ни в коем случае не удаляйте

         B.Pascal 7 & Objects/OW     - 299 -

        инструментальные средства рисования, которые выбраны в данный мо-
        мент в контекст дисплея!

             Контекст дисплея  может хранить только по одному инструменту
        рисования каждого типа в данный  момент  времени,  поэтому  нужно
        отслеживать   доступные  инструментальные  средства  отображения.
        Очень важно удалить их все до завершения работы  вашего  приложе-
        ния. Один  из методов,  (использован в примере Главы 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

         B.Pascal 7 & Objects/OW     - 300 -

                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, который будет вызывать методы и функции, изоб-
        ражающие в окне текст и графику.

             Единственное, что  вы  можете  сделать с контекстом дисплея,
        это выбрать в него новый инструмент  рисования,  например,  перья
        других цветов или кисти других образцов. Вам придется указать эти

         B.Pascal 7 & Objects/OW     - 301 -

        инструменты в контексте дисплея рисования вашего метода 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);


         B.Pascal 7 & Objects/OW     - 302 -

                               Графические функции 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.



         B.Pascal 7 & Objects/OW     - 303 -

                               Функции рисования линий
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Функции рисования линии используют  для  рисования  заданное
        текущее перо контекста дисплея.  Большинство линий рисуется с ис-
        пользованием функций 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;

         B.Pascal 7 & Objects/OW     - 304 -

              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;



         B.Pascal 7 & Objects/OW     - 305 -

                                  Изображение фигур
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

                                Функция 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).

         B.Pascal 7 & Objects/OW     - 306 -


             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.



         B.Pascal 7 & Objects/OW     - 307 -

                                 Использование палитр
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

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

                                  Установка палитры
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Логические палитры являются инструментами рисования,  такими
        же  как  перья  и  кисти,  описанные  в разделе "Инструментальные
        средства изображения".  Для создания логической палитры использу-
        ется  функция  CreatePalette,  которая  берет указатель на запись
        данных LogPalette,  создает новую палитру и возвращает ее  описа-
        тель, который  передается  в  SelectPalette  для выбора палитры в
        контекст дисплея.  Запись TLogPalette содержит поля номера версии
        Windows (в настоящее время $0300), число элементов палитры и мас-
        сив элементов палитры.  Каждый элемент палитры - это запись  типа
        TPaletteEntry. Тип TPaletteEntry имеет три байтовых поля для спе-
        цификации цвета (peRed,  peGreen и peBlue) и одно поле для флагов
        (peFlags).

             GetStockObject(Default_Palette) создает  палитру  по умолча-
        нию, состоящую из 20 цветов, которые всегда присутствуют в палит-
        ре системы.

         B.Pascal 7 & Objects/OW     - 308 -


             После выбора   палитры   в   контекст   дисплея   с  помощью
        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  воспринимает

         B.Pascal 7 & Objects/OW     - 309 -

        индекс,  диапазон  и указатель на 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, это свиде-
        тельствует о том, что активное окно сменило системную палитру пу-
        тем реализации ее логической  палитры.  Окно,  принявшее  сообще-
        ние, может отреагировать на него тремя способами: оно может ниче-

         B.Pascal 7 & Objects/OW     - 310 -

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

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

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



         B.Pascal 7 & Objects/OW     - 311 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                         Глава 18. Более подробно о ресурсах
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

             Следующие ресурсы  вы будете создавать и использовать наибо-
        лее часто:

             - Меню.
             - Блоки диалога.
             - Пиктограммы.
             - Курсоры.
             - Оперативные клавиши.
             - Графические изображения.
             - Строки символов.

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

                                  Создание ресурсов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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


         B.Pascal 7 & Objects/OW     - 312 -

             Двоичный файл  ресурса (.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 представляет собой выбран-
        ного варианта меню (а не самого ресурса меню).  Каждый пункт меню
        имеет уникальный целочисленный идентификатор. В этом методе зада-
        ча состоит в организации соответствующей реакции на выбор  пункта
        меню. Обычно вы будете определять символьные константы для команд
        вашего меню.

                             Загрузка оперативных клавиш
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Оперативные клавиши  -  это  активные клавиши или комбинации

         B.Pascal 7 & Objects/OW     - 314 -

        клавиш, которые используются для задания команд приложения. Обыч-
        но  оперативные клавиши определяются как эквиваленты выбора пунк-
        тов меню.  Например,  клавиша 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, "Объекты окна".

                             Загрузка строковых ресурсов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
             Принципиальная причина выделения строк приложения в качестве

         B.Pascal 7 & Objects/OW     - 316 -

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

             Для загрузки строки из таблицы в буфер сегмента данных ваше-
        го   приложения   используется   функция   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;

             Данный пример загружает отдельную строку в блок сообщения об

         B.Pascal 7 & Objects/OW     - 317 -

        ошибке.  Для  загрузки  списка  строк  в  блок  списка вызывается
        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));

             После загрузки графического образа ваше приложение может ис-
        пользовать его разными способами:

             * Для рисования картинки на экране. Например, вы можете заг-
               рузить побитовое распределение в блок информации о  прило-
               жении в качестве заставки.

         B.Pascal 7 & Objects/OW     - 318 -


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

             * Для отображения картинок вместо текста  в  элементах  меню
               или  элементах  блока списка.  Например,  вы можете вместо
               слова 'Arrow' (стрелка) в пункте меню поместить  изображе-
               ние стрелки.

             Дополнительная информация относительно использования графики
        с побитовым отображением содержится в Главе 17.

             Если побитовое отображение не  используется,  то  его  нужно
        удалить из памяти.  В противном случае занимаемая им память будет
        недоступна другим приложениям. Даже если вы не удаляете его после
        использования  приложением,  вы обязательно должны удалить его до
        прекращения работы приложения. Графический образ удаляется из па-
        мяти с помощью функции Windows DeleteObject:

             if DeleteObject(HMyBit) then         { успешно };

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



         B.Pascal 7 & Objects/OW     - 319 -

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

             Вы можете  использовать графические образы для создания кис-
        тей, которые могут закрашивать области экрана. Область может быть
        закрашена сплошным цветом или в виде заданного образца. Минималь-
        ный размер используемого в кисти графического образа составляет 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;

         B.Pascal 7 & Objects/OW     - 320 -

               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 это его новый идентифика-
        тор. Однако, вы можете использовать один и тот же идентификатор в

         B.Pascal 7 & Objects/OW     - 321 -

        обоих случаях.

        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДВДї
        і±=±ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫStepsЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫі^іvі
        ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДБДґ
        іЫЫFileЫЫЫ  Help                                                і
        ГДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        іЫЫЫЫNewЫЫЫЫЫЫЫі                                                і
        і    pick      і                                                і
        і        me    і                                                і
        і    Save      і                                                і
        і    Save As   і                                                і
        ГДДДДДДДДДДДДДДЩ                                                і
        і                                                               і
        і                                                               і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

             Рис. 18.3. Меню, где в качестве одного из пунктов выбора ис-
        пользовано графическое изображение.



         B.Pascal 7 & Objects/OW     - 322 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                                   Глава 19. Наборы
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

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

                                   Объекты наборов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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


                       Динамическая установка размеров наборов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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


         B.Pascal 7 & Objects/OW     - 323 -

                                 Полиморфизм наборов
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

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

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

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



         B.Pascal 7 & Objects/OW     - 324 -

                Объединение в набор элементов, не являющихся объектами
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Вы даже можете добавить в набор нечто, что вообще не являет-
        ся объектом,  но это также может явиться серьезным предметом оза-
        боченности.  Наборы ожидают получения нетипизированных указателей
        незаданного типа на нечто.  Но некоторые методы 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);

         B.Pascal 7 & Objects/OW     - 325 -

               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 клиентов.  Следующие два опера-
        тора создают новый объект клиента и вставляют его в набор.  Вызов

         B.Pascal 7 & Objects/OW     - 326 -

        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) должна:

             * Быть  процедурой  - она не может быть функцией или методом

         B.Pascal 7 & Objects/OW     - 327 -

               объекта,  хотя данный пример показывает, что процедура мо-
               жет вызвать метод.

             * Быть локальной (вложенной) относительно вызывающей ее прог-
               раммы.

             * Описываться как дальняя процедура директивой 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;


         B.Pascal 7 & Objects/OW     - 328 -

             Снова обратите внимание на то,  что 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

         B.Pascal 7 & Objects/OW     - 329 -

               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.

                                     Наборы строк
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Многим программам  требуется  работать  с   отсортированными

         B.Pascal 7 & Objects/OW     - 330 -

        строками. Для этих целей 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:
        удаляется  каждый  элемент  набора, и  затем  удаляется сам набор

         B.Pascal 7 & Objects/OW     - 331 -

        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 метода.  Когда вы исполь-

         B.Pascal 7 & Objects/OW     - 332 -

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

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

             Если вы рассмотрите приведенные примеры наборов,  вы  можете
        заметить, что все элементы каждого набора были одно и того же ти-
        па.  Мы имели дело со списком строк в котором каждый элемент  был
        строкой.  Мы  также занимались списком клиентов.  Но наборы могут
        хранить любые производные от 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;

         B.Pascal 7 & Objects/OW     - 333 -

               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

         B.Pascal 7 & Objects/OW     - 334 -

               .
               .
               .
              if GraphicsList <> nil then DrawAll(GraphicsList);
               .
               .
               .
             end.

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



         B.Pascal 7 & Objects/OW     - 335 -

                             Наборы и управление памятью
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             TCollection может динамически расти от  начального  размера,
        установленного Init,  до максимального размера в 16380 элементов.
        ObjectWindows хранит  максимальный  размер  набора  в  переменной
        MaxCollectionSize.  Каждый  добавляемый  в набор элемент занимает
        четыре байта памяти, т.к. он хранится в виде указателя.

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

             Если не хватает памяти при добавлении элемента в  набор,  то
        вызывается метод TCollection.Error,  и возникает ошибка этапа вы-
        полнения в динамически распределяемой области памяти.  Вы  можете
        переписать  TCollection.Error для организации собственного метода
        информирования или исправления ошибки.

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



         B.Pascal 7 & Objects/OW     - 336 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                                   Глава 20. Потоки
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

             Есть ли  в самом объектно-ориентированном программировании и
        ObjectWindows некоторые средства,  которые могли бы разрешить эту
        проблему? Есть, и это потоки.

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

                             Вопрос: объектный ввод-вывод
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

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

             Но эту проблему снова можно обойти.  Вы можете выделить дан-

         B.Pascal 7 & Objects/OW     - 337 -

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

                                    Ответ: потоки
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

                                 Полиморфизм потоков
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

                             Потоки обрабатывают объекты
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             Но каким образом один и тот же поток может считывать и запи-
        сывать  такие  разные объекты как TCollection и TDialog,  даже не
        зная в момент компиляции,  какие типы объектов он будет обрабаты-
        вать?  Это  существенно  отличается от традиционных операций вво-
        да-вывода языка Паскаль.  В действительности потоки могут обраба-
        тывать даже новые типы объектов,  которые вообще еще не были соз-
        даны к моменту компиляции потока.

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



         B.Pascal 7 & Objects/OW     - 338 -

                             Смысл использования потоков
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

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

                                Установка потока

             Все что нужно сделать для использования потока - это инициа-
        лизировать  его.  Точный  синтаксис  конструктора Init может быть
        разным,  в зависимости от типа потока,  с которым вы имеете дело.
        Например,  если  вы открываете поток DOS,  вам нужно передать имя
        файла DOS и режим доступа (только  чтение,  только  запись,  чте-
        ние/запись) для содержащего поток файла.

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

             var
               SaveFile: TBufStream;
             begin
               SaveFile.Init('COLLECT.DTA', stOpen, 1024);
                .
                .

             После инициализации потока все готово к работе.

             TStream это абстрактный механизм потока,  поэтому  вы  будет
        работать не с ним, а с производными от TStream удобными объектами
        потока. Это будет,  например, TDosStream, для выполнения дисковых
        операций  ввода-вывода,  TBufStream  для  буферизованных операций
        ввода-вывода (очень удобен для частых операций считывания или за-
        писи небольших объемов информации на диск) и TEmsStream для пере-
        дачи объектов в память EMS.  Кроме того,  ObjectWindows реализует
        индексированные потоки с указателем,  указывающим место в потоке.
        Перемещая этот указатель вы можете организовать произвольный дос-
        туп в потоке.

         B.Pascal 7 & Objects/OW     - 339 -


                          Чтение из потока и запись в поток
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Основной объект потока 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 ищет сложные объекты. Следовательно, если вы
        ищите  в  потоке окно,  которое владеет дочерними окнами,  то они

         B.Pascal 7 & Objects/OW     - 340 -

        также будут загружены.

                                   Метод 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)

         B.Pascal 7 & Objects/OW     - 341 -

                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,  которая определяется следующим об-
        разом:


         B.Pascal 7 & Objects/OW     - 342 -

             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 и не
        требует никакого вмешательства с вашей стороны.  Оно просто обес-

         B.Pascal 7 & Objects/OW     - 343 -

        печивает внутреннее использование скомпонованного списка  регист-
        рационных записей потока.

                                 Регистрация на месте
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             После конструирования регистрационной записи потока вы вызы-
        ваете 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, ко-
        торая действительно пишет корректное число байт в поток.

         B.Pascal 7 & Objects/OW     - 344 -


             Ваш объект не должен ничего знать о потоке - это может  быть
        файл на диске,  память 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).

         B.Pascal 7 & Objects/OW     - 345 -


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

                               Добавление методов 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);

         B.Pascal 7 & Objects/OW     - 346 -

             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,  поскольку  в данном примере рассматривается

         B.Pascal 7 & Objects/OW     - 347 -

        только помещение данных в поток.  В следующем примере методы 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;

         B.Pascal 7 & Objects/OW     - 348 -


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

                                  Как все хранится?
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

                                    Поля в потоке
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             Решение состоит   в   использовании  методов  TWindowsObject
        GetChildPtr и PutChildPtr.  При хранении поля,  которое  является
        дочерним  окном,  вместо  записи указателя,  как если бы это была
        простая переменная, вы вызываете метод PutChildPtr, который запи-
        сывает  ссылку на  позицию  дочернего окна в списке дочерних окон
        группы.  Аналогично, при загрузке (Load) группы из потока, вы вы-
        зываете GetChildPtr,  который гарантирует,  что поле и список до-
        черних окон указывают на один и тот же объект.  Приведем короткий
        пример использования GetChildPtr и PutChildPtr в простом окне:

             type
               TDemoWinodw = object(TWindow)

         B.Pascal 7 & Objects/OW     - 349 -

               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;

         B.Pascal 7 & Objects/OW     - 350 -

                .
                .
                .
              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) объекты в конец ва-

         B.Pascal 7 & Objects/OW     - 351 -

        шего потока и считывали их назад (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 должны быть
        переписаны.  Если производный тип объекта имеет буфер,  то должен

         B.Pascal 7 & Objects/OW     - 352 -

        быть переписан и метод Flush.

                               Обработка ошибок потока
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             TStream имеет метод Error(Code,  Info),  который  вызывается
        при  обнаружении  ошибки  потока.  Error  просто присваивает полю
        Status потока значение одной из констант,  приведенных в Главе 21
        "Справочник по ObjectWindows" в разделе "Константы stXXXX".

             Поле ErrorInfo  не определено,  если значение Status не есть
        stGetError  или  stPutError.  Если  значение  поля  Status  равно
        stGetError, то поле ErrorInfo содержит номер идентификатора пото-
        ка незарегистрированного типа.  Если значение поля  Status  равно
        stPutError, то поле ErrorInfo содержит смещение VMT типа, который
        вы пытались поместить в поток. Вы можете переписать TStream.Error
        для генерации любого уровня обработки ошибок, включая ошибки эта-
        па выполнения.



         B.Pascal 7 & Objects/OW     - 353 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
                         Часть 4. Справочник по ObjectWindows
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


                        Глава 21. Объектные типы ObjectWindows
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

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

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



         B.Pascal 7 & Objects/OW     - 354 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         TSample                                            модуль TSample
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             TObject   TSample
             ЪДДДДДДї  ЪДДДДДДДДДДДДДДї
             ГДДДДДДґ  і AField       і
             іДInitДі  і AnotherField і
             і Done і  ГДДДДДДДДДДДДДДґ
             і Free і  і Init         і
             АДДДДДДЩ  і Zilch        і
                       АДДДДДДДДДДДДДДЩ

             Сначала дается  общее описание объекта,  его связи с дpугими
        объектами и использование.  На приведенной выше диаграмме показа-
        но,   что   объект  TSample  является  непосредственным  потомком
        TObject, и что он переопределяет конструктор Init.

                                         Поля
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

                                     AField

             AField: SomeType:                            (только чтение)

             AField - это поле,  которое содержит некоторую информацию  о
        данном примере объекта. Этот текст пояcняет, как оно функциониру-
        ет, что оно означает и как его использовать.

             См. также:  родственные поля,  методы,  объекты,  глобальные
        функции и т.д.

                                  AnotherField

             AhotherField: Word:                          (чтение/запись)

             Далее следует поясняющая информация, аналогичная AField.

                                        Методы
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             В данном разделе перечисляются все методы,  вновь определяе-
        мые для  данного объекта или переопределяющие наследуемые методы.
        Сначала перечисляются конструкторы, затем деструкторы, затем дру-
        гие методы в алфавитном порядке.

             Для виртуальных  методов указывается также,  насколько часто

         B.Pascal 7 & Objects/OW     - 355 -

        требуется переопределять метод: никогда, редко, иногда, часто или
        всегда.

                                         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 со счетчиком,  равным

         B.Pascal 7 & Objects/OW     - 356 -

        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     і Элемент выделен (серый).і
           АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДЩ



         B.Pascal 7 & Objects/OW     - 357 -

         Стили кнопок 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хнийі
        і                      і угол.                                  і

         B.Pascal 7 & Objects/OW     - 358 -

        ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і  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.



         B.Pascal 7 & Objects/OW     - 359 -

         Стили комбинированного блока 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ажает частич-і
        і                        і ные элементы.                        і
        ГДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ

         B.Pascal 7 & Objects/OW     - 360 -

        і  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.



         B.Pascal 7 & Objects/OW     - 361 -

         Константы 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.


         B.Pascal 7 & Objects/OW     - 362 -

                            Смещения команд на основе
                       используемых по умолчанию значений    Таблица 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_CascadeChildren і cm_Reserved + 17      і    Windowsі    і
        і                      і                       і     Cascade    і
        і   cm_CreateChild     і cm_Reserved + 18      і    Windowsі    і
        і                      і                       і   Close All    і
        і   cm_Exit            і cm_Reserved + 20      і    FileіExit   і
        АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДЩ

         B.Pascal 7 & Objects/OW     - 363 -

         Константы coXXXX                                   модуль Objects
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Назначение: Когда   TCollection  обнаруживает  при  операции
        ошибку,  константы coXXXX передаются методу  TCollection.Error  в
        качестве параметра Code.

             Значения: Для всех стандартных наборов ObjectWindows опреде-
        лены следующие стандартные коды ошибок:

                               Коды ошибок наборов           Таблица 21.6
        ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і    Код ошибки        і Значение   і          Смысл            і
        ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і    coIndexError      і    -1      і Индекс вне диапазона.  Па-і
        і                      і            і раметр Info,    переданныйі
        і                      і            і методу Error, содержит не-і
        і                      і            і допустимое значение индек-і
        і                      і            і са.                       і
        ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і    coOverflow        і    -2      і Переполнение       набора.і
        і                      і            і TCollection.SetLimit    неі
        і                      і            і удалось  расширить   наборі
        і                      і            і до требуемого размера. Пе-і
        і                      і            і реданный  методу Error па-і
        і                      і            і раметр содержит  требуемыйі
        і                      і            і размер.                   і
        АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

             См. также: объект TCollection.



         B.Pascal 7 & Objects/OW     - 364 -

         Стили класса 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;

         B.Pascal 7 & Objects/OW     - 366 -


             Назначение: Содержит  текущий  описатель  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едак-і

         B.Pascal 7 & Objects/OW     - 367 -

        і                     і ти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ажаемогоі
        і                     і символа  может  использоваться сообщениеі

         B.Pascal 7 & Objects/OW     - 368 -

        і                     і 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 для описания длины  буфера,  содержащего  имя  данного
        файла.

         B.Pascal 7 & Objects/OW     - 369 -

         Константы 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  возвращают  следующие
        значения для указания того,  какую командную кнопку "нажал" поль-
        зователь для закрытия диалогового блока или окна сообщений.  Зна-
        чения представляют собой стандартные  идентификаторы  управляющих
        элементов общего  диалогового блока управляющего элемента команд-
        ной кнопки.


         B.Pascal 7 & Objects/OW     - 370 -


             Значения: 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.


         B.Pascal 7 & Objects/OW     - 371 -


             Значения: 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      і Этот стиль блока списка  отвечает заі

         B.Pascal 7 & Objects/OW     - 372 -

        і                         і pисование его соде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
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


         B.Pascal 7 & Objects/OW     - 373 -

             Описание: 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, но использование этого наз-

         B.Pascal 7 & Objects/OW     - 374 -

        вания типа делает программу понятнее.

         Переменная MaxCollectionSize                       модуль Objects
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Описание: MaxCollectionSize = 65520 div SizeOf(Pointer);

             Назначение: MaxCollection определяет максимальное число эле-
        ментов, которые могут содержаться в наборе,  что в сущности равно
        числу указателей, которые можно разместить в сегменте памяти объ-
        емом 64К.



         B.Pascal 7 & Objects/OW     - 375 -

         Флаги блоков 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овняі

         B.Pascal 7 & Objects/OW     - 376 -

        і                      і в п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.


         B.Pascal 7 & Objects/OW     - 377 -

         Константы nf_XXXX                                 модуль OWindows
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

             Значения: Определены следующие константы:

                        Константы уведомляющих сообщений    Таблица 21.15
        ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і    Константа     і Значение   і          Смысл                і
        ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і    nf_First      і $9000      і Начало уведомляющих сообщений.і
        ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і    nf_Count      і $1000      і Число уведомляющих сообщений. і
        ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і    nf_Internal   і $9F00      і Начало уведомляющих сообщений,і
        і                  і            і зарезервированных для внутрен-і
        і                  і            і него использования.           і
        АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ



         B.Pascal 7 & Objects/OW     - 378 -

         Константы 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 определяет  несколько  констант,  используемых
        объектами принтера для определения состояния принтера.


         B.Pascal 7 & Objects/OW     - 379 -


             Определены следующие константы:

                           Константы состояния принтера     Таблица 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;


         B.Pascal 7 & Objects/OW     - 380 -

             Назначение: Вызывает 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;

         B.Pascal 7 & Objects/OW     - 381 -


             Если LowMemory равно True, что указывает на отсутствие буфе-
        ра надежности,  выделяет  для  буфера  надежности  SafetyPoolSize
        байт.

             См. также: функцию LowMemory, переменную SafetyPoolSize.

         Переменная SafetyPoolSize                          модуль OMemory
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Описание: SafetyPoolSize: Word = 8192;

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

             Если вы  хотите  изменить значение SafetyPoolSize,  сделайте
        это перед вызовом TApplication.Init,  который инициализирует дан-
        ный буфер.  Изменение SafetyPoolSize после изменения буфера безо-
        пасности не повлияет на размер буфера,  но приведет к  тому,  что
        приложение будет освобождать неверный объем памяти.

             См. также: LowMemory, MemAlloc, TApplication.ValidWindow.



         B.Pascal 7 & Objects/OW     - 382 -

         Стили полосы прокрутки 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утки будет иметь точ-і

         B.Pascal 7 & Objects/OW     - 383 -

        і                            і ный 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.



         B.Pascal 7 & Objects/OW     - 384 -

         Константы 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.



         B.Pascal 7 & Objects/OW     - 385 -

         Стили управляющего элемента 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авниваются слева.          і
        ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і  ss_LeftNoWordWrap і Этот стиль статического элемента упpавле-і
        і                    і ния отобpажает текст в левой части пpямо-і

         B.Pascal 7 & Objects/OW     - 386 -

        і                    і угольника.  Если длина текста больше, чемі
        і                    і ши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ная кисть.                            і

         B.Pascal 7 & Objects/OW     - 387 -

        і 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 этого
        потока.



         B.Pascal 7 & Objects/OW     - 388 -

         Константы 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.

         B.Pascal 7 & Objects/OW     - 389 -


         Константы отображения окна 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ом.                                   і
        ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ

         B.Pascal 7 & Objects/OW     - 390 -

        ЪДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і     Константа      і                    Смысл                 і
        ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і  sw_ShowMaximized  і Максимизиpовано и активно.               і
        ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і  sw_ShowMinimized  і Минимизиpовано и активно.                і
        ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і  sw_ShowMinNoActiveі Минимизиpовано.  Не влияет на активизациюі
        і                    і окна.                                    і
        ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і  sw_ShowMinNA      і В текущем состоянии окна.  Не  влияет  наі
        і                    і активизацию окна.                        і
        ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і  sw_ShowNoActive   і В текущем  положении  окна с текущим pаз-і
        і                    і меpом. Не влияет на активизацию окна.    і
        ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і  sw_ShowNormal     і Восстановлено и активно.                 і
        АДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

             См. также: переменную CmdShow, TWindowsObject.Show.



         B.Pascal 7 & Objects/OW     - 391 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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 указывает на текущее активное окно, если разре-
        шен механизм обработчика клавиатуры  этого  окна.  Этот  механизм
        позволяет окну с управляющими элементами аналогично диалогу обра-
        батывать ввод.  Если этот механизм для активного  окна  запрещен,

         B.Pascal 7 & Objects/OW     - 392 -

        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.

                         Done (иногда переопределяется)

         B.Pascal 7 & Objects/OW     - 393 -

        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Уничтожает объекты,  владельцем которых является приложение,
        отменяя основное окно,  а затем вызывая для завершения приложения
        наследуемый из 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 (никогда не переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         B.Pascal 7 & Objects/OW     - 394 -


             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;

         B.Pascal 7 & Objects/OW     - 395 -


             Выполняет инициализацию, необходимую для каждого выполняюще-
        гося экземпляра  приложения.  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р  вызывает

         B.Pascal 7 & Objects/OW     - 396 -

        р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;

         B.Pascal 7 & Objects/OW     - 397 -


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



         B.Pascal 7 & Objects/OW     - 398 -

                        Функция Run (переопределяется редко)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             рrocedure Run; virtual;

             Если инициализация  была успешной (то есть поле Status равно
        0), запускает выполнение приложения путем вызова MessageLooр.

             См. также: TApplication.MessageLooр.

                   SetKBHandler (никогда не переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             рrocedure SetKBHandler(AWindowsObject: рWindowObject);

             Активизирует обработку клавиатуры (перевод ввода  с  клавиа-
        туры  в  выбор элементов управления) для данного окна путем уста-
        новки KBHandlerWnd в AWindowsObject. (Используется для внутренне-
        го вызова в ObjectWindows.)

             См. также: TApplication.KBDHandlerWnd.



         B.Pascal 7 & Objects/OW     - 399 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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;


         B.Pascal 7 & Objects/OW     - 400 -

             Указывает на начало буфера потока.

                             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.


                       Done (никогда не переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             destructor Done; virtual;

             Закрывает и уничтожает файловый поток;  выводит и уничтожает
        его буфер.

             См. также: TBufStream.Flush.


                       Flush (никогда не переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             рrocedure Flush; virtual;

             Выводит буфер потока, обеспечивая для потока stOk.

         B.Pascal 7 & Objects/OW     - 401 -


             См. также: 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;

             Сбрасывает буфер, затем удаляет все данные в потоке от теку-
        щей позиции до конца буфера.  Текущая позиция  устанавливается  в
        новый конец потока.

         B.Pascal 7 & Objects/OW     - 402 -


             См. также: TBufStream.Getрos, TBufStream.Seek.

                       Write (никогда не переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             рrocedure Write(var Buf; Count: Word); virtual;

             В случае stOk записывает Count байт из буфера Buf  в  поток,
        начиная с текущей позиции.

             Заметим, что Buf не является буфером потока. Это внешний бу-
        фер, который содержит записываемые в  поток  данные.  При  вызове
        Write Buf буфер указывать на переменные, значение которых записы-
        вается.

             См. также: stWriteError, TBufStream.Read.



         B.Pascal 7 & Objects/OW     - 403 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 404 -


             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 "нажимаемой" (команд-
        ной)  кнопкой.  Существует два типа "нажимаемых" кнопок.  Обычная
        кнопка выводится с тонкой границей. Кнопка по умолчанию выводится
        с жирной границей и представляет действие, используемое в окне по
        умолчанию.  В окне может быть только одна кнопка, используемая по
        умолчанию.



         B.Pascal 7 & Objects/OW     - 405 -

                                       Методы
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Ниже описываются методы, определенные в данном объекте.

                                      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;

             Назначение: Тип байтового массива для общего использования в

         B.Pascal 7 & Objects/OW     - 406 -

        приведении типа.



         B.Pascal 7 & Objects/OW     - 407 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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;

         B.Pascal 7 & Objects/OW     - 409 -


             Поле 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.


         B.Pascal 7 & Objects/OW     - 410 -

             См. также: 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 информирует группу, что выбор

         B.Pascal 7 & Objects/OW     - 411 -

        изменился.

             См. также: 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.

         B.Pascal 7 & Objects/OW     - 412 -


             См. также: TCheckBox.SetCheck.



         B.Pascal 7 & Objects/OW     - 413 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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.

             Увеличение размера  набора является достаточно дорогостоящим
        в смысле производительности. Чтобы минимизировать число раз, ког-

         B.Pascal 7 & Objects/OW     - 414 -

        да это происходит, попробуйте установить начальное значение 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 (часто переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         B.Pascal 7 & Objects/OW     - 415 -


             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 элементов.  Если с помощью

         B.Pascal 7 & Objects/OW     - 416 -

        вызова 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 возвращает для

         B.Pascal 7 & Objects/OW     - 417 -

        всех элементов значение 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);


         B.Pascal 7 & Objects/OW     - 418 -

             См. также: 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.


         B.Pascal 7 & Objects/OW     - 419 -

             См. также: 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:

         B.Pascal 7 & Objects/OW     - 420 -


             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.



         B.Pascal 7 & Objects/OW     - 421 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 422 -


             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  комбинированным  блоком.

         B.Pascal 7 & Objects/OW     - 423 -

        Объекты комбинированного  блока  наследуют  большую  часть  своих
        функциональных возможностей от 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);


         B.Pascal 7 & Objects/OW     - 424 -

             Связывает объект  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)
        и возвращает число скопированных символов.


         B.Pascal 7 & Objects/OW     - 425 -

                                   GetTextLen
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             function GetTextLen: Integer;

             Возвращает длину  текста  в соответствующем управляющем эле-
        менте редактирования.

                                      HideList
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             рrocedure HideList;
                                                                                                   BNClicked
             Принудительно "скрывает" спускающийся список для всплывающе-
        го комбинированного блока или комбинированного блока списка.

                                     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;

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


         B.Pascal 7 & Objects/OW     - 426 -

                                       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.



         B.Pascal 7 & Objects/OW     - 427 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 428 -


             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) относительно начала области  пользователя

         B.Pascal 7 & Objects/OW     - 429 -

        порождающего окна,  шириной (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.



         B.Pascal 7 & Objects/OW     - 430 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 431 -


             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 содержит параметр, передаваемый
        диалоговой процедуре при создании диалога.


         B.Pascal 7 & Objects/OW     - 432 -

                                      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

         B.Pascal 7 & Objects/OW     - 433 -

                              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,

         B.Pascal 7 & Objects/OW     - 434 -

        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;

             Если диалоговый    блок    является    режимным,    вызывает

         B.Pascal 7 & Objects/OW     - 435 -

        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.

         B.Pascal 7 & Objects/OW     - 436 -


         Тип TDialogAttr                                   модуль ODialogs
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Описание:

             TDialogAttr = record
                   Name: рChar;
                   рaram: Longint;
             end;

             Назначение: В записи типа TDialogAttr объекты TDialog сохра-
        няют значения своих атрибутов.

             См. также: TDialog.Attr.



         B.Pascal 7 & Objects/OW     - 437 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

         B.Pascal 7 & Objects/OW     - 438 -


             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.

         B.Pascal 7 & Objects/OW     - 439 -


                        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.



         B.Pascal 7 & Objects/OW     - 440 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         B.Pascal 7 & Objects/OW     - 441 -


             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 байт до начала  по-

         B.Pascal 7 & Objects/OW     - 442 -

        тока.

             См. также: TDosStream.Getрos, TDosStream.GetSize.

                       Truncate (никогда не переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             рrocedure Trancate; virtual;

             Удаляет все данные в потоке от текущей позиции до конца.

                        Write (никогда не переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             рrocedure Write(var Buf; Count: Word); virtual;

             Записывает Count байт из буфера Buf в поток, начиная с теку-
        щей позиции.

             См. также: TDosStream.Read, stWriteError.



         B.Pascal 7 & Objects/OW     - 443 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 444 -


             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    і

         B.Pascal 7 & Objects/OW     - 445 -

                                    і 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
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


         B.Pascal 7 & Objects/OW     - 446 -

             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;

             Уничтожает управляющий элемент редактирования,  связанный  с

         B.Pascal 7 & Objects/OW     - 447 -

        объектом проверки допустимости, вызывая 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 (никогда не переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         B.Pascal 7 & Objects/OW     - 448 -


             р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.


         B.Pascal 7 & Objects/OW     - 449 -

                           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 (никогда не переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


         B.Pascal 7 & Objects/OW     - 450 -

             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.


         B.Pascal 7 & Objects/OW     - 451 -

             См. также: 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.

         B.Pascal 7 & Objects/OW     - 452 -


                        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
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


         B.Pascal 7 & Objects/OW     - 453 -

             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.

         B.Pascal 7 & Objects/OW     - 454 -


             См. также: 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 фокус ввода из
        управляющего элемента.  Для выполнения используемой по  умолчанию

         B.Pascal 7 & Objects/OW     - 455 -

        обработки сообщений 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.




         B.Pascal 7 & Objects/OW     - 456 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
          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;


         B.Pascal 7 & Objects/OW     - 457 -

             Устанавливается 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.

         B.Pascal 7 & Objects/OW     - 458 -


             См. также: 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 отделяет
        невыделенные части строки.


         B.Pascal 7 & Objects/OW     - 459 -

                                   SetPrintParams
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             procedure SetPrintParams(ADC: HDC; ASize: TPoint); virtual;

             Устанавливает контекст устройства объекта распечатки и печа-
        тает область заданного размера,  вызывая наследуемый из TPrintout
        метод SetPrintParams,  а затем получает число строк в Editor, вы-
        зывая метод GetNumLines.  Вычисляет LineHeight и LinesPerPage  на
        основе размера текста в контексте устройства, переданного в ADC.

             См. также: TPrintout.SetPrintParams.



         B.Pascal 7 & Objects/OW     - 460 -

         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 461 -


             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.

         B.Pascal 7 & Objects/OW     - 462 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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;

         B.Pascal 7 & Objects/OW     - 463 -


             Текущая позиция в потоке. Первая позиция - это 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 (никогда не переопределяется)

         B.Pascal 7 & Objects/OW     - 464 -

        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             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.

         B.Pascal 7 & Objects/OW     - 465 -


             Значения: Определены следующие константы:

                           Константы функции Transfer       Таблица 21.25
        ЪДДДДДДДДДДДДДДДДДВДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і   Константы     і Значение і              Смысл               і
        ГДДДДДДДДДДДДДДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і   tf_SizeData   і    0     і Определяет размер переданных объ-і
        і                 і          і ектом данных.                    і
        і                 і          і                                  і
        і   tf_GetData    і    1     і Считывает данные из объекта.     і
        і                 і          і                                  і
        і   tf_SetData    і    2     і Передает   данные  для  установкиі
        і                 і          і значения объекта.                і
        і                 і          і                                  і
        АДДДДДДДДДДДДДДДДДБДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ



         B.Pascal 7 & Objects/OW     - 466 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 467 -


             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 указывает  на  буфер,  который будет содержать выбранное
        пользователем имя маршрута.  Файловый диалоговый блок помещает  в

         B.Pascal 7 & Objects/OW     - 468 -

        буфер итоговое имя файла.

                                    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
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         B.Pascal 7 & Objects/OW     - 469 -


             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 от-
        меняет выбор выделенных элементов.



         B.Pascal 7 & Objects/OW     - 470 -

         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 471 -


             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.



         B.Pascal 7 & Objects/OW     - 472 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         B.Pascal 7 & Objects/OW     - 473 -


             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.



         B.Pascal 7 & Objects/OW     - 474 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 475 -


             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.


         B.Pascal 7 & Objects/OW     - 476 -

                                       Методы
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Ниже описываются методы, определенные в данном объекте.

                           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'.


         B.Pascal 7 & Objects/OW     - 477 -

                     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.



         B.Pascal 7 & Objects/OW     - 478 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 479 -


             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

         B.Pascal 7 & Objects/OW     - 480 -


             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;


         B.Pascal 7 & Objects/OW     - 481 -

             Назначение: Массив  общих  указателей,  предназначенных  для
        внутреннего использования в TCollection.



         B.Pascal 7 & Objects/OW     - 482 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 483 -


             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  и  добавляет  к  полю

         B.Pascal 7 & Objects/OW     - 484 -

        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 (никогда не переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


         B.Pascal 7 & Objects/OW     - 485 -

             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ица-
        тельное значение в случае ошибки.


         B.Pascal 7 & Objects/OW     - 486 -

                       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,
        который используется для блока списка, как буфер передачи.

             Характер записи может изменяться в зависимости от того,  до-
        пускает ли  блок выделение нескольких строк.  Первый передаваемый
        элемент всегда представляет собой указатель на набор строк, явля-
        ющихся записями блока списка. Для однострочных блоков списка этот
        указатель сопровождается целочисленными индексом выделенного эле-
        мента. Для  блоков  списка с возможностью выбора нескольких строк

         B.Pascal 7 & Objects/OW     - 487 -

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

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

             type
               TListBoxXferRec = record         { одиночный выбор }
                  Strings: PStrCollection;
                  Selection: Integer;
               end;

               TMultiListBoxXferRec = record    { множественный выбор }
                  Strings: PStrCollection;
                  Selection: PMultiSelRec;
               end;

             PMultiSelRec - это запись,  определенная в модуле  ODialogs.
        Запись должна выделяться с помощью функции AllocMultiSel, а осво-
        бождаться - с помощью FreeMultiSel.  Указатель nil  указывает  на
        отсутствие выбранных элементов.



         B.Pascal 7 & Objects/OW     - 488 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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 и

         B.Pascal 7 & Objects/OW     - 489 -

        выполнять поиск на основе фактического списка допустимых  элемен-
        тов.



         B.Pascal 7 & Objects/OW     - 490 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 491 -


             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

         B.Pascal 7 & Objects/OW     - 492 -

               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.  Дочерние окна могут перек-
        рываться, хотя заголовок каждого окна остается видимым.


         B.Pascal 7 & Objects/OW     - 493 -

                     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.



         B.Pascal 7 & Objects/OW     - 494 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 495 -


             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 определяет индекс, задающий позицию управляюще-
        го меню дочернего окна.  В индексе  учитываются  только  элементы
        верхнего уровня,  а  верхний левый элемент занимает нулевую пози-

         B.Pascal 7 & Objects/OW     - 496 -

        цию.

                            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  уничтожает  объект

         B.Pascal 7 & Objects/OW     - 497 -

        окна клиента 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;

         B.Pascal 7 & Objects/OW     - 498 -


             Вызывая 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 (иногда переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


         B.Pascal 7 & Objects/OW     - 499 -

             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 (часто переопределяется)

         B.Pascal 7 & Objects/OW     - 500 -

        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             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.



         B.Pascal 7 & Objects/OW     - 501 -

         Тип 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.



         B.Pascal 7 & Objects/OW     - 502 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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

         B.Pascal 7 & Objects/OW     - 503 -

                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.



         B.Pascal 7 & Objects/OW     - 504 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 505 -


             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


         B.Pascal 7 & Objects/OW     - 506 -

             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

         B.Pascal 7 & Objects/OW     - 507 -


             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);

         B.Pascal 7 & Objects/OW     - 508 -


             Строит диалоговый  блок печати,  вызывая сначала конструктор
        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;

             Назначение: Диалоговые   объекты   печати   используют   тип

         B.Pascal 7 & Objects/OW     - 509 -

        TPrintDialogRec как буферы передачи. Поля drStart и drStop предс-
        тавляют, соответственно,  первую и последнюю страницы для печати.
        drCopies  указывает  число  печатаемых копий.  drCollate сообщает
        принтеру о сравнении копий,  если drCopies  вызывается  несколько
        раз.  drUseSelection сообщает принтеру о печати выделенного текс-
        та, а не текста, указанного drStart и drStop.



         B.Pascal 7 & Objects/OW     - 510 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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

         B.Pascal 7 & Objects/OW     - 511 -


             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


         B.Pascal 7 & Objects/OW     - 512 -

             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;


         B.Pascal 7 & Objects/OW     - 513 -

             Возвращает для  текущего связанного с объектом принтера кон-
        текст устройства. Если объект находится в недопустимом состоянии,
        или принтер связан с неактивным портом (то есть с портом "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;

             Переводит указанный объект распечатки на связанное  устройс-
        тво печати.  При печати выводит на экран диалоговое окно прерыва-

         B.Pascal 7 & Objects/OW     - 514 -

        ния и обнаруженные ошибки.

                       ReportError (иногда переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             procedure ReportError(PrintOut: PPrintOut); virtual;

             Print вызывает  ReportError в случае обнаружения ошибки.  По
        умолчанию выводится блок системного сообщения со строкой  ошибки,
        полученной из значений таблицы строк 32512 - 32519. Чтобы вывести
        специализированный диалоговый блок ошибки, данный метод можно пе-
        реопределить.

                                     SetDevice
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             procedure SetDevice(ADevice, ADriver, APort: PChar);

             Изменяет связь   с   устройством   печати.   Setup  вызывает
        SetDevice для интерактивного изменения связи. Допустимые парамет-
        ры данного метода можно найти в секции устройств файла WIN.INI.

             Записи секции устройств имеют следующий формат:

             <имя_устройства>=<драйвер>, <порт> {, <порт>}

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

                                       Setup
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             procedure Setup(Parent: PWindowsObject);

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



         B.Pascal 7 & Objects/OW     - 515 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 516 -


             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).


         B.Pascal 7 & Objects/OW     - 517 -

                        SetupWindow (переопределяется редко)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             procedure SetupWindow; virtual;

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

                         WMCommand (переопределяется редко)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             procedure WMCommand(var Msg: TMessage); virtual
                                 wm_First + wm_Command;

             Предназначена для  внутренней работы с кнопкой Cancel (Отме-
        на).



         B.Pascal 7 & Objects/OW     - 518 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 519 -


             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);

             Строит диалоговый  блок  установки принтера,  модифицирующий
        указанный принтер.


         B.Pascal 7 & Objects/OW     - 520 -

                           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;

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



         B.Pascal 7 & Objects/OW     - 521 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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

         B.Pascal 7 & Objects/OW     - 522 -


             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  один  раз

         B.Pascal 7 & Objects/OW     - 523 -

        перед печатью   каждой   копии   документа.   Поле  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, если выбор страниц возможен. Ис-

         B.Pascal 7 & Objects/OW     - 524 -

        пользовать 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;

         B.Pascal 7 & Objects/OW     - 525 -


             Устанавливает поля DC и Size в ADC  и  ASize  соответственно.
        Это первый  метод  распечатки,  вызываемый  методом  Print объекта
        принтера и обеспечивающий объект распечатки информацией, необходи-
        мой для  разбиения  на страницы и ведения счетчика страниц.  Если
        наследующие объекты переопределяют SetPrintParams, они должны вы-
        зывать наследуемый метод.



         B.Pascal 7 & Objects/OW     - 526 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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.


         B.Pascal 7 & Objects/OW     - 527 -

                                        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;

         B.Pascal 7 & Objects/OW     - 528 -


             Сравнивает переданную в 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.


         B.Pascal 7 & Objects/OW     - 529 -


             Символы, используемые для создания трафаретов формата, пока-
        заны в следующей таблице:

                            Символы трафарета формата       Таблица 21.26
        ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і    Тип символа   і Символ  і        Описание                  і
        ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і    Специальный   і   #     і Воспринимается только цифра.     і
        і                  і         і                                  і
        і                  і   ?     і Воспринимается только буква  (безі
        і                  і         і различия регистра).              і
        і                  і         і                                  і
        і                  і   &     і Воспринимается только буква (пре-і
        і                  і         і образуется в верхний регистр).   і
        і                  і         і                                  і
        і                  і   @     і Воспринимается любой символ.     і
        і                  і         і                                  і
        і                  і   !     і Воспринимается любой символ (пре-і
        і                  і         і образуется в верхний регистр).   і
        ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і    Соответствие  і   ;     і Следующий  символ  воспринимаетсяі
        і                  і         і литерально.                      і
        і                  і         і                                  і
        і                  і   *     і Счетчик повторения.              і
        і                  і         і                                  і
        і                  і   []    і Параметр.                        і
        і                  і         і                                  і
        і                  і   {}    і Группирование операций.          і
        і                  і         і                                  і
        і                  і   '     і Набор альтернатив.               і
        ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і    Все прочие    і         і Воспринимаются литерально.       і
        і                  і         і                                  і
        АДДДДДДДДДДДДДДДДДДБДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

             См. также: тип TPicResult.

                                       Store
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             procedure Store(var S: TStream);

             Сохраняет объект проверки допустимости по трафарету в потоке
        S, вызывая  сначала при записи строки,  на которую указывает Pic,
        наследуемый из TValidator метод Store.



         B.Pascal 7 & Objects/OW     - 530 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 531 -


             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авляющие элементы.

                                       Методы
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Ниже описываются методы, определенные в данном объекте.


         B.Pascal 7 & Objects/OW     - 532 -

                           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.

         B.Pascal 7 & Objects/OW     - 533 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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 - это наименьшее допустимое длинное целое  значение  для
        строки ввода.

                                       Методы
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         B.Pascal 7 & Objects/OW     - 534 -


             Ниже описываются методы, определенные в данном объекте.

                                        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.


         B.Pascal 7 & Objects/OW     - 535 -

                                       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.



         B.Pascal 7 & Objects/OW     - 536 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 537 -


             TWindow                TControl
             ЪДДДДДДДДДДДДДДДДДДДї  ЪДДДДДДДДДДДДДДДДДї
             і Attr              і  ГДДДДДДДДДДДДДДДДДґ
             і DefaultProc       і  іДInitДДДДДДДДДДДДі
             і Scrol[ler         і  іДInitResourceДДДДі
             і 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.


         B.Pascal 7 & Objects/OW     - 538 -

                                        Поля
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

                          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);

             Связывает объект  полосы прокрутки с управляющим элементом в

         B.Pascal 7 & Objects/OW     - 539 -

        ресурсе, заданным   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.

         B.Pascal 7 & Objects/OW     - 540 -


                         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х   или   влево   на

         B.Pascal 7 & Objects/OW     - 541 -

        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;

             Устанавливает допустимый диапазон  для  положений  указателя

         B.Pascal 7 & Objects/OW     - 542 -

        п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;



         B.Pascal 7 & Objects/OW     - 543 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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 имеет значение

         B.Pascal 7 & Objects/OW     - 544 -

        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 для горизонтальной прокрутки
        в ответ на нажатие кнопки "мыши" на области курсора полосы  гори-

         B.Pascal 7 & Objects/OW     - 545 -

        зонтальной прокрутки. По умолчанию 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 (только чтение)

         B.Pascal 7 & Objects/OW     - 546 -


             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, для унич-
        тожения объекта прокрутки.


         B.Pascal 7 & Objects/OW     - 547 -

                        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 (переопределяется редко)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         B.Pascal 7 & Objects/OW     - 548 -


             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
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         B.Pascal 7 & Objects/OW     - 549 -


             procedure Store(var S: TStream);

             Записывает объект   прокрутки  в  поток  S,  записывая  поля
        TScroller, за исключением XPage, YPage, XPos, YPos.

                       VScroll (никогда не переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             procedure VScroll(ScrollEvent: Word; ThumbPos: Integer);
                               virtual;

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

             См. также: TWindow.WMVScroll.



         B.Pascal 7 & Objects/OW     - 550 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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, что позво-
        лит использовать в наборе элементы с дублирующимися ключами.

                                        Поля
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         B.Pascal 7 & Objects/OW     - 551 -


                           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;

         B.Pascal 7 & Objects/OW     - 552 -


             Использует 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.


         B.Pascal 7 & Objects/OW     - 553 -

                                       Store
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             procedure Store(var S: Stream);

             Записывает отсортированный набор и его элементы в потоке  S,
        вызывая для записи набора TCollection.Store,  а затем записывая в
        поток поле Duplicates.

             См. также: TSortedCollection.Store.



         B.Pascal 7 & Objects/OW     - 554 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 555 -


             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.

                                       Методы
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Ниже описываются методы, определенные в данном объекте.

         B.Pascal 7 & Objects/OW     - 556 -


                                        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;


         B.Pascal 7 & Objects/OW     - 557 -

             Возв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 без передачи данных.



         B.Pascal 7 & Objects/OW     - 558 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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.

         B.Pascal 7 & Objects/OW     - 559 -


             См. также: 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.



         B.Pascal 7 & Objects/OW     - 560 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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 (чтение/запись)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


         B.Pascal 7 & Objects/OW     - 561 -

             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 ничего  не
        делает и должна переопределяться в наследующих типах,  где реали-

         B.Pascal 7 & Objects/OW     - 562 -

        зуются буферы.

             См. также: 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 записи регистрации) и, наконец, вы-

         B.Pascal 7 & Objects/OW     - 563 -

        зывает метод 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.  Это абстрактный метод, ко-
        торый должен переопределяться во всех потомках.


         B.Pascal 7 & Objects/OW     - 564 -

             См. также: 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.

         B.Pascal 7 & Objects/OW     - 565 -

         Тип 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:


         B.Pascal 7 & Objects/OW     - 566 -

             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.

         B.Pascal 7 & Objects/OW     - 567 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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.

         B.Pascal 7 & Objects/OW     - 568 -


                                        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 уничтожает существующий  список,  не
        присваивая новый.


         B.Pascal 7 & Objects/OW     - 569 -

                                       Store
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             procedure Store(var S: TStream);

             Записывает объект проверки допустимости с просмотром строк в
        потоке S, вызывая сначала метод Store, наследуемый из TValidatos,
        а затем записывая содержащийся в Strings набор строк.



         B.Pascal 7 & Objects/OW     - 570 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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.

                                       Методы
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Ниже перечисляются методы, содержащиеся в данном объекте.


         B.Pascal 7 & Objects/OW     - 571 -

                                        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;


         B.Pascal 7 & Objects/OW     - 572 -

             Если строка ввода имеет соответствующий объект проверки  до-
        пустимости, то  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 в  запись  дан-
        ных.

             По умолчанию строки ввода с проверкой допустимости дают сна-
        чала объекту  проверки  допустимости  возможность   ответить   на

         B.Pascal 7 & Objects/OW     - 573 -

        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.



         B.Pascal 7 & Objects/OW     - 574 -

         Тип 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 - это описатели пиктог-

         B.Pascal 7 & Objects/OW     - 575 -

        раммы, курсора  класса и фонового цвета класса соответственно.  В
        качестве фонового цвета должно указываться значение  цвета  (один
        из стандартных системных цветов, заданный константой color_, уве-
        личенный на 1) или  описатель  кисти  для  раскраски  фона.  Если
        hbgBackGround равно  0,  то  фон приложения должен раскрашиваться
        при раскраске области клиента.  Необходимость этого можно опреде-
        лить обработкой сообщения wm_EraseBkgnd или проверкой поля fErase
        записи TPaintStruct, созданной BeginPaint.

             Поля lpszMenuName и lpszClassName указывают на строки с  за-
        вершающим нулем, представляющими, соответственно, имя ресурса ме-
        ню класса и имя класса.

             См. также: TWindowsObject.GetWindowClass.



         B.Pascal 7 & Objects/OW     - 576 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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ДДДДДДДДДДі
                       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ


         B.Pascal 7 & Objects/OW     - 577 -


             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,  но  могут  переопределяться  в
        конструкторах наследующих типов.


         B.Pascal 7 & Objects/OW     - 578 -

             См. также: тип 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 в их соот-
        ветствующие используемые по умолчанию  значения  для  образования
        перекрывающихся и всплывающих окон.

         B.Pascal 7 & Objects/OW     - 579 -


             В конструкторе объекта, производного от 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,  и  вызывается

         B.Pascal 7 & Objects/OW     - 580 -

        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.


         B.Pascal 7 & Objects/OW     - 581 -

                           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;


         B.Pascal 7 & Objects/OW     - 582 -

             Устанавливает 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;

             Этот метод при автоматической прокрутки отвечает на  нажатие
        левой  кнопки  "мыши",  перехватывая весь будущий ввод от "мыши",
        пока левая кнопка "мыши" не будет освобождена. Если вы планируете

         B.Pascal 7 & Objects/OW     - 583 -

        для обработки  нажатий кнопок "мыши" переопределить данный метод,
        но все равно собираетесь пользоваться автоматической  прокруткой,
        убедитесь, что   этот   метод   вызывается   из   вашего   метода
        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:

         B.Pascal 7 & Objects/OW     - 584 -

                             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.



         B.Pascal 7 & Objects/OW     - 585 -

         Тип 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.



         B.Pascal 7 & Objects/OW     - 586 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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);

             Строит объект  распечатки  окна, вызывая сначала конструктор

         B.Pascal 7 & Objects/OW     - 587 -

        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.



         B.Pascal 7 & Objects/OW     - 588 -

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         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 (только чтение)

         B.Pascal 7 & Objects/OW     - 589 -


             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 в коде наследующих объ-
        ектных типов, чтобы отметить ошибку инициализации.


         B.Pascal 7 & Objects/OW     - 590 -

             Возможные значения ошибки,  определенные  в  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.  Уничтожает все свои  до-
        черние окна  и удаляет себя из списка дочерних окон своего порож-
        дающего окна.  Деструкторы всех наследующих типов должны включать

         B.Pascal 7 & Objects/OW     - 591 -

        в себя вызов 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.


         B.Pascal 7 & Objects/OW     - 592 -

                                       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;

         B.Pascal 7 & Objects/OW     - 593 -


             Выполняет станда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.

         B.Pascal 7 & Objects/OW     - 594 -

                                 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;


         B.Pascal 7 & Objects/OW     - 595 -

             Обеспечивает, чтобы  инте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

         B.Pascal 7 & Objects/OW     - 596 -

                  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
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


         B.Pascal 7 & Objects/OW     - 597 -

             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;  таким образом, разыменование указа-

         B.Pascal 7 & Objects/OW     - 598 -

        теля братского окна в конструкторе 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;

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


         B.Pascal 7 & Objects/OW     - 599 -

             См. также: 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,  если
        класс успешно зарегистрирован.


         B.Pascal 7 & Objects/OW     - 600 -

             См. также:                      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                і Скрыто                           і

         B.Pascal 7 & Objects/OW     - 601 -

          і 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 объекта
        приложения.


         B.Pascal 7 & Objects/OW     - 602 -

             См. также: 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 (никогда не переопределяется)
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

         B.Pascal 7 & Objects/OW     - 603 -


             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;

             Назначение: Тип массива с элементами размером  в  слово  для
        общего использования.

         B.Pascal 7 & Objects/OW     - 604 -

         Константы 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.          і
        АДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

         B.Pascal 7 & Objects/OW     - 605 -

         Константы vsXXXX                                  модуль Validate
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Назначение: Объекты строки ввода используют vsOK для провер-
        ки и правильного построения соответствующих объектов проверки до-
        пустимости. При вызове с командным параметром или  cmValid  метод
        Valid объекта  строки  ввода проверяет поле Status своего объекта
        проверки допустимости.  Если Status равно vsOK,  то  метод  Valid
        строки ввода возвращает значение True,  указывая, что объект про-
        верки допустимости можно использовать.

             Единственное значение, определенное для поля Status и отлич-
        ное от  vsOK  - это vsSyntax,  используемое в TPXPictureValidator
        для указания,  что невозможно интерпретировать переданную  строку
        трафарета. Если вы создаете собственные объекты проверки допусти-
        мости, то можете определить коды ошибок и возвратить  их  в  поле
        Status.

             Значения: Модуль Validate определяет две константы,  исполь-
        зуемые в объектах проверки допустимости  для  сообщения  о  своем
        состоянии.

         Константы состояния объекта проверки допустимости  Таблица 21.30
        ЪДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і    Константа      і  Значение   і         Смысл               і
        ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і    vsOK           і    0        і Объект проверки допустимостиі
        і                   і             і построен правильно.         і
        ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
        і    vsSyntax       і    1        і Ошибка синтаксиса в трафаре-і
        і                   і             і те шаблона объекта проверки.і
        АДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

             См. также: TValidator.Status.

         B.Pascal 7 & Objects/OW     - 606 -

         Константы 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. і
            АДДДДДДДДДДДДДДДБДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

         B.Pascal 7 & Objects/OW     - 607 -


ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
         Тип WordRec                                        модуль Objects
        ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

             Описание:

             WordRec = record
                 Lo, Hi: Byte;
             end;

             Назначение: Рабочая запись, позволяющая обращаться к старшим
        (Hi) и младшим (Lo) байтам слова.

             См. также: LongRec.



         B.Pascal 7 & Objects/OW     - 608 -

         Стили окна 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.                            і
        ГДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ

         B.Pascal 7 & Objects/OW     - 609 -

        і   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.


?????? ???????????