- •Содержание
- •Глава 1 README.TXT
- •Вызов, брошенный программистам
- •Основные правила
- •Краткая история Windows
- •Краткая история этой книги
- •Начнем
- •Глава 2 Hello, Windows 95
- •Отличительная особенность Windows
- •Графический интерфейс пользователя
- •Концепции и обоснование GUI
- •Содержимое интерфейса пользователя
- •Преимущество многозадачности
- •Управление памятью
- •Независимость графического интерфейса от оборудования
- •Соглашения операционной системы Windows
- •Вызовы функций
- •Объектно-ориентированное программирование
- •Архитектура, управляемая событиями
- •Оконная процедура
- •Ваша первая программа для Windows
- •Что в этой программе неправильно?
- •Файлы HELLOWIN
- •Make-файл
- •Вызовы функций Windows
- •Идентификаторы, написанные прописными буквами
- •Новые типы данных
- •Описатели
- •Венгерская нотация
- •Точка входа программы
- •Регистрация класса окна
- •Создание окна
- •Отображение окна
- •Цикл обработки сообщений
- •Оконная процедура
- •Обработка сообщений
- •Воспроизведение звукового файла
- •Сообщение WM_PAINT
- •Сообщение WM_DESTROY
- •Сложности программирования для Windows
- •Не вызывай меня, я вызову тебя
- •Синхронные и асинхронные сообщения
- •Думайте о ближнем
- •Кривая обучения
- •Глава 3 Рисование текста
- •Рисование и обновление
- •Сообщение WM_PAINT
- •Действительные и недействительные прямоугольники
- •Введение в графический интерфейс устройства (GDI)
- •Контекст устройства
- •Структура информации о рисовании
- •Получение описателя контекста устройства. Второй метод
- •Функция TextOut. Подробности
- •Системный шрифт
- •Размер символа
- •Метрические параметры текста. Подробности
- •Форматирование текста
- •Соединим все вместе
- •Не хватает места!
- •Размер рабочей области
- •Полосы прокрутки
- •Диапазон и положение полос прокрутки
- •Сообщения полос прокрутки
- •Прокрутка в программе SYSMETS
- •Структурирование вашей программы для рисования
- •Создание улучшенной прокрутки
- •Мне не нравится пользоваться мышью
- •Глава 4 Главное о графике
- •Концепция GDI
- •Структура GDI
- •Типы функций
- •Примитивы GDI
- •Другие аспекты
- •Контекст устройства
- •Получение описателя контекста устройства
- •Программа DEVCAPS1
- •Размер устройства
- •О цветах
- •Атрибуты контекста устройства
- •Сохранение контекста устройства
- •Рисование отрезков
- •Ограничивающий прямоугольник
- •Сплайны Безье
- •Использование стандартных перьев
- •Создание, выбор и удаление перьев
- •Закрашивание пустот
- •Режимы рисования
- •Рисование закрашенных областей
- •Функция Polygon и режим закрашивания многоугольника
- •Закрашивание внутренней области
- •Режим отображения
- •Координаты устройства (физические координаты) и логические координаты
- •Системы координат устройства
- •Область вывода и окно
- •Работа в режиме MM_TEXT
- •Метрические режимы отображения
- •Ваши собственные режимы отображения
- •Программа WHATSIZE
- •Прямоугольники, регионы и отсечение
- •Работа с прямоугольниками
- •Случайные прямоугольники
- •Создание и рисование регионов
- •Отсечения: прямоугольники и регионы
- •Программа CLOVER
- •Пути
- •Создание и воспроизведение путей
- •Расширенные перья
- •Bits and Blts
- •Цвета и битовые образы
- •Файл DIB
- •Упакованный формат хранения DIB
- •Отображение DIB
- •Преобразование DIB в объекты "битовые образы"
- •Битовый образ — объект GDI
- •Создание битовых образов в программе
- •Формат монохромного битового образа
- •Формат цветного битового образа
- •Контекст памяти
- •Мощная функция BitBlt
- •Перенос битов с помощью функции BitBlt
- •Функция DrawBitmap
- •Использование других ROP кодов
- •Дополнительные сведения о контексте памяти
- •Растяжение битовых образов с помощью функции StretchBlt
- •Кисти и битовые образы
- •Метафайлы
- •Простое использование метафайлов памяти
- •Сохранение метафайлов на диске
- •Расширенные метафайлы
- •Делаем это лучше
- •Базовая процедура
- •Заглянем внутрь
- •Вывод точных изображений
- •Текст и шрифты
- •Вывод простого текста
- •Атрибуты контекста устройства и текст
- •Использование стандартных шрифтов
- •Типы шрифтов
- •Шрифты TrueType
- •Система EZFONT
- •Внутренняя работа
- •Форматирование простого текста
- •Работа с абзацами
- •Глава 5 Клавиатура
- •Клавиатура. Основные понятия
- •Игнорирование клавиатуры
- •Фокус ввода
- •Аппаратные и символьные сообщения
- •Аппаратные сообщения
- •Системные и несистемные аппаратные сообщения клавиатуры
- •Переменная lParam
- •Виртуальные коды клавиш
- •Использование сообщений клавиатуры
- •Модернизация SYSMETS: добавление интерфейса клавиатуры
- •Логика обработки сообщений WM_KEYDOWN
- •Посылка асинхронных сообщений
- •Символьные сообщения
- •Сообщения WM_CHAR
- •Сообщения немых символов
- •Каретка (не курсор)
- •Функции работы с кареткой
- •Программа TYPER
- •Наборы символов Windows
- •Набор символов OEM
- •Набор символов ANSI
- •Наборы символов OEM, ANSI и шрифты
- •Международные интересы
- •Работа с набором символов
- •Связь с MS-DOS
- •Использование цифровой клавиатуры
- •Решение проблемы с использованием системы UNICODE в Windows NT
- •Глава 6 Мышь
- •Базовые знания о мыши
- •Несколько кратких определений
- •Сообщения мыши, связанные с рабочей областью окна
- •Простой пример обработки сообщений мыши
- •Обработка клавиш <Shift>
- •Сообщения мыши нерабочей области
- •Сообщение теста попадания
- •Сообщения порождают сообщения
- •Тестирование попадания в ваших программах
- •Гипотетический пример
- •Пример программы
- •Эмуляция мыши с помощью клавиатуры
- •Добавление интерфейса клавиатуры к программе CHECKER
- •Использование дочерних окон для тестирования попадания
- •Дочерние окна в программе CHECKER
- •Захват мыши
- •Рисование прямоугольника
- •Решение проблемы — захват
- •Программа BLOKOUT2
- •Глава 7 Таймер
- •Основы использования таймера
- •Система и таймер
- •Таймерные сообщения не являются асинхронными
- •Использование таймера: три способа
- •Первый способ
- •Второй способ
- •Третий способ
- •Использование таймера для часов
- •Позиционирование и изменение размеров всплывающего окна
- •Получение даты и времени
- •Обеспечение международной поддержки
- •Создание аналоговых часов
- •Стандартное время Windows
- •Анимация
- •Класс кнопок
- •Создание дочерних окон
- •Сообщения дочерних окон родительскому окну
- •Сообщения родительского окна дочерним окнам
- •Нажимаемые кнопки
- •Флажки
- •Переключатели
- •Окна группы
- •Изменение текста кнопки
- •Видимые и доступные кнопки
- •Кнопки и фокус ввода
- •Дочерние окна управления и цвета
- •Системные цвета
- •Цвета кнопок
- •Сообщение WM_CTLCOLORBTN
- •Кнопки, определяемые пользователем
- •Класс статических дочерних окон
- •Класс полос прокрутки
- •Программа COLORS1
- •Интерфейс клавиатуры, поддерживаемый автоматически
- •Введение новой оконной процедуры
- •Закрашивание фона
- •Окрашивание полос прокрутки и статического текста
- •Класс редактирования
- •Стили класса редактирования
- •Коды уведомления управляющих окон редактирования
- •Использование управляющих окон редактирования
- •Сообщения управляющему окну редактирования
- •Класс окна списка
- •Стили окна списка
- •Добавление строк в окно списка
- •Выбор и извлечение элементов списка
- •Получение сообщений от окон списка
- •Простое приложение, использующее окно списка
- •Список файлов
- •Утилита Head для Windows
- •Компиляция ресурсов
- •Значки и курсоры
- •Редактор изображений
- •Получение описателя значков
- •Использование значков в вашей программе
- •Использование альтернативных курсоров
- •Битовые образы: картинки в пикселях
- •Использование битовых образов и кистей
- •Символьные строки
- •Использование ресурсов-символьных строк
- •Меню
- •Структура меню
- •Шаблон меню
- •Ссылки на меню в вашей программе
- •Меню и сообщения
- •Образец программы
- •Этикет при организации меню
- •Сложный способ определения меню
- •Третий подход к определению меню
- •Независимые всплывающие меню
- •Использование системного меню
- •Изменение меню
- •Другие команды меню
- •Использование в меню битовых образов
- •Два способа создания битовых образов для меню
- •Контекст памяти
- •Создание битового образа, содержащего текст
- •Масштабирование битовых образов
- •Соберем все вместе
- •Добавление интерфейса клавиатуры
- •Быстрые клавиши
- •Зачем нужны быстрые клавиши?
- •Некоторые правила назначения быстрых клавиш
- •Таблица быстрых клавиш
- •Преобразование нажатий клавиш клавиатуры
- •Получение сообщений быстрых клавиш
- •Программа POPPAD, имеющая меню и быстрые клавиши
- •Разрешение пунктов меню
- •Обработка опций меню
- •Глава 11 Окна диалога
- •Модальные окна диалога
- •Создание окна диалога About
- •Шаблон окна диалога
- •Диалоговая процедура
- •Вызов окна диалога
- •Дополнительная информация о стиле окна диалога
- •Дополнительная информация об определении дочерних окон элементов управления
- •Более сложное окно диалога
- •Работа с дочерними элементами управления окна диалога
- •Кнопки OK и Cancel
- •Позиции табуляции и группы
- •Рисование в окне диалога
- •Использование с окном диалога других функций
- •Определение собственных окон управления
- •Окна сообщений
- •Информация во всплывающих окнах
- •Немодальные окна диалога
- •Различия между модальными и немодальными окнами диалога
- •Новая программа COLORS
- •Программа HEXCALC: обычное окно или окно диалога?
- •Творческое использование идентификаторов дочерних окон элементов управления
- •Диалоговые окна общего пользования
- •Модернизированная программа POPPAD
- •Изменение шрифта
- •Поиск и замена
- •Программа для Windows, содержащая всего один вызов функции
- •Основы элементов управления общего пользования
- •Инициализация библиотеки
- •Создание элементов управления общего пользования
- •Стили элементов управления общего пользования
- •Уведомляющие сообщения от элементов управления общего пользования
- •Элементы управления главного окна
- •Панели инструментов
- •Создание панели инструментов
- •Строка состояния
- •Программа GADGETS
- •Наборы страниц свойств
- •Создание набора страниц свойств
- •Процедуры диалогового окна страницы свойств
- •Программа PROPERTY
465
Программа GADGETS посылает простой набор сообщений своей панели инструментов. Большинство из них относятся к действиям с конкретными кнопками, такие как TB_CHECKBUTTON для установки нажатого (checking) или отжатого (unchecking) состояния кнопки, и TB_ENABLEBUTTON для разрешения или запрещения действий над кнопкой. Два сообщения с запросами позволяют вам узнать число кнопок и число строк.
Сообщение TB_CUSTOMIZE вызывает появление диалогового окна изменения конфигурации (Customize Toolbar dialog box), что дает пользователю возможность добавить или удалить кнопку из панели инструментов. Ключом к правильной работе диалогового окна изменения конфигурации является правильная обработка уведомляющих сообщений TBN_QUERYINSERT, TBN_QUERYDELETE и TBN_GETBUTTONINFO. При изменении конфигурации панели инструментов следите за потоком уведомляющих сообщений, чтобы прочувствовать последовательность этих запросов.
Управление строкой состояния программы GADGETS
Программа GADGETS содержит меню для управления стилями строки состояния и для посылки ей сообщений. Это меню имеет намного меньше команд, чем соответствующее меню панели инструментов, поскольку строка состояния значительно проще, чем панель инструментов.
Наиболее интересным аспектом управления строкой состояния в программе GADGETS является то, каким образом программа обрабатывает сообщение WM_MENUSELECT с целью отображения в строке состояния вспомогательной информации. Все строки, выводимые в строку состояния, расположены в таблице строк программы. Для упрощения установки соответствия между идентификаторами пунктов меню и идентификаторами текстовых строк они заданы одинаковыми. Например, идентификатор команды меню File Open задан равным IDM_FILE_OPEN; в то же время эта величина является идентификатором строки "Open an existing document".
Для того чтобы обеспечить отображение в строке состояния вспомогательной информации для всплывающих меню, программа GADGETS устанавливает соответствие описателей меню идентификаторам строк. В программе GADGETS имеется десять всплывающих меню, являющихся дочерними трех родительских меню: главного меню, всплывающего меню Toolbar и всплывающего меню Statusbar. Описания ресурсов-строк строки состояния для этих всплывающих меню в этих родительских меню начинаются со строк IDS_MAIN_MENU, IDS_TOOLBAR_MENU и IDS_STATUSBAR_MENU. Программа GADGETS устанавливает соответствие между описателями родительских меню и этими тремя значениями, передавая их в функцию MenuHelp для отображения необходимой строки вспомогательного текста.
Наборы страниц свойств
Наборы страниц свойств иногда также называют диалогами с закладками (tabbed dialogs). Они дают возможность объединить несколько диалоговых окон в одно, составное диалоговое окно. В наборе страниц свойств каждый отдельный диалог называется страницей свойств (property page). На рис. 12.9 показан набор страниц свойств дисплея Display Properties, доступный с рабочего стола (desktop) Windows 95. (Для доступа к этому набору страниц свойств активизируйте контекстное меню оболочки системы, щелкнув правой кнопкой мыши и выбрав пункт меню Properies — свойства.) Различные страницы в этом наборе страниц свойств позволяют пользователю удобно задать такие настройки дисплея, как обои (wallpaper), хранитель экрана (screen saver), цвета (colors), шрифты (fonts), а также изменить установки дисплейного драйвера, связанные с числом доступных цветов (available colors), разрешением устройства (device resolution), и даже сменить текущий драйвер дисплея.
Рис. 12.9 Набор страниц свойств дисплея (Display Properties)
466
Набор страниц свойств позволяет модифицировать все установки сложного объекта, такого как, например, экран дисплея, путем объединения нескольких страниц свойств в единый элемент управления. Каждая страница имеет свою закладку (tab), щелчком на которой пользователь ее активизирует. Необязательная кнопка Apply позволяет пользователю посмотреть на изменения, им внесенные, без выхода из окна набора страниц свойств. Если результаты окажутся неудовлетворительными, то может быть сделан другой выбор, например, возврат к предыдущим установкам, которые доступны в наборе страниц свойств.
Другим типом составного диалогового окна, относящимся к набору страниц свойств, является мастер (wizard ). Мастер — это набор диалогов, которые получают информацию от пользователя в определенном порядке, для выполнения какой-либо специфичной задачи. На рис. 12.10 показана первая из шести страниц мастера установки принтера в Windows 95 (Add Printer Wizard), который позволяет пользователю последовательно ввести всю детальную информацию для подключения нового системного принтера. Программный интерфейс для мастеров такой же как и для наборов страниц свойств, хотя и имеются небольшие отличия в интерфейсе пользователя: кнопки OK и Cancel заменены кнопками Back и Next. Эти кнопки предназначены для переходов между страницами мастера (вместо закладок в наборе страниц свойств). На последней странице мастера отображается кнопка Finish, которая при нажатии, разрешает выполнение той задачи, для решения которой и был активизирован мастер.
Рис. 12.10 Страница мастера установки принтера (Add Printer Wizard)
Создание набора страниц свойств
Для создания набора страниц свойств необходимы те же элементы, которые могли бы потребоваться для создания независимых диалоговых окон — шаблоны диалога и процедуры диалога. Они заносятся в некоторые структуры данных, а затем вызывается функция PropertySheet. Каждая страница свойств требует наличия своего собственного шаблона диалогового окна, описывающего расположение конкретных элементов управления. Каждая страница свойств требует также своей собственной диалоговой процедуры, обрабатывающей сообщение инициализации диалогового окна WM_INITDIALOG и уведомляющие сообщения от элементов управления WM_COMMAND. Диалоговая процедура страницы свойств обрабатывает также третье сообщение — WM_NOTIFY, которое используется для уведомлений о изменениях в состоянии самого набора страниц свойств.
Эти элементы элементизируются с использованием двух структур данных. Одна — для каждой страницы свойств, а вторая — заголовок, описывающий атрибуты набора страниц свойств целиком. Атрибуты каждой страницы свойств задаются в структуре типа PROPSHEETPAGE, а эти структуры объединяются в массив. Указатель на массив структур типа PROPSHEETPAGE включается в структуру данных типа PROPSHEETHEADER, содержащий атрибуты набора страниц свойств в целом.
Шаблоны диалога страниц свойств
Шаблоны диалога, используемые для страниц свойств, почти полностью идентичны тем шаблонам диалога, которые используются для обычных диалоговых окон. Шаблон диалога страницы свойств содержит обычные элементы управления, такие как окна редактирования (edits), списки (lists), кнопки (push buttons); он может также содержать элементы управления общего пользования, такие как, анимационное изображение (animation), списки типа Drag and Drop (drag lists), окна с движком для выбора значения из диапазона (trackbars) и полосы прокрутки, связанные с окном редактирования (up-down controls). Так же как и в случае обычного шаблона диалога, каждый элемент управления в шаблоне страницы свойств имеет уникальный идентификатор, указывая который при вызове функции GetDlgItem можно получить описатель окна.
467
Единственное отличие между обычным шаблоном диалога и шаблоном страницы свойств состоит в том, что последний обычно не содержит кнопок OK и Cancel. Набор страниц свойств создает и поддерживает разделяемый между всеми страницами свойств набор кнопок. Обычно, по умолчанию, набор страниц свойств имеет кнопки OK, Cancel и Apply, хотя возможно указание флага, удаляющего кнопку Apply, если в ней нет надобности. Возможно также задание флага, указывающего на необходимость вывода в наборе страниц свойств кнопки Help, которая будет доступна тем страницам свойств, которые поддерживают помощь. Мастера используют несколько отличающийся набор кнопок: Back и Next для пролистывания страниц мастера, и кнопку Finish на последней странице.
Для заданного набора страниц свойств вам следует так сформировать шаблоны страниц, чтобы они имели примерно одинаковые размеры и форму, поскольку набор страниц свойств приводит свои размеры в соответствие с самой широкой и высокой страницей свойств. Удачное расположение элементов управления в шаблонах диалоговых окон
— задача, утомительная, требующая больших временных затрат. В контексте набора страниц свойств у вас еще прибавляется работы: необходимо скоординировать расположение различных шаблонов диалога.
Структура PROPSHEETPAGE
Как только будут созданы шаблоны диалоговых окон для каждой страницы свойств, и будет создан, как минимум, скелет процедуры диалогового окна, следующий шаг при создании набора страниц свойств состоит в заполнении структуры PROPSHEETPAGE для каждой страницы свойств. Структура PROPSHEETPAGE определена в файле PRSHT.H следующим образом:
typedef struct _PROPSHEETPAGE |
|
|
|
{ |
|
|
|
DWORD |
dwSize; |
// = sizeof(PROPSHEETPAGE) |
|
DWORD |
dwFlags; |
|
|
HINSTANCE |
hInstance; |
|
|
union |
|
|
|
{ |
|
|
// по умолчанию |
LPCSTR |
pszTemplate; |
||
LPCDLGTEMPLATE |
pResource; |
// PSP_DLGINDIRECT |
|
} DUMMYUNIONNAME; |
|
|
|
union |
|
|
|
{ |
|
|
|
HICON |
hIcon; // PSP_USEHICON |
||
LPCSTR |
pszIcon; |
|
// PSP_USEICONID |
} DUMMYUNIONNAME2; |
|
|
|
LPCSTR |
pszTitle; |
|
// PSP_USETITLE |
DLGPROC |
pfnDlgProc; |
|
|
LPARAM |
lParam; |
|
|
LPFNPSPCALLBACKA |
pfnCallback; |
// PSP_USECALLBACK |
|
UINT FAR |
*pcRefParent;// PSP_USEREFPARENT |
} PROPSHEETPAGE, FAR *LPPROPSHEETPAGE;
Комментарии в этом листинге описывают кратко каждый член структуры. Наличие флага с префиксом PSP_ означает, что этот флаг должен быть включен в поле dwFlags для активизации указанного элемента структуры данных. Ниже описаны детали о назначении конкретных полей структуры PROPSHEETPAGE:
•dwSize — текущая версия страницы свойств; должно быть равно sizeof (PROPSHEETPAGE).
•dwFlags — содержит один или несколько PSP-флагов, объединенных поразрядной оператором OR языка C. Большинство флагов влияют на то, будет или нет использоваться то или иное поле структуры PROPSHEETPAGE. Два дополнительных флага, неиспользуемых с этой целью, PSP_HASHELP и PSP_RTLREADING. Флаг PSP_HASHELP делает доступной кнопку Help, когда активна данная страница (флаг PSP_HASHELP должен быть указан в структуре PROPSHEETHEADER для того, чтобы кнопка Help присутствовала). Флаг PSP_RTLREADING заставляет страницу свойств использовать запись справа налево (для еврейского и арабского языков).
•hInstance — идентифицирует выполняемый файл, из которого загружены ресурсы диалоговых шаблонов
(pszTemplate) и значков (pszIcon).
•Шаблон диалогового окна идентифицируется pszTemplate (по умолчанию) для шаблонов, загруженных из ресурсов, или pResource (необходимо задание флага PSP_DLGINDIRECT в поле dwFlags) для шаблонов, загруженных из памяти.
•На закладке страницы свойств дополнительно может быть отображен значок. Значок может быть идентифицирован описателем значка hIcon (при установленном флаге PSP_USEHICON в поле dwFlags) или идентификатором ресурса-значка pszIcon (при установленном флаге PSP_USEICONID в поле dwFlags).
468
•По умолчанию заголовок закладки страницы свойств — заголовок шаблона диалога, кроме тех случаев, когда в поле dwFlags установлен флаг PSP_USETITLE, что приводит к использованию заголовка pszTitle.
•pfnDlgProc — определяет диалоговую процедуру для страницы свойств.
•lParam — задает начальное значение, передаваемое в функцию обратного вызова страницы свойств, заданную параметром pfnCallback.
•pfnCallback — функция обратного вызова (при установленном в поле dwFalgs флаге PSP_USECALLBACK), вызываемая перед тем, как страница свойств создается, и после того, как уничтожается.
•pcRefParent идентифицирует счетчик ссылок для набора страниц свойств. Это указатель на величину типа UINT, которая увеличивается на единицу при создании страницы свойств, и уменьшается на единицу при удалении страницы свойств. В любой момент времени величина этого счетчика позволяет вам определить, сколько страниц свойств в данный момент присутствует.
Ниже показано, как в примере программы PROPERTY в этой главе заполняется массив структур типа
PROPSHEETPAGE:
PROPSHEETPAGE pspage[2];
// Обнуляем данные
ZeroMemory(&pspage, 2 * sizeof(PROPSHEETPAGE));
// инициализируем данные первой страницы
pspage[0].dwSize |
= |
sizeof(PROPSHEETPAGE); |
pspage[0].dwFlags |
= |
PSP_USECALLBACK | PSP_USEICONID; |
pspage[0].hInstance |
= |
hInst; |
pspage[0].pszTemplate |
= |
MAKEINTRESOURCE(IDD_STYLES); |
pspage[0].pszIcon |
= |
MAKEINTRESOURCE(IDI_PAGE1); |
pspage[0].pfnDlgProc |
= StyleDlgProc; |
|
pspage[0].lParam |
=(LPARAM)&dwChildStyle; |
|
pspage[0].pfnCallback = StylePageProc; |
||
// инициализируем данные второй страницы |
||
pspage[1].dwSize |
= sizeof(PROPSHEETPAGE); |
|
pspage[1].dwFlags |
= PSP_USECALLBACK | PSP_USEICONID | PSP_HASHELP; |
|
pspage[1].hInstance |
= hInst; |
|
pspage[1].pszTemplate |
= MAKEINTRESOURCE(IDD_EXSTYLES); |
|
pspage[1].pszIcon |
= MAKEINTRESOURCE(IDI_PAGE2); |
|
pspage[1].pfnDlgProc |
= ExStyleDlgProc; |
|
pspage[1].lParam |
=(LPARAM)&dwChildExStyle; |
|
pspage[1].pfnCallback |
= ExStylePageProc; |
Член структуры PROPSHEETPAGE pfnDlgProc содержит указатель на процедуру диалогового окна. В добавок к сообщениям WM_INITDIALOG и WM_COMMAND, которые обрабатываются в большинстве процедур диалоговых окон, диалоговые процедуры страниц свойств должны обрабатывать третье сообщение — WM_NOTIFY. Ниже приведен примерный шаблон диалоговой процедуры для страницы свойств:
BOOL CALLBACK EmptyPageDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_INITDIALOG:
[инициализация диалогового окна] break;
case WM_COMMAND:
[уведомления от обычных диалоговых элементов управления] break;
case WM_NOTIFY:
{
LPNMHDR pnmh =(LPNMHDR)lParam;
[уведомления от набора страниц свойств]
}
}
}
Член pfnCallback структуры PROPSHEETPAGE ссылается на функцию обратного вызова, которая вызывается перед тем, как конкретная страница свойств создается, и сразу после того, как она уничтожается. Смысл использования этой функции состоит в том, чтобы иметь возможность прочитать данные члена lParam структуры
469
PROPSHEETPAGE, который содержит начальное значение, посланное создателем страницы свойств странице свойств (например, указатель на изменяемые данные). Ниже приведен шаблон функции обратного вызова страницы свойств:
static LPARAM InputData;
UINT CALLBACK EmptyPageProc(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
{
switch(uMsg)
{
case PSPCB_CREATE:
InputData = ppsp->lParam; return TRUE;
case PSPCB_RELEASE: return 0;
}
}
В текущей реализации параметр описателя окна hwnd всегда равен NULL. Параметр uMsg равен PSPCB_CREATE для вызова перед созданием страницы свойств и равен PSPCB_RELEASE после того, как она будет уничтожена. Хотя уведомление при создании посылается только, если страница свойств действительно создается, уведомление при уничтожении всегда посылается каждой странице свойств, вне зависимости от того, была она создана или нет.
После заполнения массива структур типа PROPSHEETPAGE следующим шагом в создании набора страниц свойств является занесение указателя на этот массив в поле ppsp структуры заголовка набора страниц свойств
PROPSHEETHEADER.
Структура PROPSHEETHEADER
Структура PROPSHEETHEADER определена в файле PRSHT.H следующим образом:
typedef struct _PROPSHEETHEADER |
|
|
|
|
{ |
|
|
|
|
DWORD |
dwSize; |
// = sizeof(PROPSHEETHEADER) |
||
DWORD |
dwFlags; |
|
|
|
HWND |
hwndParent; |
|
|
|
HINSTANCE |
hInstance; |
|
|
|
union |
|
|
|
|
{ |
|
|
|
|
HICON |
hIcon; // PSH_USEHICON |
|
||
LPCSTR pszIcon; |
|
// PSH_USEICONID |
||
} DUMMYUNIONNAME; |
|
|
|
|
LPCSTR |
pszCaption; |
|
|
|
UINT |
nPages; |
|
|
|
union |
|
|
|
|
{ |
|
|
//(по умолчанию) |
|
UINT |
nStartPage; |
|||
LPCSTR pStartPage; |
// PSH_USEPSTARTPAGE |
|||
} DUMMYUNIONNAME2; |
|
|
|
|
union |
|
|
|
|
{ |
|
|
|
|
LPCPROPSHEETPAGE |
|
ppsp; |
// PSH_PROPSHEETPAGE |
|
HPROPSHEETPAGE FAR |
*phpage; |
|
||
} DUMMYUNIONNAME3; |
|
|
|
|
PFNPROPSHEETCALLBACK |
|
pfnCallback; |
// PSH_USECALLBACK |
} PROPSHEETHEADER, FAR *LPPROPSHEETHEADER;
Комментарии в этом листинге описывают кратко каждый член структуры. Наличие флага с префиксом PSH_ означает, что этот флаг должен быть включен в поле dwFlags для активизации указанного члена структуры данных. Ниже описаны детали о назначении конкретных полей структуры PROPSHEETHEADER:
•dwSize — текущая версия набора страниц свойств; должно быть равно sizeof (PROPSHEETHEADER).
•dwFlags — содержит один или несколько PSH-флагов, объединенных поразрядной оператором OR языка C. Некоторые флаги определяют, будет или нет использоваться то или иное поле структуры PROPSHEETHEADER, как показано в предыдущем листинге.
•hwndParent — идентифицирует родительское окно набора страниц свойств. Для модального набора страниц свойств родительское окно недоступно.