- •Содержание
- •Глава 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
300
Раньше при обсуждении битовых образов говорилось, что 0 необязательно означает черный цвет, а 1 необязательно означает белый. Как вы можете теперь видеть, это зависит от того, как Windows использует битовые образы.
В программе RESOURC1 мы определили класс окна так, чтобы фон рабочей области был COLOR_WINDOW. Вы можете изменить цвет окна с помощью программы Control Panel, чтобы увидеть, как меняются цвета значка и курсора.
Получение описателя значков
В файле описания ресурсов ссылка на файл значка выглядит примерно так:
myicon ICON iconfile.ico
где ICONFILE.ICO — имя файла значка. В этой инструкции значку присваивается имя "myicon". В программе на С для получения описателя значка используется функция LoadIcon. В функции LoadIcon имеется два параметра. Первым является описатель экземпляра вашей программы, который в WinMain обычно называется hInstance. Этот описатель требуется для Windows, чтобы определить, в каком файле с расширением .EXE содержится ресурс значка. Вторым параметром является имя значка из описания ресурсов, заданное в виде указателя на оканчивающуюся нулем строку. Возвращаемым значением функции LoadIcon является значение типа HICON, которое определяется в WINDOWS.H.
Имеется связь между именем значка в описании ресурсов и в инструкции, содержащей функцию LoadIcon вашей программы на С:
Описание ресурсов: |
myicon ICON iconfile.ico |
Исходный текст программы: |
hIcon = LoadIcon (hInstance, "myicon"); |
Не беспокойтесь о том, в верхнем или нижнем регистре задано имя значка. Компилятор преобразует в файле описания ресурсов имя значка в символы верхнего регистра и вставляет это имя в таблицу ресурсов в заголовке файла программы с расширением .EXE. При первом вызове функции LoadIcon, Windows преобразует строку, заданную вторым параметром в символы верхнего регистра и отыскивает в таблице ресурсов файла с расширением
.EXE совпадающее с этой строкой имя.
Вместо имени вы также можете использовать число (16-разрядное беззнаковое WORD). Это число называется идентификатором (ID) значка. Ниже показано как это делается:
Описание ресурсов: |
125 ICON iconfile.ico |
Исходный текст программы: |
hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (125)); |
MAKEINTRESOURCE (make an integer into a resourse string — преобразовать целое в строку ресурса) является макросом, определенным в заголовочных файлах Windows, который преобразует число в указатель, но со старшими 16 разрядами, установленными в нуль. Так Windows узнает, что второй параметр функции LoadIcon является числом, а не указателем на символьную строку.
В примерах программ, представленных ранее в этой книге, использовались предопределенные значки:
LoadIcon(NULL, IDI_APPLICATION);
Поскольку параметр hInstance установлен в NULL, Windows узнает, что этот значок является предопределенным. IDI_APPLICATION также определяется в заголовочных файлах Windows с использованием макроса
MAKEINTRESOURCE:
#define IDI_APPLICATION MAKEINTRESOURCE(32512)
Предопределенные значки и курсоры являются частью файла драйвера дисплея.
На имя значка можно ссылаться и с помощью третьего метода, который является комбинацией метода, использующего текстовую строку, и метода, использующего число:
Описание ресурсов: |
125 ICON iconfile.ico |
Исходный текст программы: |
hIcon = LoadIcon (hInstance, "#125"); |
По символу # операционная система Windows определяет, что далее следует число в ASCII-коде.
Как насчет четвертого способа? В этом способе используется макроопределение в заголовочном файле, который включается (с помощью директивы #include) и в файл описания ресурсов, и в вашу программу:
Заголовочный файл: |
#define myicon 125 |
Описание ресурсов: |
myicon ICON iconfile.ico |
301
Исходный текст программы: hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (myicon));
При использовании этого способа будьте внимательны! Хотя регистр символов при использовании строки в качестве имени значка не имеет значения, он приводит к различию идентификаторов, генерируемых с помощью инструкций #define.
Использование идентификаторов вместо имен значков уменьшает размер файла с расширением .EXE и, вероятно, немного ускоряет работу функции LoadIcon. Больше того, если в вашей программе используется множество значков, то вы обнаружите, что проще хранить их идентификаторы в массиве.
Использование значков в вашей программе
Хотя для обозначения программ Windows использует значки несколькими способами, во множестве программ для Windows значок задается только при определении класса окна:
wndclass.hIcon = LoadIcon(hInstance, "MyIcon");
.
.
.
wndclass.hIconSm = LoadIcon(hInstance, "MySmIcon");
Вы можете в обеих инструкциях сослаться на один и тот же значок стандартного размера, и Windows при выводе маленького значка на экран просто приведет его к необходимому размеру. Если в дальнейшем вы захотите изменить значок программы, это можно сделать с помощью функции SetClassLong. Предположим, что у вас в описании ресурсов был второй значок:
anothericon ICON iconfil2.ico
С помощью следующей инструкции вы можете заменить этот значок значком "myicon":
SetClassLong( hwnd, GCL_HICON, LoadIcon(hInstance, "anothericon") );
Маленький значок можно заменить с помощью GCL_HICONSM. Если вы сохранили описатель значка, возвращенный функцией LoadIcon, то вы также можете и нарисовать значок в рабочей области вашего окна:
DrawIcon(hdc, x, y, hIcon);
Сама Windows использует функцию DrawIcon при выводе значка вашей программы в соответствующее место. Windows получает описатель значка из структуры класса окна. Вы можете получить описатель тем же способом:
DrawIcon(hdc, x, y, GetClassLong(hwnd, GCL_HICON));
В примере программы RESOURC1 в классе окна используется тот же значок, который выводится в рабочей области окна программы. В файле описания ресурсов значку дается такое же имя, как и программе:
resourc1 ICON resourc1.ico
Поскольку символьная строка "Resourc1" хранится в массиве szAppName и уже используется программой в качестве имени класса окна, функция LoadIcon вызывается просто:
LoadIcon(hInstance, szAppName);
Можно заметить, что функция LoadIcon для одного и того же значка вызывается трижды, дважды при определении класса окна в WinMain и еще раз при получении описателя значка во время обработки сообщения WM_CREATE в WndProc. Троекратный вызов функции LoadIcon не создает проблем, поскольку возвращаемым значением функции является один и тот же описатель. Фактически, Windows только однажды загружает значок из файла с расширением .EXE.
Использование альтернативных курсоров
Инструкции для задания курсора в файле описания ресурсов и для получения описателя курсора в вашей программе очень похожи на показанные ранее инструкции для значков:
Описание ресурсов: mycursor CURSOR cursfile.cur
Исходный текст программы: hCursor = LoadCursor (hInstance, "mycursor");
Другие способы, показанные для значков (использование идентификаторов и MAKEINTRESOURCE), также работают и для курсоров. В заголовочные файлы Windows включается определение typedef HCURSOR, которое вы можете использовать для хранения описателя курсора.
Вы можете использовать описатель курсора, полученный при вызове функции LoadCursor, при задании поля hCursor структуры класса окна:
302
wndclass.hCursor = LoadCursor(hInstance, "mycursor");
Это заставляет курсор мыши, если он оказывается в рабочей области вашего окна, превращаться в ваш пользовательский курсор.
Если вы используете дочерние окна, можно сделать так, чтобы курсор выглядел по-разному в разных окнах. Если в вашей программе определяются классы этих дочерних окон, то для каждого класса вы можете использовать свой курсор путем соответствующей установки поля hCursor в каждом классе окна. А если вы используете предопределенные дочерние элементы управления, то изменить поле hCursor класса окна можно с помощью функции:
SetClassLong(hwndChild, GCL_HCURSOR, LoadCursor(hInstance, "childcursor"));
Если вы разделяете рабочую область окна вашей программы на маленькие логические области без использования дочерних окон, то для изменения курсора мыши вы можете использовать функцию SetCursor:
SetCursor(hCursor);
Функцию SetCursor следует вызывать при обработке сообщения WM_MOUSEMOVE. В противном случае для перерисовки курсора при его движении Windows использует курсор, ранее заданный в классе окна.
В программе RESOURC1 для задания имени курсора используется имя программы:
resourc1 CURSOR resourc1.cur
Когда в исходном тексте программы RESOURC1.С задается класс окна, переменная szAppName используется следующим образом в функции LoadCursor:
wndclass.hCursor = LoadCursor(hInstance, szAppName);
Битовые образы: картинки в пикселях
Мы уже говорили об использовании битовых образов в значках и курсорах. В Windows также включен тип ресурсов с именем BITMAP.
Битовые образы используются в двух главных целях. Первая — рисование на экране картинок. Например, файлы драйверов дисплеев в Windows содержат массу крошечных битовых образов, которые используются для рисования стрелок в полосах прокрутки, галочек в раскрывающихся меню, изображений на кнопках изменения размеров окна, флажках и переключателях. Вы можете использовать битовые образы в меню (как показано в главе 10) и панелях инструментов приложений (как показано в главе 12). В таких программах, как Paint, битовые образы используются для изображения графического меню.
Вторая цель использования битовых образов — создание кистей. Кисти, как вы уже знаете, являются шаблонами пикселей, которые Windows использует для закрашивания изображаемых на экране областей.
Использование битовых образов и кистей
Программа RESOURC2, приведенная на рис. 9.2, является модернизированной версией программы RESOURC1, включающей в себя ресурс монохромного битового образа, используемый для создания кисти фона рабочей области. С помощью редактора изображений был создан битовый образ размерами 8 на 8 пикселей, что является минимальным размером для кисти.
RESOURC2.MAK
#------------------------
# RESOURC2.MAK make file
#------------------------
resourc2.exe : resourc2.obj resourc2.res $(LINKER) $(GUIFLAGS) -OUT:resourc2.exe \
resourc2.obj resourc2.res $(GUILIBS) resourc2.obj : resourc2.c
$(CC) $(CFLAGS) resourc2.c
resourc2.res : resourc2.rc resourc2.ico resourc2.cur resourc2.bmp
$(RC) $(RCVARS) resourc2.rc
RESOURC2.C
/*-----------------------------------------------------------
RESOURC2.C -- Icon and Cursor Demonstration Program No. 2
(c) Charles Petzold, 1996
303
-----------------------------------------------------------*/
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
char |
szAppName[] = "Resourc2"; |
HINSTANCE |
hInst; |
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{ |
|
HBITMAP |
hBitmap; |
HBRUSH |
hBrush; |
HWND |
hwnd; |
MSG |
msg; |
WNDCLASSEX |
wndclass; |
hBitmap = LoadBitmap(hInstance, szAppName); hBrush = CreatePatternBrush(hBitmap);
wndclass.cbSize |
= sizeof(wndclass); |
wndclass.style |
= CS_HREDRAW | CS_VREDRAW; |
wndclass.lpfnWndProc |
= WndProc; |
wndclass.cbClsExtra |
= 0; |
wndclass.cbWndExtra |
= 0; |
wndclass.hInstance |
= hInstance; |
wndclass.hIcon |
= LoadIcon(hInstance, szAppName); |
wndclass.hCursor |
= LoadCursor(hInstance, szAppName); |
wndclass.hbrBackground |
= hBrush; |
wndclass.lpszMenuName |
= NULL; |
wndclass.lpszClassName |
= szAppName; |
wndclass.hIconSm |
= LoadIcon(hInstance, szAppName); |
RegisterClassEx(&wndclass);
hInst = hInstance;
hwnd = CreateWindow(szAppName, "Icon and Cursor Demo", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DeleteObject((HGDIOBJ) |
hBrush); |
// clean-up |
DeleteObject((HGDIOBJ) |
hBitmap); |
|
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static HICON hIcon;
static int cxIcon, cyIcon, cxClient, cyClient; HDC hdc;
304
PAINTSTRUCT |
ps; |
int |
x, y; |
switch(iMsg)
{
case WM_CREATE :
hIcon = LoadIcon(hInst, szAppName); cxIcon = GetSystemMetrics(SM_CXICON); cyIcon = GetSystemMetrics(SM_CYICON); return 0;
case WM_SIZE :
cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); return 0;
case WM_PAINT :
hdc = BeginPaint(hwnd, &ps);
for(y = cyIcon; y < cyClient; y += 2 * cyIcon) for(x = cxIcon; x < cxClient; x += 2 * cxIcon)
DrawIcon(hdc, x, y, hIcon);
EndPaint(hwnd, &ps); return 0;
case WM_DESTROY : PostQuitMessage(0); return 0;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
RESOURC2.RC
/*-----------------------------
RESOURC2.RC resource script
----------------------------- |
|
|
*/ |
|
|
|
|
resourc2 |
ICON |
resourc2.ico |
|
|
|||
resourc2 |
CURSOR |
resourc2.cur |
|
|
|||
resourc2 |
BITMAP |
resourc2.bmp |
|
|
|||
RESOURC2.ICO |
RESOURC2.CUR |
RESOURC2.BMP |
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Рис. 9.2 Программа RESOURC2, содержащая значок, курсор и битовый образ
Битовый образ включается в файл описания ресурсов в том же формате, что значок или курсор:
resourc2 BITMAP resourc2.bmp
Используемая в WinMain функция LoadBitmap аналогична функциям LoadIcon и LoadCursor. Ее возвращаемым значением является описатель битового образа:
hBitmap = LoadBitmap(hInstance, szAppName);
Этот описатель затем используется для создания шаблонной кисти (pattern brush). Основой кисти является битовый образ:
hBrush = CreatePatternBrush(hBitmap);
Когда Windows закрашивает этой кистью область экрана, битовый образ повторяется по горизонтали и вертикали через каждые восемь пикселей. Эта кисть нам нужна для придания фону рабочей области того цвета, который мы подобрали при определении класса окна: