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