Операционная система Microsoft Windows 3.1 для программиста© Александр Фролов, Григорий ФроловТом 12, М.: Диалог-МИФИ, 1993, 255 стр. 1.5. Графическое изображение типа bitmapВ ресурсы приложения вы можете включить произвольное графическое изображение в виде битового образа (в дальнейшем мы будем называть такое изображение изображением типа bitmap или просто изображением bitmap). С помощью графического редактора, входящего в состав Resource Workshop, или с помощью стандартного приложения Paint Brush вы можете нарисовать прямоугольное графическое изображение типа bitmap. При этом для представления цвета одного пикселя может использоваться разное количество бит. Изображение записывается в файл с расширением имени bmp. Мы уже сталкивались с изображениями bitmap, когда выводили в окно пиктограмму и курсор. Эти объекты являются частными случаями изображения bitmap. Изображения bitmap удобно использовать для оформления внешнего вида окон приложения. С помощью таких изображений вы можете, например, создать органы управления любой формы (например, круглые кнопки с картинками), нарисовать фотографию, введенную сканером, заставку или эмблему фирмы. Изображения bitmap открывают широкие возможности для разработки дизайна приложения Windows. К сожалению, рисование в окне изображения bitmap является достаточно сложной задачей, которой будет посвящена отдельная глава в одном из следующих томов "Библиотеки системного программиста". В программном интерфейсе Windows нет функции с именем DrawBitmap, с помощью которой вы могли бы нарисовать изображение bitmap, однако через некоторое время мы попытаемся восполнить этот пробел. В этом разделе мы расскажем вам о том, как создать и описать изображение bitmap в файле описания ресурсов, как загрузить bitmap в память и использовать его для закрашивания внутренней области окна (client area). Создание изображения типа bitmapДля создания изображения bitmap запустите Resource Workshop и из меню "File" выберите строку "New Project". В появившейся диалоговой панели включите переключатель ".BMP" и нажмите кнопку "OK". На экране появится диалоговая панель "New bitmap Attributes" (рис. 1.13).
Рис. 1.13. Диалоговая панель "New bitmap Attributes" В этой диалоговой панели вам надо выбрать ширину изображения в пикселях (поле "Width in pixels"), высоту изображения в пикселях (поле "Height in pixels"), количество цветов в изображении (2, 16 или 256). После выбора нажмите кнопку "OK". В главном окне Resource Workshop появятся окна для редактирования изображения (рис. 1.14).
Рис. 1.14. Создание изображения типа bitmap При создании изображения bitmap используются те же инструменты, что и при создании пиктограммы или курсора. Вы можете выбрать в окне "Colors" любой доступный цвет, однако нельзя сделать прозрачные участки пиктограммы или участки, инвертирующие цвет фона. Если размеры создаваемого изображения невелики, можно увеличить масштаб отображения при редактировании, выбрав из меню "View" строку "Zoom in". Для возврата к прежнему масштабу отображения выберите из этого же меню строку "Zoom out". Для сохранения созданного изображения в файле выберите из меню "File" строку "Save file as..." и укажите имя файла. Включение изображения bitmap в файл описания ресурсовДля включения изображения типа bitmap в файл описания ресурсов используется такой же способ, как и для включения пиктограмм. Файл описания ресурсов должен содержать оператор BITMAP: BitmapID BITMAP [параметры загрузки] [тип памяти] имя файла Параметры загрузки и тип памяти указывается так же, как и для описанной нами ранее таблицы строк STRINGTABLE, пиктограммы и курсора. В качестве имени файла необходимо указать имя файла, содержащего изображение bitmap, например: AppBitmap BITMAP mybrush.bmp Идентификатор изображения bitmap BitmapID можно указывать как символическое имя или как целое число - идентификатор ресурса. Загрузка изображения bitmapДля загрузки изображения bitmap вы должны использовать функцию LoadBitmap: HBITMAP WINAPI LoadBitmap(HINSTANCE hInst,LPCSTR lpszBitmap); Назначение параметров этой функции аналогично назначению параметров функций LoadIcon и LoadCursor. Параметр hInst указывает идентификатор текущей копии приложения, параметр lpszBitmap - идентификатор bitmap в файле описания ресурсов. Функция возвращает идентификатор изображения, который следует использовать для рисования bitmap. Перед завершением работы приложение должно удалить загруженное изображение, вызвав функцию DeleteObject: BOOL WINAPI DeleteObject(HGDIOBJ hGDIObj); В качестве параметра этой функции следует передать идентификатор изображения, полученный от функции LoadBitmap. Создание кисти для закрашивания окнаОдно из простых применений изображений bitmap - раскрашивание фона окна. С этой целью вы можете использовать изображения размером 8х8 точек, созданные при помощи Resource Workshop. Изображение, которое будет использовано для закрашивания внутренней области окна, должно быть определено в файле описания ресурсов при помощи оператора BITMAP. После загрузки изображения функцией LoadBitmap приложение должно создать из этого изображения кисть, вызвав функцию CreatePatternBrush: HBRUSH WINAPI CreatePatternBrush(HBITMAP hBmp); В качестве параметра функции необходимо передать идентификатор изображения bitmap, полученный от функции LoadBitmap. Функция CreatePatternBrush возвращает идентификатор кисти, который можно использовать при регистрации класса окна. Значение этого идентификатора следует записать в поле hbrBackground структуры wndclass, используемой для регистрации класса окна. Перед завершением работы приложения созданная кисть должна быть уничтожена. Для этого следует вызвать функцию DeleteObject, передав ей в качестве параметра идентификатор кисти. Приложение BRUSHПриложение BRUSH демонстрирует использование изображения типа bitmap для закрашивания внутренней области окна (рис. 1.15).
Рис. 1.15. Закрашивание окна в приложении BRUSH Главный файл приложения BRUSH приведен в листинге 1.18. Листинг 1.18. Файл brush\brush.cpp // ---------------------------------------- // Использование кисти для закрашивания // внутренней области окна // ---------------------------------------- #define STRICT #include <windows.h> #include <mem.h> // Прототипы функций BOOL InitApp(HINSTANCE); LRESULT CALLBACK _export WndProc(HWND, UINT, WPARAM, LPARAM); // Имя класса окна char const szClassName[] = "BrushAppClass"; // Заголовок окна char const szWindowTitle[] = "Brush Demo"; // Идентификатор изображения bitmap HBITMAP hBmp; // Идентификатор кисти HBRUSH hBrush; // ===================================== // Функция WinMain // ===================================== #pragma argsused int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { MSG msg; // структура для работы с сообщениями HWND hwnd; // идентификатор главного окна приложения // Загружаем изображение bitmap из ресурсов hBmp = LoadBitmap(hInstance, "#123"); // Создаем кисть для закрашивания окна hBrush = CreatePatternBrush(hBmp); // Инициализируем приложение if(!InitApp(hInstance)) return FALSE; // После успешной инициализации приложения создаем // главное окно приложения hwnd = CreateWindow( szClassName, // имя класса окна szWindowTitle, // заголовок окна WS_OVERLAPPEDWINDOW, // стиль окна CW_USEDEFAULT, // задаем размеры и расположение CW_USEDEFAULT, // окна, принятые по умолчанию CW_USEDEFAULT, CW_USEDEFAULT, 0, // идентификатор родительского окна 0, // идентификатор меню hInstance, // идентификатор приложения NULL); // указатель на дополнительные // параметры // Если создать окно не удалось, завершаем приложение if(!hwnd) return FALSE; ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); // Запускаем цикл обработки сообщений while(GetMessage(&msg, 0, 0, 0)) { DispatchMessage(&msg); } // Перед завершением работы приложения // уничтожаем созданные нами изображение и кисть DeleteObject(hBmp); DeleteObject(hBrush); return msg.wParam; } // ===================================== // Функция InitApp // Выполняет регистрацию класса окна // ===================================== BOOL InitApp(HINSTANCE hInstance) { ATOM aWndClass; // атом для кода возврата WNDCLASS wc; // структура для регистрации // класса окна memset(&wc, 0, sizeof(wc)); // Закраска внутренней области окна wc.hbrBackground = hBrush; wc.style = 0; wc.lpfnWndProc = (WNDPROC) WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszMenuName = (LPSTR)NULL; wc.lpszClassName = (LPSTR)szClassName; // Регистрация класса aWndClass = RegisterClass(&wc); return (aWndClass != 0); } // ===================================== // Функция WndProc // ===================================== LRESULT CALLBACK _export WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DESTROY: { PostQuitMessage(0); return 0; } } return DefWindowProc(hwnd, msg, wParam, lParam); } Перед регистрацией класса главного окна приложения функция WinMain загружает изображение bitmap, вызывая функцию LoadBitmap: hBmp = LoadBitmap(hInstance, "#123"); В нашем примере в качестве идентификатора ресурса изображения мы указываем число 123 как строку символов, однако можно использовать и другие, описанные нами ранее, способы. Получив идентификатор изображения, функция WinMain создает кисть, для чего она вызывает функцию CreatePatternBrush: hBrush = CreatePatternBrush(hBmp); При заполнении структуры для регистрации класса окна в поле hbrBackground записывается идентификатор созданной кисти: wc.hbrBackground = hBrush; Перед завершением работы приложение уничтожает изображение и кисть, вызывая функцию DeleteObject: DeleteObject(hBmp); DeleteObject(hBrush); Файл ресурсов приведен в листинге 1.19. Листинг 1.19. Файл brush\brush.rc /* Изображение типа bitmap */ 123 BITMAP brush.bmp В этом файле описан один ресурс - изображение типа bitmap с идентификатором 123. При загрузке ресурса используется ссылка на этот идентификатор как на строку символов, для чего в качестве второго параметра функции LoadBitmap передается строка "#123". Можно также использовать ссылку с использованием макроса MAKEINTRESOURCE: hBmp = LoadBitmap(hInstance, MAKEINTRESOURCE(123)); Файл brush.bmp (листинг 1.20) был создан при помощи Resource Workshop. Еще раз обратим ваше внимание на то, что размер изображения для создания кисти должен быть 8х8 точек. Листинг 1.20. Файл brush\brush.bmp
Файл определения модуля для приложения BRUSH приведен в листинге 1.21. Листинг 1.21. Файл brush\brush.def ; ============================= ; Файл определения модуля ; ============================= NAME BRUSH DESCRIPTION 'Приложение BRUSH, (C) 1994, Frolov A.V.' EXETYPE windows STUB 'winstub.exe' STACKSIZE 5120 HEAPSIZE 1024 CODE preload moveable discardable DATA preload moveable multiple |