Шрифты
Шрифты
Для того чтобы рисовать текст, используются шрифты . Как мы уже говорили в предыдущих томах "Библиотеки системного программиста", операционная система Windows версии 3.1 может работать с растровыми, векторными и масштабируемыми шрифтами. Кроме этого, приложения Windows могут использовать шрифты, встроенные в устройство вывода (обычно это принтерные шрифты).
Растровые шрифты содержат битовые образы всех символов. Для каждого размера шрифта необходимо иметь свой набор символов. Кроме того, различные устройства вывода имеют разное соотношение горизонтальных и вертикальных размеров пиксела, что приводит к необходимости хранить отдельные наборы образов символов не только для разных размеров шрифта, но и для разного соотношения размеров пиксела физического устройства отображения.
Растровые шрифты плохо поддаются масштабированию, так как при этом наклонные линии контура символа принимают зазубренный вид.
Векторные шрифты хранятся в виде набора векторов, описывающих отдельные сегменты и линии контура символа, поэтому они легко масштабируются. Однако их внешний вид далек от идеального. Как правило, векторные шрифты используются для вывода текста на векторные устройства, такие, как плоттер.
Масштабируемые шрифты TrueType впервые появились в Windows версии 3.1 и сильно повлияли на рост популярности этой операционной системы. Шрифты True Type поддаются масштабированию без существенных искажений внешнего вида.
Создание цветовой палитры
Создание цветовой палитры
Процесс создания цветовой палитры несложен. Вначале надо убедиться в том, что bmp-файл содержит таблицу цветов. Если размер таблицы цветов не равен нулю, следует заказать память для структуры LOGPALETTE , заполнить соответствующим образом заголовок и переписать в палитру цвета из таблицы цветов: lpPal->palVersion = 0x300; lpPal->palNumEntries = wNumColors; for (i = 0; i < wNumColors; i++) { lpPal->palPalEntry[i].peRed =lpbmi->bmiColors[i].rgbRed; lpPal->palPalEntry[i].peGreen=lpbmi->bmiColors[i].rgbGreen; lpPal->palPalEntry[i].peBlue =lpbmi->bmiColors[i].rgbBlue; lpPal->palPalEntry[i].peFlags = 0; }
Палитра создается с помощью функции CreatePalette: hPal = CreatePalette(lpPal);
Создание изображений в памяти
Создание изображений в памяти
Другой способ работы с изображениями в формате DDB заключается в создании их непосредственно в оперативной памяти.
Вы должны подготовить массив, содержащий биты изображения, заполнить структуру типа BITMAP, которая описывает изображение, и затем вызвать функцию CreateBitmapIndirect , указав ей в качестве единственного параметра указатель lpbm на заполненную структуру типа BITMAP: HBITMAP CreateBitmapIndirect(BITMAP FAR* lpbm);
Функция вернет идентификатор битового изображения, который вы можете использовать обычным способом.
Как правило, в памяти создаются монохромные изображения небольших размеров. В этом случае структура битов изображения является достаточно простой.
Например, пусть нам надо нарисовать битовое изображение, показанное в увеличенном виде на Рисунок 4.2.
Создание кисти
Создание кисти
Если вам нужна цветная кисть, ее следует создать с помощью функции CreateSolidBrush : HBRUSH WINAPI CreateSolidBrush(COLORREF clrref);
В качестве параметра для этой функции необходимо указать цвет кисти. Для выбора цвета вы можете воспользоваться, например, макрокомандой RGB, позволяющей указать содержание отдельных цветовых компонент.
Windows может выбрать для кисти чистые или смешанные цвета, что зависит от текущего цветового разрешения. Подробности вы сможете узнать позже из главы, посвященной работе с цветами и цветовыми палитрами.
После использования созданной вами кисти ее следует удалить, не забыв перед этим выбрать в контекст отображения старую кисть. Для удаления кисти следует использовать макрокоманду DeleteBrush : #define DeleteBrush(hbr) DeleteObject((HGDIOBJ)(HBRUSH)(hbr))
Приложение может заштриховать внутреннюю область замкнутой фигуры, создав одну из шести кистей штриховки функцией CreateHatchBrush : HBRUSH WINAPI CreateHatchBrush(int fnStyle, COLORREF clrref);
С помощью параметра clrref вы можете определить цвет линий штриховки.
Параметр fnStyle задает стиль штриховки:
Создание области
Создание области
Приложение может создать область прямоугольной формы, область в виде многоугольника, область эллиптической формы. Можно комбинировать область из двух других, выполняя при этом над областями логические операции объединения, пересечения и т. д.
Структура PRINTDLG
Структура PRINTDLG
В качестве параметра функции PrintDlg необходимо передать адрес предварительно подготовленной структуры типа PRINTDLG , описанной в файле commdlg.h: typedef struct tagPD { DWORD lStructSize; HWND hwndOwner; HGLOBAL hDevMode; HGLOBAL hDevNames; HDC hDC; DWORD Flags; UINT nFromPage; UINT nToPage; UINT nMinPage; UINT nMaxPage; UINT nCopies; HINSTANCE hInstance; LPARAM lCustData; UINT (CALLBACK* lpfnPrintHook)(HWND, UINT,WPARAM,LPARAM); UINT (CALLBACK* lpfnSetupHook)(HWND, UINT,WPARAM,LPARAM); LPCSTR lpPrintTemplateName; LPCSTR lpSetupTemplateName; HGLOBAL hPrintTemplate; HGLOBAL hSetupTemplate; } PRINTDLG; typedef PRINTDLG FAR* LPPRINTDLG;
Рассмотрим назначение отдельных полей этой структуры.
Функция возвращает контекст отображения, позволяющий
Таблица 1
Константа | Описание |
DCX_WINDOW | Функция возвращает контекст отображения, позволяющий рисовать во всем окне, а не только в его внутренней области |
DCX_CACHE | Функция получает общий контекст отображения из кеша Windows, даже если окно создано на базе класса стиля CS_OWNDC или CS_CLASSDC |
DCX_CLIPCHILDREN | Видимые области всех дочерних окон, расположенных ниже окна hwnd, исключаются из области отображения |
DCX_CLIPSIBLINGS | Видимые области всех окон-братьев (окон, имеющих общих родителей), расположенных выше окна hwnd, исключаются из области отображения |
DCX_PARENTCLIP | Для отображения используется вся видимая область родительского окна, даже если родительское окно создано с использованием стилей WS_CLIPCHILDREN и WS_PARENTDC. Начало координат устанавливается в левый верхний угол окна hwnd |
DCX_EXCLUDERGN | Если указан этот флаг, при выводе будет использована область ограничения, заданная параметром hrgnClip |
DCX_INTERSECTRGN | Используется пересечение области ограничения, заданной параметром hrgnClip, и видимой области полученного контекста отображения |
DCX_LOCKWINDOWUPDATE | Этот флаг разрешает рисование в окне, заблокированном для рисования функцией LockWindowUpdate . Флаг можно использовать при необходимости рисовать, например, рамку, выделяющую произвольную область экрана |
Таблица 1
Поле | Описание |
bmType | Тип битового изображения. Должен быть равен 0 |
bmWidth | Ширина битового изображения в пикселах, должна быть больше 0 |
bmHeight | Высота битового изображения в пикселах, должна быть больше 0 |
bmWidthBytes | Размер памяти, занимаемый одной строкой растра битового изображения. Это значение должно быть четным, так как массив изображения состоит из целых чисел размером 16 бит. Таким образом, произведение bmWidthBytes*8 должно быть кратно 16. Кроме того, это произведение должно быть больше или равно произведению bmWidth*bmBitsPixel |
bmPlanes | Количество плоскостей в битовом изображении. В зависимости от типа видеоадаптера и его режима работы для представления цвета одного пиксела может использоваться несколько бит, расположенных в одной или нескольких плоскостях видеопамяти (подробное описание структуры видеопамяти в различных режимах вы можете найти в 3 томе "Библиотеки системного программиста") |
bmBitsPixel | Количество битов, используемых для представления цвета пиксела. Если используется несколько плоскостей, то это поле содержит количество бит одной плоскости, используемых для представления цвета пиксела |
bmBits | Дальний указатель на массив, содержащий биты изображения |
Для монохромных битовых изображений используется одна плоскость. Для определения цвета пиксела (черный или белый) используется один бит памяти. Размер памяти, занимаемый одной строкой растра битового изображения, кратен величине 16 бит.
Пусть, например, вы подготовили с помощью графического редактора, входящего в состав приложения Resource Workshop, битовое изображение, показанное на Рисунок 4.1. Для наглядности каждая строка растра этого изображения пронумерована.
Таблица 1
Семейство | Название шрифта | Пример текста |
Modern | Courier | Шрифт в стиле Modern |
Roman | Times | Шрифт в стиле Roman |
Swiss | Helvetica | Шрифт в стиле Swiss |
Script | Script Cyrillic | Шрифт в стиле Script |
Decorative | Wingdings | Dm13m,0=;rative |
Другая важная характеристика шрифта - это размер букв. Из 11 тома "Библиотеки системного программиста" вы знаете, что для описания вертикального размера букв шрифта используются несколько параметров. Не останавливаясь на тонкостях, отметим, что шрифты, содержащие буквы разного размера, являются разными шрифтами.
Растровые шрифты, которые относятся к одному семейству, но имеют разные размеры букв, хранятся в отдельных файлах. В то же время благодаря возможности масштабирования шрифтов True Type для них нет необходимости в отдельном хранении глифов различных размеров.
GDI может выполнять масштабирование растровых шрифтов, увеличивая (но не уменьшая) размер букв. Результат такого масштабирования при большом размере букв обычно неудовлетворительный, так как на наклонных линиях контура букв образуются зазубрины (Рисунок 1.5 в первой главе).
Векторные шрифты легко поддаются масштабированию, поэтому для хранения шрифта одного семейства, но разного размера, можно использовать один файл.
Вы знаете, что шрифты могут иметь нормальное (normal), жирное (bold) или наклонное (italic) начертание:
Таблица 1
Поле | Описание |
dmDeviceName | Имя драйвера принтера |
dmSpecVersion | Номер версии структуры DEVMODE. Для Windows версии 3.1 это поле содержит значение 0x30a |
dmDriverVersion | Версия драйвера |
dmSize | Размер структуры DEVMODE в байтах |
dmDriverExtra | Размер в байтах дополнительной структуры данных, которая может находиться в памяти сразу за структурой DEVMODE |
dmFields | Набор флагов, каждый из которых отвечает за свое поле структуры DEVMODE. Если флаг установлен, соответствующее поле инициализируется. возможны следующие значения: DM_ORIENTATION , DM_PAPERSIZE , DM_PAPERLENGTH , DM_PAPERWIDTH , DM_SCALE , DM_COPIES , DM_DEFAULTSOURCE , DM_PRINTQUALITY , DM_COLOR , DM_DUPLEX , DM_YRESOLUTION , DM_TTOPTION |
dmOrientation | Ориентация бумаги. Возможные значения:DMORIENT_PORTRAIT , DMORIENT_LANDSCAPE |
dmPaperSize | Код размера бумаги. Например, для бумаги формата A4 используется константа DMPAPIER_A4 |
dmPaperLength | Длина листа бумаги в десятых долях миллиметра |
dmPaperWidth | Ширина листа бумаги в десятых долях миллиметра |
dmScale | Коэффициент масштабирования для печати |
dmCopies | Количество печатаемых копий |
dmDefaultSource | Код устройства подачи бумаги, используемого по умолчанию. |
dmPrintQuality | Код разрешения принтера: DMRES_HIGH , DMRES_LOW , DMRES_MEDIUM , DMRES_DRAFT или положительное число, равное количеству точек на дюйм |
dmColor | Режим печати для цветного принтера: DMCOLOR_COLOR - цветная печать, DMCOLOR_MONOCHROME - монохромная печать |
dmDuplex | Возможность печати с двух сторон бумажного листа |
dmYResolution | Разрешение принтера по вертикали в точках на дюйм |
dmTTOption | Способ печати шрифтов True Type:DMTT_BITMAP - печать в графическом режиме, обычно используется для матричных принтеров;DMTT_DOWNLOAD - загрузка шрифтов True Type в память принтера, используется для лазерных принтеров, совместимых с принтерами HP LaserJet;DMTT_SUBDEV - замена шрифтов на принтерные шрифты, используется для PostScript-принтеров |
Первые три слова структуры содержат смещения текстовых строк с именами, соответственно, драйвера, принтера и порта вывода. Строки расположены в памяти непосредственно за структурой DEVNAMES. Поле wDefault может содержать флаг DN_DEFAULTPRN , в этом случае все три строки описывают принтер, выбранный по умолчанию.
Вы можете подготовить свои значения для двух описанных выше структур, заказать глобальные блоки памяти и передать их идентификаторы функции PrintDlg, записав в соответствующие поля структуры PRINTDLG.
После возврата из функции PrintDlg необходимо освободить эти блоки памяти, взяв их идентификаторы из полей hDevMode и hDevNames структуры PRINTDLG. Учтите, что функция PrintDlg может изменить значения последних двух полей, поэтому надо освобождать блоки памяти с идентификаторами, взятыми из структуры PRINTDLG после возврата из функции PrintDlg: if(pd.hDevMode != 0) GlobalFree (pd.hDevMode); if(pd.hDevNames != 0) GlobalFree (pd.hDevNames);
Если перед вызовом функции PrintDlg вы указали флаги PD_RETURNDC или PD_RETURNIC, после возврата поле hDC будет содержать, соответственно, идентификатор контекста устройства или идентификатор информационного контекста: if(fResult) return pd.hDC; else return NULL;
Из этой таблицы видны недостатки
Таблица 2
Параметр функции GetDeviceCaps | CGA | EGA | VGA | SVGA 800x 600 | 8514/A | SVGA 1024 x 768 |
HORZRES | 640 | 640 | 640 | 800 | 1024 | 1024 |
VERTRES | 200 | 350 | 480 | 600 | 760 | 768 |
HORZSIZE | 240 | 240 | 208 | 208 | 280 | 208 |
VERTSIZE | 180 | 175 | 156 | 152 | 210 | 152 |
ASPECTX | 5 | 38 | 36 | 36 | 10 | 36 |
ASPECTY | 12 | 48 | 36 | 36 | 14 | 36 |
ASPECTXY | 13 | 61 | 51 | 51 | 14 | 51 |
LOGPIXELSX | 96 | 96 | 96 | 96 | 120 | 96 |
LOGPIXELSY | 48 | 72 | 96 | 96 | 120 | 96 |
Во-первых, вертикальное (VERTRES) и горизонтальное (HORZRES) разрешение зависит от типа видеоконтроллера.
Во-вторых, физические размеры пикселов (ASPECTX и ASPECTY ), и, что самое главное, отношение высоты и ширины пиксела также зависят от типа видеоконтроллера.
Если приложению требуется нарисовать, например, окружность или квадрат, при использовании физической системы координат придется учитывать форму пикселов, выполняя масштабирование изображения по одной из осей координат. В противном случае вместо окружности и квадрата на экране появятся эллипс и прямоугольник.
Таблица 2
Код растровой операции | Логическое выражение | Описание |
SRCCOPY | S | Исходное изображение копируется в контекст отображения |
SRCPAINT | S | D | Цвет полученного изображения определяется при помощи логической операции ИЛИ над цветом изображения и цветом фона |
SRCAND | S & D | Цвет полученного изображения определяется при помощи логической операции И над цветом изображения и цветом фона |
SRCINVERT | S ^ D | Цвет полученного изображения определяется при помощи логической операции ИСКЛЮЧАЮЩЕЕ ИЛИ над цветом изображения и цветом фона |
SRCERASE | S & ~D | Цвет фона инвертируется, затем выполняется операция И над результатом и цветом исходного изображения |
NOTSRCCOPY | ~S | После рисования цвет изображения получается инвертированием цвета исходного изображения |
NOTSRCERASE | ~(S | D) | Цвет полученного изображения получается инвертированием результата логической операции ИЛИ над цветом изображения и цветом фона |
MERGECOPY | P & S | Выполняется логическая операции И над цветом исходного изображения и цветом кисти |
MERGEPAINT | ~S | D | Выполняется логическая операции ИЛИ над инвертированным цветом исходного изображения и цветом фона |
PATCOPY | P | Выполняется копирование цвета кисти |
PATPAINT | P | ~S | D | Цвет кисти комбинируется с инвертированным цветом исходного изображения, при этом используется логическая операция ИЛИ. Полученный результат комбинируется с цветом фона, также с помощью логической операции ИЛИ |
PATINVERT | P ^ D | Цвет полученного изображения определяется при помощи логической операции ИСКЛЮЧАЮЩЕЕ ИЛИ над цветом кисти и цветом фона |
DSTINVERT | ~D | Инвертируется цвет фона |
BLACKNESS | 0 | Область закрашивается черным цветом |
WHITENESS | 1 | Область закрашивается белым цветом |
Для рисования битовых изображений можно использовать вместо функции BitBlt функцию StretchBlt , с помощью которой можно выполнить масштабирование (сжатие или растяжение) битовых изображений: BOOL WINAPI StretchBlt( HDC hdcDest, // контекст для рисования int nXDest, // x-координата верхнего левого угла // области рисования int nYDest, // y-координата верхнего левого угла // области рисования int nWidthDest, // новая ширина изображения int nHeightDest, // новая высота изображения HDC hdcSrc, // идентификатор исходного контекста int nXSrc, // x-координата верхнего левого угла // исходной области int nYSrc, // y-координата верхнего левого угла // исходной области int nWidthSrc, // ширина исходного изображения int nHeightSrc, // высота исходного изображения DWORD dwRop); // код растровой операции
Параметры этой функции аналогичны параметрам функции BitBlt, за исключением того, что ширина и высота исходного и полученного изображения должна определяться отдельно. Размеры исходного изображения (логические) задаются параметрами nWidthSrc и nHeightSrc, размеры нарисованного изображения задаются параметрами nWidthDest и nHeightDest.
Возвращаемое значение равно TRUE при успешном завершении или FALSE при ошибке.
Следует упомянуть также еще одну функцию, которая сама по себе не может рисовать битовые изображения, но часто используется для закраски прямоугольных областей экрана. Эта функция имеет имя PatBlt : BOOL WINAPI PatBlt( HDC hdc, // контекст для рисования int nX, // x-координата верхнего левого угла // закрашиваемой области int nY, // y-координата верхнего левого угла // закрашиваемой области int nWidth, // ширина области int nHeight, // высота области DWORD dwRop); // код растровой операции
При использовании этой функции вы можете закрашивать области экрана с использованием следующих кодов растровых операций: PATCOPY, PATINVERT, PATPAINT, DSTINVERT, BLACKNESS, WHITENESS.
Возвращаемое функцией PatBlt значение равно TRUE при успешном завершении или FALSE при ошибке.
Таблица 2
Начертание | Образец шрифта |
Normal | AaBbCcDdEeFfGgHhIiJjKkLl АаБбВвГгДдЕеЖжЗзИиКкЛлМмНн |
Bold | AaBbCcDdEeFfGgHhIiJjKkLl АаБбВвГгДдЕеЖжЗзИиКкЛлМмНн |
Italic | AaBbCcDdEeFfGgHhIiJjKkLl АаБбВвГгДдЕеЖжЗзИиКкЛлМмНнОоПпРр |
Еще один часто используемый атрибут оформления строк текста - подчеркивание: Текст с подчеркиванием
Иногда используется шрифт с перечеркнутыми буквами.
GDI выполняет подчеркивание самостоятельно, файлы шрифтов не содержат глифы с подчеркиванием.
Растровые и векторные шрифты хранятся в системном каталоге Windows в файлах с расширением имени fon.
Глифы масштабируемых шрифтов True Type находятся в файлах с расширением имени ttf, причем сами эти файлы могут располагаться в любом каталоге. В процессе регистрации масштабируемого шрифта Windows создает в своем системном каталоге файлы с расширением имени fot, которые содержат ссылки на соответствующие ttf-файлы.
С помощью приложения Control Panel вы можете добавлять или удалять любые шрифты. Следует, однако, учитывать ограничение: в системе можно одновременно использовать не более 253, к тому же для представления жирного и наклонного начертания используются отдельные масштабируемые шрифты. Чрезмерное количество установленных шрифтов может привести к снижению производительности системы.
может быть разный для осей
Таблица 3
Режим отображения | Направление оси X | Направление оси Y | Размер одной логической единицы |
MM_TEXT | Вправо | Вниз | 1 пиксел |
MM_LOMETRIC | Вправо | Вверх | 0,1 мм |
MM_HIMETRIC | Вправо | Вверх | 0,01 мм |
MM_LOENGLISH | Вправо | Вверх | 0,01 дюйм |
MM_HIENGLISH | Вправо | Вверх | 0,001 дюйм |
MM_TWIPS | Вправо | Вверх | 1/1440 дюйма |
MM_ISOTROPIC | Можно выбирать | Можно выбирать | Произвольный, одинаковый для осей Xи Y |
MM_ANISOTROPIC | Можно выбирать | Можно выбирать | Произвольный, может быть разный для осей X и Y |
Нетрудно заметить, что в режиме MM_TEXT логическая единица длины полностью соответствует физической, поэтому при рисовании геометрических фигур возможны искажения формы. Эти искажения связаны с тем, что форма пиксела для некоторых видеоконтроллеров может быть отличной от квадратной. Режим MM_TEXT неудобен для рисования фигур.
В режимах MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, MM_TWIPS используется более привычное направление осей координат и единицы длины, не зависящие от аппаратного обеспечения устройства вывода.
В режиме MM_ISOTROPIC вы можете выбирать произвольное направление осей координат и произвольный (но одинаковый) масштаб для осей X и Y. Заметим, что произвольное направление координат в нашем случае не подразумевает их произвольного расположения относительно вертикальной и горизонтальной осей - ось X может располагаться только горизонтально, ось Y - только вертикально.
Режим MM_ANISOTROPIC еще более универсален. Он позволяет устанавливать произвольное направление осей координат, произвольный масштаб для осей координат, причем для каждой оси можно установить свой собственный масштаб.
Во всех режимах отображения, кроме MM_TEXT и MM_ANISOTROPIC с разным масштабом для осей X и Y, приложение может не заботиться о "квадратуре пиксела", так как масштаб по осям координат одинаковый и не зависит от особенностей устройства вывода.
Сделаем небольшое пояснение относительно режима отображения MM_TWIPS. В этом режиме используется единица длины twip (от twentieth of a point - двадцатая часть точки, или, в терминах полиграфии, двадцатая часть пункта). Размер одного пункта приблизительно равен 1/72 дюйма, следовательно размер единицы длины twip равен 1/1440 дюйма.
С помощью функции GetMapMode приложение может в любой момент времени определить номер режима отображения, выбранный в контекст отображения hdc: int WINAPI GetMapMode(HDC hdc);
Таблица 3
Поле | Описание |
bfType | Тип файла. Поле содержит значение 0x4D42 (текстовая строка "BM"). Анализируя содержимое этого поля, приложение может идентифицировать файл как содержащий битовое изображение |
bfSize | Размер файла в байтах. Это поле может содержать неправильное значение, так как в SDK для Windows версии 3.0 поле bfSize было описано неправильно (утверждалось, что это поле содержит размер файла в двойных словах). Обычно содержимое этого поля игнорируется, так как из-за ошибки в документации старые приложения устанавливали в этом поле неправильное значение |
bfReserved1 | Зарезервировано, должно быть равно 0 |
bfReserved2 | Зарезервировано, должно быть равно 0 |
bfOffBits | Смещение битов изображения от начала файла в байтах. Область изображения не обязательно должна быть расположена сразу вслед за заголовками файла или таблицей цветов (если она есть) |
Сразу после структуры BITMAPFILEHEADER в bmp-файле расположена структура BITMAPINFO (для изображений Windows) или BITMAPCOREINFO (для изображений Presentation Manager).
Структура BITMAPINFO и указатели на нее описаны в файле windows.h следующим образом: typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; } BITMAPINFO; typedef BITMAPINFO* PBITMAPINFO; typedef BITMAPINFO FAR* LPBITMAPINFO;
Структура BITMAPINFOHEADER описывает размеры и способ представления цвета в битовом изображении: typedef struct tagBITMAPINFOHEADER { DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER; typedef BITMAPINFOHEADER* PBITMAPINFOHEADER; typedef BITMAPINFOHEADER FAR* LPBITMAPINFOHEADER;
Опишем назначение отдельных полей этой структуры.
Таблица 3
Идентификатор | Описание |
SYSTEM_FONT | Системный шрифт в кодировке ANSI с переменной шириной букв, используется операционной системой Windows для отображения текста в меню, заголовках окон и диалоговых панелях |
SYSTEM_FIXED_FONT | Шрифт в кодировке ANSI с фиксированной шириной букв. Использовался в старых версиях операционной системой Windows (до версии 3.0) как системный шрифт |
ANSI_VAR_FONT | Шрифт в кодировке ANSI с переменной шириной букв |
ANSI_FIXED_FONT | Шрифт в кодировке ANSI с фиксированной шириной букв |
OEM_FIXED_FONT | Шрифт в кодировке OEM с фиксированной шириной букв |
DEVICE_DEFAULT_FONT | Шрифт, который используется для данного устройства по умолчанию. Если устройство не имеет своих шрифтов, используется системный шрифт SYSTEM_FONT |
Первый параметр этой макрокоманды определяет идентификатор контекста отображения, в который выбирается шрифт с идентификатором hfont. Она возвращает идентификатор шрифта, который был выбран в контекст отображения раньше, до вызова SelectFont.
Вам не нужно удалять встроенные шрифты, так же как не нужно удалять встроенные кисти и перья.
Способности устройства рисовать линии. Возвращаемое
Таблица 4
Имя константы | Описание |
LINECAPS | Способности устройства рисовать линии. Возвращаемое значение представляет собой набор битовых масок, установленных в 1, если устройство может само рисовать линии различного типа:LC_INTERIORS устройство может закрашивать внутреннюю область;LC_MARKER маркеры;LC_NONE устройство не может рисовать линии;LC_POLYLINE ломаные линии;LC_POLYMARKER линии polymarker;LC_STYLED устройство может рисовать линии с использованием различных стилей (штриховые, пунктирные, штрих пунктирные и т.д.);LC_WIDE широкие линии;LC_WIDESTILED устройство может рисовать широкие линии с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.) |
CURVECAPS | Способность устройства рисовать различные кривые линии и геометрические фигуры. Возвращаемое значение представляет собой набор битовых масок, установленных в 1, если устройство может само рисовать различные фигуры:CC_CIRCLES окружности;CC_CHORD сегмент эллипса;CC_ELLIPSES эллипсы;CC_INTERIORS устройство может закрашивать внутреннюю область геометрических фигур;CC_NONE устройство не может рисовать кривые линии и геометрические фигуры;CC_PIE секторы эллипса;CC_ROUNDRECT прямоугольники со скругленными углами;CC_STYLED устройство может рисовать рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т.д.);CC_WIDE широкие рамки;CC_WIDESTYLED устройство может рисовать широкие рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.) |
POLYGONALCAPS | Способности устройства рисовать многоугольники. Возвращаемое значение представляет собой набор битовых масок, установленных в 1, если устройство может само рисовать многоугольники различного типа:PC_INTERIORS устройство может закрашивать внутреннюю область;PC_NONE устройство не может рисовать многоугольники;PC_RECTANGLE прямоугольники;PC_SCANLINES устройство может выполнять сканирование линий растра;PC_STYLED устройство может рисовать рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.);PC_WIDE широкие рамки;PC_WIDESTILED устройство может рисовать широкие рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.)PC_WINDPOLYGON многоугольники с заполнением в режиме WINDING |
Учитывая сказанное выше, не следует строить работу приложений таким образом, чтобы периодичность вывода или скорость работы приложения зависела от скорости рисования (подобная практика не приветствуется и при создании программ для MS-DOS, вспомните, как ведут себя старые игры, разработанные для процессора 8088, на компьютерах с процессорами i80386 или i486). Современные видеоадаптеры сконструированы таким образом, что большинство основных операций рисования, используемых в операционной системе Windows, выполняются аппаратно. Эти видеоадаптеры иногда называются ускорителями Windows. Скорость рисования для ускорителя Windows может превышать в десятки раз скорость рисования для обычного адаптера VGA или SVGA.
Результат рисования геометрических фигур зависит от установки таких атрибутов контекста, как ширина, цвет и стиль линии (определяются выбранным в контекст отображения пером), способ закраски замкнутых фигур (определяется выбранной в контекст отображения кистью), цвета фона, прозрачностью фона (прозрачный режим TRANSPARENT и непрозрачный режим OPAQUE ), режимом рисования, режимом закрашивания, областью ограничения, режимом отображения, т. е. практически от всех атрибутов контекста отображения. Поэтому при описании функций мы будем попутно описывать способы изменения атрибутов контекста отображения, влияющих на результат их выполнения.
Работа с цветовыми палитрами и битовыми изображениями будут рассмотрены позже в отдельных разделах, так как эти вопросы далеко не тривиальны и поэтому заслуживают отдельного обсуждения.
Итак, перейдем непосредственно к описанию функций рисования геометрических фигур.
Таблица 4
Поле | Описание |
biSize | Размер структуры BITMAPINFOHEADER в байтах |
biWidth | Ширина битового изображения в пикселах |
biHeight | Высота битового изображения в пикселах |
biPlanes | Количество плоскостей в битовом изображении. Содержимое этого поля должно быть равно 1 |
biBitCount | Количество битов на один пиксел. Может быть равно 1, 4, 8 или 24. Для новых 16- и 32-битовых форматов файлов DIB, используемых в Windows NT, в этом поле могут находиться также значения 16 и 32 |
biCompression | Метод компрессии. Может принимать одно из следующих значений:BI_RGB - компрессия не используетсяBI_RLE4 - компрессия изображений, в которых для представления пиксела используется 4 бита. При использовании этого метода компрессии содержимое поля biBitCount должно быть равно 4BI_RLE8 - компрессия изображений, в которых для представления пиксела используется 8 бит. При использовании этого метода компрессии содержимое поля biBitCount должно быть равно 8BI_BITFIELDS - другой формат компрессии. Это значение используется для Windows NT. Соответствующая константа описана в файле windows.h, который поставляется вместе со средствами разработки приложений Windows NT |
biSizeImage | Размер изображения в байтах. Это поле содержит размер, необходимый для хранения разжатого изображения. Если компрессия не используется (в поле biCompression находится значение BI_RGB), содержимое поля biSizeImage может быть равно 0 |
biXPelsPerMeter | Разрешение устройства вывода по горизонтали в пикселах на метр, необходимое для вывода битового изображения без искажений. Это поле используется не всегда. Если оно не используется, в нем следует установить нулевое значение. |
biYPelsPerMeter | Разрешение устройства вывода по вертикали в пикселах на метр, необходимое для вывода битового изображения без искажений. Это поле, как и предыдущее, используется не всегда. Если оно не используется, в нем следует установить нулевое значение |
biClrUsed | Размер таблицы цветов. Это поле определяет размер массива структур RGBQUAD (Рисунок 4.4), расположенного в файле сразу после структуры BITMAPINFOHEADER. Если в этом поле находится нулевое значение, размер таблицы цветов зависит от количества бит, используемых для представления цвета одного пиксела (поле biBitCount) |
biClrImportant | Количество цветов, необходимое для отображения файла без искажений. Обычно в этом поле находится нулевое значение, в этом случае важны все цвета |
Поля rgbBlue, rgbGreen и rgbRed содержат RGB-компоненты цветов, поле rgbReserved зарезервировано и должно содержать нулевое значение.
Как мы уже говорили, файл битового изображения может содержать таблицу цветов, а может и не содержать ее. Приведем зависимость размера таблицы цветов в зависимости от значения поля biBitCount (количество бит, используемых для представления одного пиксела):
Таблица 4
Константа | Значение |
FW_DONTCARE | 0 |
FW_THIN | 100 |
FW_EXTRALIGHT | 200 |
FW_ULTRALIGHT | 200 |
FW_LIGHT | 300 |
FW_NORMAL | 400 |
FW_REGULAR | 400 |
FW_MEDIUM | 500 |
FW_SEMIBOLD | 600 |
FW_DEMIBOLD | 600 |
FW_BOLD | 700 |
FW_EXTRABOLD | 800 |
FW_ULTRABOLD | 800 |
FW_BLACK | 900 |
FW_HEAVY | 900 |
в контекст отображения по умолчанию
Таблица 5
Значение | Описание |
BLACK_PEN | Перо, рисующее черную линию толщиной в один пиксел (для любого режима отображения). Это перо выбрано в контекст отображения по умолчанию |
WHITE_PEN | Перо белого цвета. Толщина пера также равна одному пикселу и не зависит от режима отображения |
NULL_PEN | Невидимое перо толщиной в один пиксел. Используется для рисования замкнутых закрашенных фигур (таких, как прямоугольник или эллипс) в тех случаях, когда контур фигуры должен быть невидимым |
Макрокоманда SelectPen возвращает идентификатор пера, который был выбран в контекст отображения раньше. Вы можете сохранить этот идентификатор и использовать его для восстановления старого пера.
Однако при помощи встроенных перьев вы не можете нарисовать цветные, широкие, штриховые и штрих-пунктирные линии.
Если вас не устраивают встроенные перья, вы можете легко создать собственные. Для этого нужно воспользоваться функциями CreatePen или CreatePenIndirect.
Функция CreatePen позволяет определить стиль, ширину и цвет пера: HPEN WINAPI CreatePen( int fnPenStyle, // стиль пера int nWidth, // ширина пера COLORREF clrref); // цвет пера
Параметр fnPenStyle определяет стиль линии и может принимать одно из следующих значений, определенных в файле windows.h:
Таблица 5
Значение biBitCount | Размер таблицы цветов |
1 | 2 |
4 | 16 |
8 | 256 |
24 | не используется |
Таблица 5
Константа | Значение | Описание |
ANSI_CHARSET | 0 | Набор символов в кодировке ANSI |
DEFAULT_CHARSET | 1 | Не используется при отображении шрифтов. Определяется при необходимости запросить шрифт с заданным именем и размером шрифта. Следует использовать с осторожностью, так как если указанного шрифта нет, GDI может выделить шрифт с любым набором символов |
SYMBOL_CHARSET | 2 | Символьный шрифт, такой как, например, Wingdings |
SHIFTJIS_CHARSET | 128 | Шрифт, в котором для представления символов используется двухбайтовая кодировка. Нужен для работы с японской версией Windows |
OEM_CHARSET | 255 | Набор символов в кодировке OEM |
PS_SOLID
Таблица 6
Стиль линии | Внешний вид | Описание |
PS_SOLID |
Таблица 6
Поле | Описание |
bcSize | Размер структуры BITMAPCOREHEADER в байтах |
bcWidth | Ширина битового изображения в пикселах |
bcHeight | Высота битового изображения в пикселах |
bcPlanes | Количество плоскостей в битовом изображении. Содержимое этого поля должно быть равно 1 |
bcBitCount | Количество битов на один пиксел. Может быть равно 1, 4, 8 или 24 |
Зная количество битов, используемых для представления одного пиксела изображения, нетрудно определить количество элементов в таблице цветов: wClrUsed = 1 << bcBitCount;
Таблица 6
Константа | Значение | Описание |
OUT_DEFAULT_PRECIS | 0 | Используется точность, заданная по умолчанию |
OUT_STRING_PRECIS | 1 | Выбирается шрифт, для которого соблюдается наибольшее соответствие в размерах символов |
OUT_CHARACTER_PRECIS | 2 | Аналогично OUT_STRING_PRECIS |
OUT_STROKE_PRECIS | 3 | Требуется точное соответствие между запрошенными атрибутами и атрибутами полученного шрифта |
OUT_TT_PRECIS | 4 | Выбирается масштабируемый шрифт True Type, даже если есть подходящий растровый или векторный шрифт |
OUT_DEVICE_PRECIS | 5 | Выбирается шрифт устройства вывода |
OUT_RASTER_PRECIS | 6 | Выбирается растровый шрифт |
OUT_TT_ONLY_PRECIS | 7 | Используются только шрифты True Type |
Не меняется, т. е. перо
Таблица 7
Режим рисования | Формула | Цвет пиксела |
R2_COPYPEN | P | Соответствует (равен) цвету пера |
R2_BLACK | 0 | Черный |
R2_WHITE | 1 | Белый |
R2_NOP | D | Не меняется, т. е. перо ничего не рисует |
R2_NOT | ~D | Получается инвертированием цвета подложки, т. е. цвета пиксела до рисования |
R2_NOTCOPYPEN | ~P | Получается инвертированием цвета пера |
R2_MASKPEN | P&D | Комбинация компонент цветов, имеющихся как в цвете подложки, так и в цвете пера |
R2_NOTMASKPEN | ~(P&D) | Инверсия предыдущего значения |
R2_MERGEPEN | P|D | Комбинация компонент цветов подложки и пера |
R2_NOTMERGEPEN | ~(P|D) | Инверсия предыдущего значения |
R2_XORPEN | P^D | При определении цвета пиксела выполняется операция "ИСКЛЮЧАЮЩЕЕ ИЛИ" между компонентами цвета подложки и пера |
R2_NOTXORPEN | ~(P^D) | Инверсия предыдущего значения |
R2_MASKNOTPEN | ~P & D | Комбинация цвета подложки и инверсии цвета пера |
R2_MASKPENNOT | P & ~D | Комбинация двух цветов: инверсии цвета подложки и цвета пера |
R2_MERGENOTPEN | ~P | D | Комбинация компонент цветов подложки и инверсии цвета пера |
R2_MERGEPENNOT | P | ~D | Комбинация инверсии цвета подложки и цвета пера |
В режиме R2_COPYPEN, который установлен в контексте отображения по умолчанию, цвет нарисованной линии будет такой же, как и цвет пера. Для режимов R2_BLACK и R2_WHITE цвет линии будет, соответственно, черный и белый. В режиме R2_NOP вы не увидите нарисованную линию, так как цвет вдоль нее вообще не изменится. Более интересен режим R2_NOT, при использовании которого на черном фоне будет нарисована белая линия, а на белом фоне - черная.
Для цветных изображений перечисленные выше формулы применяются по отдельности к каждой компоненте цвета (всего в Windows используется три компоненты цвета - красная, зеленая и голубая), поэтому для некоторых режимов рисования цвет линии предсказать достаточно трудно. Использование цветовых палитр, которые мы рассмотрим в третьей главе нашей книги, дополнительно усложняет эту задачу.
С помощью функции GetROP2 приложение может определить режим рисования, установленный для контекста отображения hdc: int WINAPI GetROP2(HDC hdc);
Таблица 7
Поле | Критерии проверки |
biPlanes | Должно содержать значение 1 |
biBitCount | Может быть равно 1, 4, 8 или 24.Вы можете столкнуться с новыми 16- и 32-битовыми форматами файлов DIB, используемых в Windows NT. Для них в этом поле могут находиться также значения 16 и 32. Если ваше приложение не умеет обрабатывать такие файлы, данную ситуацию следует рассматривать как ошибочную |
biCompression | Может принимать одно из следующих значений: BI_RGB, BI_RLE4, BI_RLE8.При использовании метода компрессии BI_RLE4 содержимое поля biBitCount должно быть равно 4. При использовании метода компрессии BI_RLE8 содержимое поля biBitCount должно быть равно 8.Ваше приложение может ограничиться обработкой bmp-файлов в формате BI_RGB, как это делает, например, приложение Paintbrush |
Итак, подводя итоги, можно выдать следующие рекомендации:
смело игнорируйте bmp-файлы в формате Presentation Manager, а если вы не можете так поступить, преобразуйте их в формат Windows;
в структуре BITMAPINFOHEADER проверяйте только поля biPlanes, biBitCount и biCompression;
так как метод компрессии RLE4 и RLE8 используются редко и не приводит к значительной экономии памяти, ваше приложение может не поддерживать компрессованные bmp-файлы.
Таблица 7
Константа | Описание |
DEFAULT_QUALITY | Качество не имеет значения |
DRAFT_QUALITY | Низкое качество. Допустимо масштабирование шрифтов, синтезирование наклонных, жирных, перечеркнутых и подчеркнутых символов |
PROOF_QUALITY | Высокое качество. Масштабирование шрифтов не допускается. При этом могут быть получены символы, имеющие размер, немного меньший запрошенного |
Бесцветная кисть, которая ничего не
Таблица 8
Значение | Описание |
BLACK_BRUSH | Кисть черного цвета |
WHITE_BRUSH | Кисть белого цвета |
GRAY_BRUSH | Серая кисть |
LTGRAY_BRUSH | Светло-серая кисть |
DKGRAY_BRUSH | Темно-серая кисть |
NULL_BRUSH | Бесцветная кисть, которая ничего не закрашивает |
HOLLOW_BRUSH | Синоним для NULL_BRUSH |
Макрокоманда GetStockBrush возвращает идентификатор встроенной кисти.
Прежде чем использовать полученную таким образом кисть, ее надо выбрать в контекст отображения (так же, как и перо). Для этого проще всего воспользоваться макрокомандой SelectBrush : #define SelectBrush(hdc, hbr) \ ((HBRUSH)SelectObject((hdc), (HGDIOBJ)(HBRUSH)(hbr)))
Макрокоманда SelectBrush возвращает идентификатор старой кисти, выбранной в контекст отображения раньше.
Таблица 8
Константа | Описание |
DEFAULT_PITCH | Не имеет значения, будет ли шрифт иметь фиксированную или переменную ширину символов |
FIXED_PITCH | Нужен шрифт с фиксированной шириной символов |
VARIABLE_PITCH | Нужен шрифт с переменной шириной символов |
Внешний вид
Таблица 9
Стиль штриховки | Внешний вид |
HS_BDIAGONAL |
Таблица 9
Константа | Описание |
FF_DECORATIVE | Шрифт, содержащий маленькие рисунки (пиктограммы). Примером такого шрифта может послужить шрифт Wingdings, поставляемый в составе Windows |
FF_DONTCARE | Семейство шрифта не имеет значения |
FF_MODERN | Семейство Modern. Фиксированная ширина символов, могут быть засечки (но могут и не быть) |
FF_ROMAN | Семейство Roman. Переменная ширина букв, есть засечки |
FF_SCRIPT | Семейство Script. Рукописный шрифт |
FF_SWISS | Семейство Swiss. Переменная ширина букв, нет засечек |
Область hrgnSrc1, которая не входит
Таблица 10
Значение параметра fnCombineMode | Способ образования области hrgnDest |
RGN_AND | Пересечение областей hrgnSrc1 и hrgnSrc2 |
RGN_OR | Объединение областей hrgnSrc1 и hrgnSrc2 |
RGN_XOR | Объединение областей hrgnSrc1 и hrgnSrc2 с исключением перекрывающихся областей |
RGN_DIFF | Область hrgnSrc1, которая не входит в область hrgnSrc2 |
RGN_COPY | Область hrgnSrc1 |
Таблица 10
Поле | Описание |
lStructSize | Размер структуры в байтах. Это поле необходимо заполнить перед вызовом функции ChooseFont |
hwndOwner | Идентификатор окна, которому будет принадлежать диалоговая панель. Если в поле Flags не указан флаг CF_SHOWHELP, в это поле можно записать значение NULL. Поле заполняется до вызова функции ChooseFont |
hDC | Идентификатор контекста отображения или информационного контекста для принтера. Если установлен флаг CF_PRINTERFONTS, в списке появятся шрифты, доступные в данном контексте |
lpLogFont | Указатель на структуру LOGFONT. Приложение может заполнить нужные поля в этой структуре перед вызовом функции ChooseFont. Если при этом будет установлен флаг CF_INITTOLOGFONTSTRUCT, выбранные значения будут использоваться в качестве начальных. |
iPointSize | Размер букв выбранного шрифта в десятых долях пункта. Содержимое этого поля устанавливается после возврата из функции ChooseFont |
Flags | Флаги инициализации диалоговой панели. Можно использовать следующие значения:CF_APPLY - разрешается использование кнопки "Apply";CF_ANSIONLY - в списке выбора появляются только шрифты в кодировке ANSI;CF_BOTH - в списке шрифтов появляются экранные и принтерные шрифты;CF_TTONLY - можно выбирать только масштабируемые шрифты True Type;CF_EFFECTS - если указан этот флаг, с помощью диалоговой панели можно определять цвет букв создавать подчеркнутые и перечеркнутые шрифты. В этом случае необходимо перед вызовом функции проинициализировать содержимое полей lfStrikeOut, lfUnderline, rgbColors;CF_ENABLEHOOK - разрешается использовать функцию фильтра адрес которой указан в поле lpfnHook;CF_ENABLETEMPLATE - разрешается использование шаблона диалоговой панели, определяемого содержимым полей hInstance и lpTemplateName;CF_ENABLETEMPLATEHANDLE - флаг указывает, что поле hInstance содержит идентификатор загруженного шаблона диалоговой панели. Содержимое поля lpTemplateName игнорируется;CF_FIXEDPITCHONLY - можно выбрать только шрифты с фиксированной шириной символов:CF_FORCEFONTEXIST - выдается сообщение об ошибке, если пользователь пытается выбрать несуществующий шрифт;CF_INITTOLOGFONTSTRUCT - для инициализации диалоговой панели используется содержимое структуры LOGFONT, адрес которой передается через поле lpLogFont;CF_LIMITSIZE - при выборе шрифта учитывается содержимое полей nSizeMin и nSizeMax;CF_NOFACESEL - отменяется выбор в списке "Font";CF_NOOEMFONTS - нельзя выбирать векторные шрифты, этот флаг аналогичен флагу CF_NOVECTORFONTS;CF_NOSIMULATIONS - запрещается эмуляция шрифтов;CF_NOSIZESEL - отменяется выбор размера шрифта;CF_NOSTYLESEL - отменяется выбор стиля шрифта;CF_NOVECTORFONTS - нельзя выбирать векторные шрифты, этот флаг аналогичен флагу CF_NOOEMFONTS;CF_PRINTERFONTS - в списке появляются только такие шрифты, которые поддерживаются принтером, контекст отображения для которого задан в поле hDC;CF_SCALABLEONLY - можно выбирать только масштабируемые и векторные шрифты;CF_SCREENFONTS - можно выбирать только экранные шрифты;CF_SHOWHELP - в диалоговой панели отображается кнопка "Help";CF_USESTYLE - строка lpszStyle содержит указатель на буфер, который содержит строку описания стиля. Эта строка используется для инициализации списка "Font Style" диалоговой панели "Font";CF_WYSIWYG - можно выбирать только такие шрифты, которые доступны и для отображения на экране, и для печати на принтере. Если установлен этот флаг, следует также установить флаги CF_BOTH и CF_SCALABLEONLY |
rgbColors | Цвет символов шрифта, который будет выбран в меню "Colors" диалоговой панели "Fonts" сразу после отображения диалоговой панели. Должен использоваться флаг CF_EFFECTS. Поле заполняется до вызова функции ChooseFont, после возврата из функции поле содержит значение выбранного цвета |
lCustData | Произвольные данные, передаваемые функции фильтра, определенной содержимым поля lpfnHook |
lpfnHook | Указатель на функцию фильтра, обрабатывающую сообщения, поступающие в диалоговую панель. Для работы с фильтром необходимо в поле Flags указать флаг CF_ENABLEHOOK |
lpTemplateName | Строка, закрытая двоичным нулем, которая содержит идентификатор шаблона диалоговой панели. Для использования этого поля необходимо указать флаг CF_ENABLETEMPLATE |
hInstance | Идентификатор модуля, который содержит шаблон диалоговой панели в качестве ресурса. Поле используется только в тех случаях, когда в поле Flags указаны значения CF_ENABLETEMPLATE или CF_ENABLETEMPLATEHANDLE. Поле заполняется до вызова функции ChooseFont |
lpszStyle | Указатель на буфер, содержащий строку, описывающую шрифт. Если указан флаг CF_USESTYLE, эта строка используется для инициализации списка "Font Style". Размер буфера должен быть не меньше LF_FACESIZE байт |
nFontType | Тип выбираемого шрифта. Можно использовать одно из следующих значений:SIMULATED_FONTTYPE - GDI может эмулировать этот шрифт;PRINTER_FONTTYPE - принтерный шрифт;SCREEN_FONTTYPE - экранный шрифт;BOLD_FONTTYPE - жирный шрифт, используется только для шрифтов True Type;ITALIC_FONTTYPE - наклонный шрифт, используется только для шрифтов True Type;REGULAR_FONTTYPE - не жирный и не наклонный шрифт, используется только для шрифтов True Type |
nSizeMin | Минимальный размер шрифта, который можно выбрать. Для использования этого поля необходимо установить флаг CF_LIMITSIZE |
nSizeMax | Максимальный размер шрифта, который можно выбрать. Для использования этого поля необходимо установить флаг CF_LIMITSIZE |
Новая область не является самопересекающейся
Таблица 11
Значение | Описание |
ERROR | Ошибка |
NULLREGION | Новая область пустая |
SIMPLEREGION | Новая область не является самопересекающейся (т. е. граница созданной области не пересекает саму себя) |
COMPLEXREGION | Создана самопересекающаяся область |
Таблица 11
Константа | Значение |
FW_DONTCARE | 0 |
FW_THIN | 100 |
FW_EXTRALIGHT | 200 |
FW_ULTRALIGHT | 200 |
FW_LIGHT | 300 |
FW_NORMAL | 400 |
FW_REGULAR | 400 |
FW_MEDIUM | 500 |
FW_SEMIBOLD | 600 |
FW_DEMIBOLD | 600 |
FW_BOLD | 700 |
FW_EXTRABOLD | 800 |
FW_ULTRABOLD | 800 |
FW_BLACK | 900 |
FW_HEAVY | 900 |
Поля tmFirstChar и tmLastChar определяют, соответственно, коды первого и последнего символа, определенных в шрифте.
Если приложение пытается вывести символ, код которого отсутствует в шрифте, вместо него будет выведен символ с кодом, расположенным в поле tmDefaultChar.
Поле tmBreakChar содержит код символа, который используется для переноса слов с одной строки на другую при выравнивании текста.
Поле tmPitchAndFamily содержит код семейства шрифта. В нем могут находится следующие флаги, соответствующие четырем младшим битам:
Векторный шрифт или масштабируемый шрифт
Таблица 12
Значение | Описание |
TMPF_FIXED_PITCH | Шрифт с фиксированной шириной букв |
TMPF_VECTOR | Векторный шрифт или масштабируемый шрифт True Type |
TMPF_TRUETYPE | Шрифт True Type |
TMPF_DEVICE | Шрифт устройства вывода, например, принтерный шрифт |
Старшие четыре бита описывают семейство шрифта:
Примером такого шрифта может послужить
Таблица 13
Константа | Описание |
FF_DECORATIVE | Шрифт, содержащий маленькие рисунки (пиктограммы). Примером такого шрифта может послужить шрифт Wingdings, поставляемый в составе Windows |
FF_DONTCARE | Семейство шрифта не имеет значения или неизвестно |
FF_MODERN | Семейство Modern. Фиксированная ширина символов, могут быть засечки (но могут и не быть) |
FF_ROMAN | Семейство Roman. Переменная ширина букв, есть засечки |
FF_SCRIPT | Семейство Script. Рукописный шрифт |
FF_SWISS | Семейство Swiss. Переменная ширина букв, нет засечек |
Не используется при отображении шрифтов.
Таблица 14
Константа | Значение | Описание |
ANSI_CHARSET | 0 | Набор символов в кодировке ANSI |
DEFAULT_CHARSET | 1 | Не используется при отображении шрифтов. Определяется при необходимости запросить шрифт с заданным именем и размером шрифта. Следует использовать с осторожностью, так как если указанного шрифта нет, GDI может выделить шрифт с любым набором символов |
SYMBOL_CHARSET | 2 | Символьный шрифт, такой как Wingdings |
SHIFTJIS_CHARSET | 128 | Шрифт, в котором для представления символов используется двухбайтовая кодировка. Нужен для работы с японской версией Windows |
OEM_CHARSET | 255 | Набор символов в кодировке OEM |
Поля tmDigitizedAspectX и tmDigitizedAspectY содержат значения, которые можно использовать для определения отношения масштабов устройства отображения по горизонтали и вертикали.
Через последний параметр функции EnumFontFamProc
Таблица 15
Значение | Описание |
DEVICE_FONTTYPE | Шрифт устройства вывода |
RASTER_FONTTYPE | Растровый шрифт |
TRUETYPE_FONTTYPE | Шрифт True Type |
Если приложение собирается продолжить просмотр доступных шрифтов, функция EnumFontFamProc должна возвратить ненулевое значение. Если просмотр должен быть завершен, следует возвратить нуль.
Текущая позиция пера
Текущая позиция пера
Для рисования линий в интерфейсе GDI предназначена функция LineTo, которая использует понятие текущей позиции пера (current pen position ). Функция LineTo рисует линию из точки, соответствующей текущей позиции пера в точку, указанную при помощи параметров. Для установки текущей позиции пера предназначена функция MoveTo .
По умолчанию текущая позиция пера равна значению (0,0), что в системе координат, выбранной по умолчанию, соответствует верхнему левому углу внутренней области окна.
Заметим, что текущая позиция используется интерфейсом GDI только для рисования линий.
Текущая позиция пера
Для рисования прямых линий (и только для этого) в контексте отображения хранятся координаты текущей позиции пера . Для изменения текущей позиции пера в Windows версии 3.1 есть две функции с именами MoveTo и MoveToEx . Для совместимости с 32-разрядными версиями Windows, такими, как Windows NT, в новых приложениях следует использовать функцию MoveToEx: BOOL WINAPI MoveToEx( HDC hdc, // идентификатор контекста отображения int x, // x-координата int y, // y-координата POINT FAR* lppt); // указатель на структуру POINT
Для контекста отображения hdc эта функция устанавливает текущую позицию пера, равную (x,y). В структуру типа POINT, на которую указывает параметр lppt, после возврата из функции будут записаны старые координаты пера.
Функция MoveToEx возвращает TRUE при нормальном завершении или FALSE при ошибке.
Чтобы узнать текущую позицию пера, приложение может использовать функцию GetCurrentPositionEx : BOOL WINAPI GetCurrentPositionEx(HDC hdc, POINT FAR* lppt);
После вызова этой функции текущая позиция пера будет записана в структуру типа POINT, на которую указывает параметр lppt. Функция GetCurrentPositionEx возвращает TRUE при нормальном завершении или FALSE при ошибке.
Установка начальных координат кисти
Установка начальных координат кисти
Начальные координаты кисти (brush origin ) - это атрибут контекста отображения. Он используются для определения координат точки внутри кисти, которая будет служить начальной при закраске внутренней области фигуры или окна. По умолчанию используются координаты (0,0), соответствующие верхнему левому углу кисти (в системе координат, выбранной в контекст отображения по умолчанию).
Если кисть используется для закраски внутренней области окна, верхний левый угол изображения кисти совмещается с верхним левым углом этой области. Затем изображение кисти многократно повторяется с шагом 8 пикселов.
При закраске фигур начальное расположение кисти привязывается не к фигуре, а по-прежнему к верхнему левому углу внутренней области окна. Поэтому при закраске, например, прямоугольника, верхний левый угол кисти может не совпадать с верхним левым углом прямоугольника.
Приложение может изменить начальные координаты кисти (сдвинуть кисть) при помощи функций SetBrushOrg и UnrealizeObject.
Прежде всего нужно вызвать функцию UnrealizeObject , передав ей в качестве параметра идентификатор сдвигаемой кисти (только если это не встроенная кисть): BOOL WINAPI UnrealizeObject(HGDIOBJ hbrush);
В этом случае система сбросит координаты кисти после выбора ее в контекст отображения. После сброса надо установить новые значения координат кисти, вызвав функцию SetBrushOrg : DWORD WINAPI SetBrushOrg(HDC hdc, int nx, int ny);
Параметры nx и ny определяют новые значения для начальных координат кисти пикселах (от 0 до 7).
В завершении следует снова выбрать кисть в контекст отображения при помощи макрокоманды SelectBrush.
Библиотеки системного программиста" представляли собой
Введение
Предыдущие три тома " Библиотеки системного программиста" представляли собой краткое (!) введение в программирование для операционной системы Microsoft Windows. В них мы рассказали вам только о некоторых возможностях, не углубляясь в тонкости графического интерфейса и других подсистем. Мы также отложили рассказ о таких важных понятиях, как многооконный интерфейс MDI, протокол обмена данными между приложениями DDE, системе привязки и вставки объектов OLE.
В книге, которую вы сейчас держите в руках, мы расскажем о графическом интерфейсе GDI (Graphic Device Interface - интерфейс графических устройств), посредством которого графическая операционная система Windows выводит графику и текст на экран, принтер, плоттер и другие аналогичные устройства. В предыдущих томах мы уже упоминали о GDI, однако были рассмотрены только основные моменты, без понимания которых невозможно сделать ни одно приложение (разве что такое, которое не создает окон и ничего не выводит на экран или принтер).
Интерфейс GDI избавляет приложения Windows от необходимости учитывать многие (но не все) аппаратные особенности графических устройств вывода. Например, адресация видеопамяти выполняется по-разному в видеоадаптерах CGA, EGA, VGA, SVGA и, к тому же, структура видеопамяти сильно зависит от используемого режима (подробности вы можете найти третьем томе "Библиотеки системного программиста", который называется "Программирование видеоадаптеров CGA, EGA и VGA"). Однако приложения не работают непосредственно с видеопамятью. Для того чтобы нарисовать линию или написать строку текста, приложения вызывают ту или иную функцию интерфейса GDI, реализованного в виде DLL-библиотеки. Функции GDI также не работают с аппаратурой. Для выполнения нужной графической операции GDI вызывает драйвер устройства вывода, который "знает" о всех особенностях аппаратуры.
Таким образом, с помощью GDI приложения могут организовать вывод текста и графических изображений на некоторое логическое устройство вывода. Функции GDI и драйверы обеспечивают независимость приложений от аппаратуры, поэтому правильно созданное приложение Windows будет корректно работать с любыми видеоадаптерами и принтерами, как существующими на момент разработки приложения, так и с теми, которые появятся в будущем. В этом приложения Windows имеют большое преимущество над программами MS-DOS, вынужденными для повышения производительности работать непосредственно с регистрами видеоконтроллера и видеопамятью.
В первой главе вы познакомитесь с основными понятиями GDI, такими, как контекст отображения и его атрибуты, узнаете об инструментах, которые приложение Windows может использовать для рисования.
Вторая глава посвящена контексту отображения. Вы узнаете о типах контекста, научитесь получать и освобождать контекст отображения и контекст устройства. Мы расскажем вам об использовании режимов отображения, позволяющих работать с различными логическими системами координат. Отдельные разделы этой главы посвящены рисованию геометрических фигур и использованию областей.
В третьей главе мы расскажем о цвете и цветовых палитрах. Вы познакомитесь со статическими и системными цветами, научитесь создавать логическую палитру цветов и следить за изменениями системной палитры цветов. Все это позволит вам рисовать многоцветные изображения. Мы также расскажем об особенностях работы в режимах с высоким цветовым разрешением, таких как True Color.
Четвертая глава - об использовании битовых изображений. Вы узнаете о существовании различных типов битовых изображений и форматов bmp-файлов, содержащих изображения, научитесь рисовать битовые изображения, загруженные из bmp-файлов, а также создавать и использовать логическую палитру на базе таблицы цветов, расположенной в bmp-файле.
Пятая глава посвящена использованию шрифтов, в том числе масштабируемых шрифтов True Type. Будет рассмотрен механизм отображения шрифтов, который используется в процессе выделения шрифтов по запросу приложения. Мы расскажем о том, как выбрать нужный шрифт из числа установленных в системе, как получить различную информацию о шрифте, выбранном в контекст отображения. Несмотря на то что мы не привели полного описания функций GDI, предназначенных для работы с шрифтами True Type (оно занимает слишком много места), пользуясь нашей книгой вы сможете выполнять все основные операции, связанные с использованием шрифтов True Type. Если перед вами стоит задача разработки такого приложения, как редактор шрифтов True Type, вы сможете получить недостающую информацию из документации, которая поставляется вместе с Microsoft SDK for Windows 3.1.
В шестой главе рассмотрены средства, предназначенные для работы с принтером. Теперь ваши приложения смогут печатать текст и графику на любом принтере, установленном в системе. Мы научим вас пользоваться стандартными диалоговыми панелями, предназначенными для печати, выбора принтера и установки параметров принтера, опишем функции GDI, предназначенные для печати.
Мы привели исходные тексты приложений, демонстрирующих использование описанных средств GDI. Вы можете купить дискету, содержащую исходные тексты всех этих приложений.
Для трансляции исходных текстов приложений, приведенных в книге, мы пользовались системой разработки Borland Turbo C++ for Windows версии 3.1. Вы можете также использовать Borland C++ версий 3.1 или 4.0.
Чтобы вы смогли изучить приемы работы с палитрой и использовать режимы с высоким цветовым разрешением, в вашем компьютере должен быть установлен подходящий видеоадаптер и видеомонитор, способный работать в режимах SVGA. Обычный адаптер VGA в Windows предоставляет возможность работы всего лишь с 16 цветами, что недостаточно для многих графических приложений. Механизм цветовых палитр операционной системы Windows используется только в том случае, если в компьютере есть видеоадаптер SVGA, способный отображать 256 цветов. Лучше всего приобрести недорогой видеоадаптер с ускорителем для Windows, который может работать в режиме True Color (примерно 16 млн. цветов). Для отладки приложений, приведенных в этой книге, авторы использовали следующие видеоадаптеры: AVGA3 с видеопроцессором фирмы Cirrus Logic и объемом видеопамяти 1 Мбайт (акселератор для шины ISA стоимостью примерно 100 долларов), Orchid Fahrenheit VA-VLB (акселератор для шины VL-BUS), OAK VGA (адаптер SVGA с объемом видеопамяти 1 Мбайт без ускорителя).
Наш адрес E-mail: frolov@glas.apc.org
Вы можете присылать нам по этому адресу свои замечания и предложения по содержанию книг серий "Библиотека системного программиста" и "Персональный компьютер. Шаг за шагом". Мы их обязательно учтем при подготовке следующих изданий.
Авторы выражают благодарность сотрудникам АО "Диалог-МИФИ" Елене Виноградовой, Олегу Александровичу Голубеву, Наталье Дмитриевой, Оксане Кузьминовой, корректору Виктору Кустову. Появление этой книги стало возможным только благодаря напряженному труду всех этих людей. Мы также благодарим за помощь в работе над книгой Максима Синева и Сергея Ноженко.
Выбор кисти
Выбор кисти
Для закрашивания внутренней области замкнутых фигур вы можете использовать встроенные кисти, или кисти, созданные вашим приложением. Последние необходимо удалять после использования.
Выбор пера
Выбор пера
Для рисования линий приложения Windows могут выбрать одно из трех встроенных перьев, либо создать собственное перо.
Для выбора встроенного пера лучше всего воспользоваться макрокомандами GetStockPen и SelectPen , определенными в файле windowsx.h: #define GetStockPen(i) ((HPEN)GetStockObject(i)) #define SelectPen(hdc, hpen) \ ((HPEN)SelectObject((hdc), (HGDIOBJ)(HPEN)(hpen)))
Макрокоманда GetStockPen возвращает идентификатор встроенного пера, заданного параметром i. Вы можете выбрать для этого параметра одно из следующих значений:
Выбор режима фона
Выбор режима фона
Режим фона влияет на заполнение промежутков между штрихами и точками в штрих-пунктирных, штриховых и пунктирных линиях.
Напомним, что по умолчанию в контексте отображения установлен непрозрачный режим фона OPAQUE . В этом режиме промежутки закрашиваются цветом фона, определенным как атрибут контекста отображения. Приложение может установить прозрачный режим фона TRANSPARENT , в этом случае промежутки в линиях не будут закрашиваться (Рисунок 2.16).
Выбор режима рисования
Выбор режима рисования
Возвращаясь к обычной бумаге и карандашу, отметим, что в процессе рисования графит (или иной материал) переносится с острия карандаша на поверхность бумаги. Цвет полученной линии полностью соответствует цвету карандаша и не зависит от цвета бумаги. По умолчанию в контексте отображения выбран именно такой режим рисования , т. е. цвет рисуемой линии не зависит от цвета изображения, поверх которого рисуется линия.
Однако это не единственная возможность. При выборе соответствующего режима рисования цвет линии (на растровых устройствах вывода, таких, как экран монитора) может зависеть от цвета подложки, причем зависимость может быть достаточно сложная.
Для выбора режима рисования предназначена функция SetROP2 : int WINAPI SetROP2(HDC hdc, int fnDrawMode);
Параметр hdc предназначен для указания контекста отображения, в котором необходимо установить новый режим рисования, определяемый параметром fnDrawMode.
Функция SetROP2 возвращает код предыдущего режима рисования.
Процесс рисования на экране монитора заключается в выполнении логической операции над цветами точек экрана и цветами изображения. Ниже в таблице мы привели возможные значения для параметра fnDrawMode. Для каждого режима рисования в этой таблице есть формула, с использованием которой вычисляется результат, и краткое описание режима рисования. В формулах цвет пера обозначается буквой P, цвет подложки - D.
Выбор созданного шрифта в контекст отображения
Выбор созданного шрифта в контекст отображения
Если вы заполнили все нужные поля в структуре LOGFONT и затем передали адрес структуры функции CreateFontIndirect, эта функция вернет идентификатор шрифта. Вы должны выбрать шрифт с этим идентификатором в контекст отображения с помощью макрокоманды SelectFont (точно так же, как для встроенных шрифтов): hfontOldFont = SelectFont(hdc, hfont);
Как только в созданном шрифте отпадет необходимость, его следует удалить при помощи макрокоманды DeleteFont , предварительно выбрав в контекст отображения тот шрифт, который был выбран в него раньше: #define DeleteFont(hfont) \ DeleteObject((HGDIOBJ)(HFONT)(hfont))
Процесс отображения логического шрифта достаточно сложен. GDI сравнивает заданные в структуре LOGFONT параметры с параметрами различных шрифтов, которые можно использовать для данного устройства отображения, выбирая наиболее подходящий шрифт. Для сравнения используются пенальти (штрафные очки), которые имеют разные весовые коэффициенты. Выбирается тот шрифт, для которого сумма пенальти наименьшая.
Наиболее важное поле в структуре LOGFONT - поле lfCharSet. Если в этом поле будет установлено нулевое значение, будет выбран шрифт ANSI_CHARACTER, так как значение соответствующей ему константы равно нулю. Понятно, почему это поле самое важное - если приложение запрашивает шрифт OEM_CHARSET, оно предполагает использовать для вывода кодировку OEM. Если бы GDI предоставил приложению шрифт в кодировке ANSI, скорее всего, строку было бы невозможно прочесть. Если же в Windows нет ни одного шрифта с кодировкой OEM, приложение все равно получит какой-нибудь шрифт, однако результат вывода текста может оказаться неудовлетворительным.
Учтите, что растровые шрифты семейств Modern, Roman и Script, которые пришли из Windows версии 3.0, отмечены как имеющие кодировку OEM, хотя в действительности для этих шрифтов используется кодировка ANSI. Это сделано для того, чтобы в процессе выбора GDI вначале использовал масштабируемые шрифты перечисленных семейств, и только в крайнем случае остановил свой выбор на растровых шрифтах.
Следующее по важности поле в структуре LOGFONT - это поле lfPitchAndFamily. Оно имеет большое значение потому, что приложение, запрашивающее шрифт с фиксированной шириной букв, может работать неправильно, если ему будет выделен шрифт с переменной шириной букв.
Далее следует поле lfFaceName, а после него - поле lfFamily.
После сравнения всех описанных полей GDI сравнивает высоту букв шрифта (поле lfHeight), затем в сравнении принимают участие поля lfWidth, lfItalic, lfUnderline, lfStrikeOut.
Выбор встроенного шрифта
Выбор встроенного шрифта
По умолчанию в контекст отображения при его создании выбирается системный шрифт, основным (и почти единственным) преимуществом которого является то, что он всегда доступен. Системный шрифт не является масштабируемым, содержит буквы переменной ширины, не имеющие засечек, для него используется кодировка ANSI.
Однако в некоторых случаях вам может понадобиться шрифт с фиксированной шириной букв, или шрифт в кодировке OEM. Вы можете получить идентификатор одного из встроенных шрифтов при помощи макрокоманды GetStockFont , описанной в файле windowsx.h: #define GetStockFont(i) ((HFONT)GetStockObject(i))
В качестве единственного параметра этой макрокоманде следует передать идентификатор одного из встроенных шрифтов:
Загрузка bmpфайла и проверка заголовков
Загрузка bmp-файла и проверка заголовков
Вы можете загрузить в оперативную память весь bmp-файл сразу или вначале только заголовки, а затем таблицу цветов и биты изображений. В приложении BMPINFO, рисующем изображения DIB в своем окне, мы использовали первый способ, отведя для загрузки bmp-файла один сплошной блок глобальной памяти.
Составляя программу чтения bmp-файла в память, не следует забывать о том, что размер файла, а следовательно и размер нужного для его загрузки блока памяти, практически всегда превышает 64 Кбайт. Поэтому для чтения такого файла лучше всего использовать функцию _hread , позволяющую прочитать сразу весь файл в один блок памяти любого (теоретически) размера.: _hread(hfDIBFile, lpBuf, *dwFileSize);
Мы уже пользовались этой функцией для перекодировки файла из OEM в ANSI.
Прочитав файл в память, следует убедиться, что его первые два байта содержат значение 0x4d42 ("BM"). Если это так, нужно определить формат bmp-файла. Для этого следует проанализировать содержимое поля biSize, расположенное сразу после заголовка BITMAPFILEHEADER. Для файлов в формате Windows в этом поле должно быть значение 40, что соответствует размеру структуры BITMAPINFOHEADER. Для файлов в формате Presentation Manager в этом поле должно находиться значение 12 (размер структуры BITMAPCOREHEADER).
Ваше приложение может отвергнуть файл в формате Presentation Manager, и это не будет большим недостатком для приложения Windows. В случае необходимости bmp-файлы Presentation Manager могут быть преобразованы в формат Windows, например, с помощью приложения Paintbrush.
Убедившись в том, что вы загрузили bmp-файл в формате Windows, следует проверить содержимое полей структуры BITMAPINFOHEADER.
Следует проверить поля biPlanes, biBitCount и biCompression. Вы можете использовать для проверки следующие критерии:
Загрузка изображений из ресурсов приложения
Загрузка изображений из ресурсов приложения
Самый простой способ использования битовых изображений в приложениях Windows заключается в том, что изображение создается графическим редактором в виде bmp-файла и описывается в файле определения ресурсов приложения при помощи оператора BITMAP: LOGO BITMAP mylogo.bmp
Созданное таким образом битовое изображение можно загрузить в память при помощи функции LoadBitmap : HBITMAP WINAPI LoadBitmap(HINSTANCE hinst, LPCSTR lpszBitmap);
Параметр hinst определяет идентификатор копии приложения, из ресурсов которого нужно загрузить изображение. Идентификатор ресурса изображения задан параметром lpszBitmap. Функция LoadBitmap возвращает идентификатор загруженного изображения или NULL при ошибке.
После использования приложение должно удалить битовое изображение. Для этого лучше всего воспользоваться макрокомандой DeleteBitmap , описанной в файле windowsx.h следующим образом: #define DeleteBitmap(hbm) \ DeleteObject((HGDIOBJ)(HBITMAP)(hbm))
В качестве параметра этой макрокоманде нужно передать идентификатор удаляемого изображения.
Приложение может определить параметры загруженного изображения, вызвав функцию GetObject : int WINAPI GetObject( HGDIOBJ hgdiobj, // идентификатор объекта int cbBuffer, // размер буфера void FAR* lpvObject); // адрес буфера
С помощью этой функции можно получить разнообразную информацию об объектах GDI, таких, как логические перья, кисти, шрифты или битовые изображения.
Для нас интересно использование этой функции с целью получения параметров изображения. Идентификатор изображения должен передаваться через параметр hgdiobj. Параметр lpvObject должен указывать на структуру типа BITMAP, в которую будут записаны сведения об изображении. Через параметр cbBuffer следует передать размер структуры BITMAP: BITMAP bm; HBITMAP hBitmap; GetObject(hBitmap, sizeof(BITMAP), (LPSTR) &bm);
Структура BITMAP и указатели на нее описаны в файле windows.h: typedef struct tagBITMAP { int bmType; int bmWidth; int bmHeight; int bmWidthBytes; BYTE bmPlanes; BYTE bmBitsPixel; void FAR* bmBits; } BITMAP; typedef BITMAP* PBITMAP; typedef BITMAP NEAR* NPBITMAP; typedef BITMAP FAR* LPBITMAP;
Опишем назначение отдельных полей этой структуры.
Закрашивание области
Закрашивание области
Для закрашивания области кистью, выбранной в контекст отображения, предназначена функция PaintRgn : BOOL WINAPI PaintRgn(HDC hdc, HRGN hrgn);
Функция FillRgn также закрашивает область, но, в отличие от функции PaintRgn, эта функция использует кисть, идентификатор которой передается ей в качестве параметра hbrush: BOOL WINAPI FillRgn(HDC hdc, HRGN hrgn, HBRUSH hbrush);
С помощью функции FrameRgn вы можете обвести заданную область (закрасить ее границу), используя кисть hbrush: BOOL WINAPI FrameRgn(HDC hdc, HRGN hrgn, HBRUSH hbrush, int nWidth, int nHeight);
Параметры nWidth и nHeight определяют, соответственно, ширину и высоту кисти в пикселах, используемой для рисования границы.
Функция InvertRgn инвертирует цвета в указанной области: BOOL WINAPI InvertRgn(HDC hdc, HRGN hrgn);
Все эти функции возвращают TRUE при успешном завершении или FALSE при ошибке.
Графический редактор битовых изображений Paint Brush, который поставляется вместе с операционной системой Windows, умеет закрашивать внутренние области замкнутых фигур. Для закраски вам достаточно, находясь в соответствующем режиме редактора, указать мышью любую точку внутри фигуры.
Для реализации описанной выше операции в программном интерфейсе GDI предусмотрены функции FloodFill и ExtFloodFill.
Для функции FloodFill необходимо указать идентификатор контекста отображения hdc, координаты точки nX и nY, а также цвет контура clrref, ограничивающего область: BOOL WINAPI FloodFill(HDC hdc, int nX, int nY, COLORREF clrref);
Функция возвращает TRUE при успешном завершении или FALSE при ошибке (ошибка возникает в том случае, когда указанная точка имеет цвет clrref или она лежит вне области ограничения данного контекста отображения).
Для закраски используется кисть, выбранная в контекст отображения.
Функция ExtFloodFill аналогична функции FloodFill: BOOL WINAPI ExtFloodFill(HDC hdc, int nX, int nY, COLORREF clrref, UINT fuFillType);
Эта функция имеет дополнительный параметр fuFillType, определяющий способ закраски области. Параметр может принимать значения FLOODFILLBORDER или FLOODFILLSURFACE . В первом случае закрашивается внутренняя область фигуры, ограниченная контуром, имеющим цвет clrref (как и при использовании функции FloodFill). Во втором случае закрашивается вся область, имеющая цвет clrref.
Функция ExtFloodFill возвращает TRUE при успешном завершении или FALSE при ошибке. Если значение параметра fuFillType равно FLOODFILLBORDER, ошибка может возникнуть из-за тех же причин, что и при выполнении функции FloodFill. Если же значение параметра fuFillType равно FLOODFILLSURFACE, ошибка может возникнуть из-за того, что цвет точки (nX,nY) не равен clrref.
Закрашивание внутренней области окна
Закрашивание внутренней области окна
Напомним, что кисть можно использовать еще и для закрашивания внутренней области окна . Для этого идентификатор кисти следует записать в поле hbrBackground структуры типа WNDCLASS перед регистрацией класса окна: wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);