- •Содержание
- •Глава 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
359
рабочей области родительского окна и на расстоянии 2,5 символов от ее верхнего края. Ширина окна диалога равна 40 символам, а высота – 10 символам.
Такая система координат дает возможность использовать в окне диалога такие координаты и размеры, которые сохранят его общий вид и расположение, независимо от разрешающей способности дисплея. Поскольку высота символов системного шрифта обычно примерно вдвое больше его ширины, то размеры деления по осям х и у примерно одинаковы.
Функция GetDialogBaseUnits позволяет определять размеры системного шрифта, которые используются менеджером окна диалога. Для стандартного монитора VGA (самого часто используемого видеоадаптера в Windows) функция GetDialogBaseUnits возвращает ширину символа равную 8 и высоту равную 16 единицам. Поскольку единицы окна диалога соответствуют 1/4 средней ширины символа и 1/8 его высоты, то каждая единица соответствует 2 пикселям монитора VGA. Если идея использования таких единиц измерения окна диалога временами кажется слишком абстрактной, то лучше просто запомнить это правило.
Инструкция STYLE шаблона напоминает поле стиля функции CreateWindow. Использование WS_POPUP и WS_DLGFRAME вполне обычно для модальных окон диалога, хотя в дальнейшем мы изучим несколько альтернативных идентификаторов.
Внутри фигурных скобок определяются те дочерние окна элементов управления, которые появятся в окне диалога. В нашем окне диалога используются дочерние окна элементов управления трех типов: CTEXT (текст, выровненный по центру), ICON (значок) и DEFPUSHBUTTON (кнопка, выбираемая по умолчанию). Формат инструкций описания следующий:
control-type "text" id, xPos, yPos, xWidth, yHeight [, iStyle]
Значение iStyle в конце инструкции не является обязательным; оно задает дополнительные стили окна, используя идентификаторы, заданные в заголовочных файлах Windows.
Идентификаторы CTEXT, ICON и DEFPUSHBUTTON используются исключительно в окнах диалога. Они являются сокращенной формой записи идентификаторов класса окна и стиля окна. Например, CTEXT показывает, что класс дочернего окна элементов управления — это "static", а стиль такой:
WS_CHILD | SS_CENTER | WS_VISIBLE | WS_GROUP
Если с идентификатором WS_GROUP мы сталкиваемся впервые, то стили окна WS_CHILD, SS_CENTER и WS_VISIBLE уже встречались нам в главе 8 при создании статических дочерних окон элементов управления в программе COLORS1.
Что касается значка, то текстовое поле — это имя ресурса значка в программе, который также определен в файле описания ресурсов программы ABOUT1. Текстовое поле кнопки — это тот текст, который появится внутри кнопки на экране. Этот текст аналогичен тексту, заданному во втором параметре функции CreateWindow, которая вызывается при создании в программе дочернего окна элемента управления.
Поле id представляет собой число, с помощью которого дочернее окно идентифицирует себя при посылке сообщений (обычно эти сообщения WM_COMMAND) своему родительскому окну. Родительским окном этих дочерних окон элементов управления является само окно диалога, которое посылает эти сообщения оконной процедуре, находящейся внутри Windows. Эта оконная процедура посылает эти сообщения процедуре диалогового окна, которая включается в вашу программу. Значения id аналогичны идентификаторам дочерних окон, которые использовались в функции CreateWindow при создании в главе 8 дочерних окон. Поскольку дочерние окна с текстом и значком не посылают сообщений обратно родительскому окну, эти значения для них устанавливаются равными —1. Значение id для кнопки устанавливается равным IDOK, который в заголовочных файлах Windows определяется как 1.
Следующие четыре числа задают положение дочернего окна элемента управления (относительно верхнего левого угла рабочей области окна диалога) и его размер. Положение и размер выражены в единицах, равных 1/4 средней ширины и 1/8 высоты символа системного шрифта. В инструкции ICON высота и ширина игнорируются.
Инструкция DEFPUSHBUTTON шаблона окна диалога в дополнение к стилю окна, заданному ключевым словом
DEFPUSHBUTTON, включает в себя стиль окна WS_GROUP. О стиле WS_GROUP (и стиле WS_TABSTOP) будет рассказано несколько позже, при обсуждении второй версии рассмотренной ранее программы — ABOUT2.
Диалоговая процедура
Диалоговая процедура или процедура диалога программы обрабатывает сообщения, получаемые окном диалога. Хотя она очень сильно напоминает оконную процедуру, это не настоящая оконная процедура. Оконная процедура окна диалога находится в Windows. Эта оконная процедура вызывает вашу диалоговую процедуру, передавая ей многие из сообщений, которые получает сама. Здесь представлена процедура диалога программы ABOUT1:
360
BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch(iMsg)
{
case WM_INITDIALOG : return TRUE;
case WM_COMMAND : switch(LOWORD(wParam))
{
case IDOK : case IDCANCEL :
EndDialog(hDlg, 0); return TRUE;
}
break;
}
return FALSE;
}
Параметры этой функции те же, что и параметры обычной оконной процедуры; как и оконная процедура, процедура диалога должна быть определена как функция типа CALLBACK. Хотя в качестве описателя окна диалога использовался описатель hDlg, вместо него можно при желании использовать hwnd. Обратите внимание на отличия между этой функцией и оконной процедурой:
•Оконная процедура возвращает значение типа LRESULT; а процедура диалогового окна — значение типа BOOL (определяемое в заголовочных файлах Windows как int).
•Если оконная процедура не обрабатывает какое-то сообщение, она вызывает DefWindowProc; процедура диалога, если она не обрабатывает сообщение, возвращает FALSE (0), а если обрабатывает, то TRUE (ненулевое значение).
•Процедура диалога не обрабатывает сообщения WM_PAINT и WM_DESTROY. Процедура диалога не получит сообщения WM_CREATE; вместо этого она выполняет инициализацию при обработке специального сообщения WM_INITDIALOG.
Сообщение WM_INITDIALOG является первым сообщением, которое получает процедура диалога. Это сообщение посылается только процедурам диалога. Если процедура диалога возвращает TRUE, то Windows помещает фокус ввода на первое дочернее окно элемента управления, которое имеет стиль WS_TABSTOP (о котором будет рассказано при изучении программы ABOUT2). В нашем окне диалога первым дочерним окном элемента управления, которое имеет стиль WS_TABSTOP, является кнопка. С другой стороны, при обработке сообщения WM_INITDIALOG процедура диалога может использовать функцию SetFocus для того, чтобы установить фокус на одно из дочерних окон управления окна диалога, и тогда она должна вернуть значение
FALSE.
Единственным оставшимся сообщением, которое обрабатывает процедура окна диалога, является WM_COMMAND. Это то сообщение, которое элемент управления кнопка посылает своему родительскому окну тогда, когда либо на ней производится щелчок мышью, либо нажата клавиша <Spacebar> (пробел) и кнопка имеет фокус ввода. Идентификатор дочернего окна элемента управления (который в шаблоне окна диалога равен IDOK) находится в младшем слове параметра wParam. Для этого сообщения процедура диалога вызывает функцию EndDialog, которая сообщает Windows о необходимости закрытия окна диалога. Для всех остальных сообщений процедура диалога возвращает FALSE, сообщая оконной процедуре окна диалога внутри Windows, что процедура диалога программы не обрабатывает сообщение.
Сообщения для модального окна диалога не проходят через очередь сообщений программы, поэтому не беспокойтесь о влиянии быстрых клавиш на работу окна диалога.
Вызов окна диалога
При обработке в WndProc сообщения WM_CREATE, программа ABOUT1 получает описатель экземпляра программы и сохраняет его в статической переменной:
hInstance =((LPCREATESTRUCT) lParam) -> hInstance;
Программа ABOUT1 обрабатывает те сообщения WM_COMMAND, в которых младшее слово параметра wParam равно IDM_ABOUT. Когда программа его получает, она вызывает функцию DialogBox:
DialogBox(hInstance, "AboutBox", hwnd, AboutDlgProc);
Для этой функции требуется описатель экземпляра (сохраненный при обработке сообщения WM_CREATE), имя окна диалога (как оно определено в файле описания ресурсов), описатель родительского окна окна диалога
361
(которым является главное окно программы) и адрес процедуры диалога. Если вместо имени шаблона окна диалога используется число, то с помощью макрокоманды MAKEINTRESOURCE его можно преобразовать в строку.
Выбор из меню пункта "About About1..." приводит к выводу на экран окна диалога, показанного на рис. 11.2. Закрыть это окно диалога можно, щелкнув на кнопке OK мышью, нажав клавишу <Spacebar> или <Enter>. При нажатии клавиш <Spacebar> или <Enter> в любом окне диалога, в котором имеется кнопка по умолчанию, Windows посылает диалоговой процедуре сообщение WM_COMMAND, в котором младшее слово параметра wParam равно идентификатору заданной по умолчанию кнопки.
Функция DialogBox, которая вызывается для вывода на экран окна диалога, не возвращает управление в WndProc до тех пор, пока окно диалога не будет закрыто. Возвращаемым значением функции DialogBox является второй параметр функции EndDialog, которая вызывается в процедуре диалога. (Это значение не используется в программе ABOUT1, но используется в программе ABOUT2.) Затем WndProc может передать управление
Windows.
Даже при выводе на экран окна диалога, WndProc может продолжать получать сообщения. Вы даже можете посылать в WndProc сообщения из процедуры диалога. Поскольку главным окном программы ABOUT1 является родительское окно всплывающего окна диалога, то вызов функции SendMessage в AboutDlgProc должен начинаться следующим образом:
SendMessage(GetParent(hDlg), ...);
Рис. 11.2 Окно диалога программы ABOUT1
Дополнительная информация о стиле окна диалога
Стиль окна диалога задается в строке STYLE шаблона окна диалога. Для программы ABOUT1 использовался стиль, который наиболее часто используется для модальных окон диалога:
STYLE WS_POPUP | WS_DLGFRAME
Однако вы можете также поэкспериментировать с другими стилями. Например, можно попытаться использовать такой стиль:
STYLE WS_POPUP | WS_CAPTION
Такой стиль позволяет создать окно диалога со строкой заголовка и обычной для окна рамкой. Строка заголовка дает возможность пользователю с помощью мыши перемещать окно диалога по экрану. Если используется стиль WS_CAPTION, то координаты х и у, задаваемые в инструкции DIALOG, являются координатами рабочей области окна диалога относительно верхнего левого угла рабочей области родительского окна. Строка заголовка будет располагаться выше координаты у.
При наличии строки заголовка следом за инструкцией STYLE в шаблоне окна диалога можно задать текст заголовка с помощью инструкции CAPTION:
CAPTION "Dialog Box Caption"
Можно сделать то же самое с помощью функции SetWindowText при обработке сообщения WM_INITDIALOG в процедуре диалога:
SetWindowText(hDlg, "Dialog Box Caption");
362
Кроме этого, при условии использования стиля WS_CAPTION с помощью стиля WS_SYSMENU к окну диалога можно добавить системное меню:
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU
Такой стиль позволяет пользователю выбрать из системного меню опции Move или Close.
Добавление к стилю идентификатора WS_THICKFRAME дает возможность пользователю изменять размер окна диалога, хотя такое изменение размера для окон диалога является делом необычным. Аналогично обстоит дело и с идентификатором WS_MAXIMIZEBOX.
Инструкция STYLE не является необходимой. Если в шаблон не включать инструкцию STYLE или CAPTION, то по умолчанию задается следующий стиль:
WS_POPUP | WS_BORDER
Но окно такого стиля смотрится хуже. Идентификатор WS_DLGFRAME обеспечивает гораздо более привлекательные результаты. Если к инструкции STYLE добавить инструкцию CAPTION, то по умолчанию задается следующий стиль:
WS_POPUP | WS_CAPTION | WS_SYSMENU
Кроме этого, меню к окну диалога можно добавить с помощью следующей инструкции в шаблоне окна диалога:
MENU menu-name
Аргументом является либо имя, либо номер меню в файле описания ресурсов. Меню в модальных окнах диалога – вещь очень необычная. И если оно используется, то необходима уверенность в том, что все идентификаторы меню и дочерних окон элементов управления окна диалога являются уникальными.
Инструкция FONT позволяет использовать в тексте окна диалога какой-либо иной шрифт, отличный от системного.
Хотя оконная процедура окна диалога обычно находится внутри Windows, для обработки сообщений окна диалога можно использовать одну из собственных оконных процедур. Для этого в шаблоне окна диалога необходимо задать имя класса окна:
CLASS "class-name"
Это делается редко, но тем не менее именно такой подход применяется в представленной далее в этой главе программе HEXCALC.
Когда вызывается функция DialogBox с указанием имени шаблона окна диалога, Windows уже имеет почти все необходимое для создания всплывающего окна с помощью обычной функции CreateWindow. Windows получает координаты и размеры окна, стиль окна, заголовок и меню из шаблона окна диалога. Описатель экземпляра и описатель родительского окна Windows получает из параметров функции DialogBox. Единственной недостающей частью информации является класс окна (если он не задан в шаблоне окна диалога). Для окон диалога Windows регистрирует особый класс окна. Оконная процедура для такого класса окна имеет доступ к указателю на процедуру диалога приложения (который передается в функцию DialogBox), таким образом Windows может информировать программу о сообщениях, получаемых этим всплывающим окном. Конечно, вы можете сами создать и поддерживать собственное диалоговое окно путем создания всплывающего окна. Использование функции DialogBox значительно облегчает дело.
Дополнительная информация об определении дочерних окон элементов управления
В шаблоне окна управления файла ABOUT1.RC, для определения трех типов дочерних окон элементов управления, которые появляются в окне диалога, использовалась сокращенная запись: CTEXT, ICON и DEFPUSHBUTTON. Можно использовать и другие идентификаторы. Каждый тип соответствует конкретному предопределенному классу окна и стилю окна. В представленной ниже таблице показаны соответствующие каждому типу дочерних окон элементов управления класс окна и стиль окна:
Тип элемента управления |
Класс окна |
Стиль окна |
PUSHBUTTON |
button |
BS_PUSHBUTTON | WS_TABSTOP |
DEFPUSHBUTTON |
button |
BS_DEFPUSHBUTTON | WS_TABSTOP |
CHECKBOX |
button |
BS_CHECKBOX | WS_TABSTOP |
RADIOBUTTON |
button |
BS_RADIOBUTTON | WS_TABSTOP |
GROUPBOX |
button |
BS_GROUPBOX | WS_TABSTOP |
LTEXT |
static |
SS_LEFT | WS_GROUP |
CTEXT |
static |
SS_CENTER | WS_GROUP |
RTEXT |
static |
SS_RIGHT | WS_GROUP |
363
Тип элемента управления |
Класс окна |
Стиль окна |
ICON |
static |
SS_ICON |
EDITTEXT |
edit |
ES_LEFT | WS_BORDER | WS_TABSTOP |
SCROLLBAR |
scrollbar |
SBS_HORZ |
LISTBOX |
listbox |
LBS_NOTIFY | WS_BORDER | WS_VSCROLL |
COMBOBOX |
combobox |
CBS_SIMPLE | WS_TABSTOP |
Единственной программой, которая понимает эту краткую запись, является компилятор ресурсов (RC). Кроме показанных выше стилей окна, каждое из представленных дочерних окон элементов управления имеет стиль:
WS_CHILD | WS_VISIBLE
Для всех типов дочерних окон элементов управления, за исключением EDITTEXT, SCROLLBAR, LISTBOX и COMBOBOX, используется следующий формат инструкций, описывающих элементы управления:
control-type "text", id, xPos, yPos, xWidth, yHeight [, iStyle]
А для типов элементов управления EDITTEXT, SCROLLBAR, LISTBOX и COMBOBOX в формат инструкций определения не входит текстовое поле:
control-type id, xPos, yPos, xWidth, yHeight [, iStyle]
Вобеих этих инструкциях поле iStyle не является обязательным.
Вглаве 8 рассказывалось о правилах задания ширины и высоты предопределенных дочерних окон элементов управления. Полезно было бы вернуться к этой главе и к этим правилам, учитывая, что размеры, которые указываются в шаблонах окон диалога, всегда задаются в единицах 1/4 средней ширины символа и 1/8 его высоты.
Поле стиля (style) инструкций определения окон элементов управления не является обязательным. Оно дает возможность включить в инструкцию другие идентификаторы стиля окна. Например, если необходимо создать флажок с текстом, находящимся слева от квадратного окна флажка, то можно было бы воспользоваться такой инструкцией:
CHECKBOX "text", id, xPos, yPos, xWidth, yHeight, BS_LEFTTEXT
Хотя сокращенная запись для дочерних окон управления весьма удобна, но она не является исчерпывающей. Например, нельзя создать дочернее окно управления без рамки. По этой причине в компиляторе файла описания ресурсов также определяется и обобщенная форма инструкции окна управления, которая выглядит так:
CONTROL "text", id, "class", iStyle, xPos, yPos, xWidth, yHeight
Эта инструкция, где можно задать класс окна и полностью определить стиль окна, дает возможность создать любой тип дочернего окна управления. Например, вместо инструкции:
PUSHBUTTON "OK", IDOK, 10, 20, 32, 14
можно использовать инструкцию:
CONTROL "OK", IDOK, "button", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP, 10, 20, 32, 14
При компиляции файла описания ресурсов две этих инструкции кодируются одинаково, как в файле с расширением .RES, так и в файле с расширением .EXE.
Если инструкция CONTROL используется в шаблоне окна диалога, нет необходимости включать в нее стили WS_CHILD и WS_VISIBLE. Windows включает их в стиль окна при создании дочерних окон. Кроме этого формат инструкции CONTROL облегчает понимание того, что делает менеджер окна диалога Windows, когда он создает окно диалога. Во-первых, как уже ранее говорилось, он создает всплывающее окно, родительское окно которого определяется описателем окна, заданным в функции DialogBox. Затем для каждой инструкции элемента управления в шаблоне диалога, менеджер окна диалога создает дочернее окно. Родительским окном каждого из этих дочерних окон управления является всплывающее окно диалога. Приведенная выше инструкция CONTROL преобразуется в вызов функции CreateWindow, которая выглядит следующим образом:
CreateWindow("button", "OK",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP, 10 * cxChar / 4, 20 * cyChar / 8,
32 * cxChar / 4,14 * cyChar / 8, hDlg, IDOK, hInstance, NULL);
где cxChar и cyChar — это ширина и высота символа системного шрифта в пикселях. Параметр hDlg является возвращаемым значением функции CreateWindow, которая создает окно диалога. Параметр hInstance получен при первом вызове функции DialogBox.