Перья
на основе растровых изображений
Последним испытанием
для геометрического пера будет произвольное bitmap-изображение. Если задать
BS_PATTERN в качестве стиля кисти, на основе которой создается перо, то линия
рисунка может иметь произвольный узор и толщину, что дает волю фантазии разработчика.
Однако сначала следует создать ресурс bitmap-изображения, загрузить его и задать
его описатель в поле IbHatch логической кисти. Для создания изображения:
- Перейдите в окно Resource
View.
- Раскройте узел дерева
под именем API.rc и убедитесь, что в дереве нет узла с именем Bitmap.
- Вызовите контекстное
меню на узле API.rc и дайте команду Add Resource.
- В диалоге Add Resource
выберите тип Bitmap и нажмите кнопку New.
- Откройте окно Properties
и в поле справа от текста ID задайте идентификатор IDB_PAT1 новому точечному
изображению.
- Измените размер изображения,
уменьшив его до 5x5. Используйте для этой цели элементами управления (resize
handles) рамки.
- Создайте произвольное
изображение с помощью контрастирующих цветов.
- В окне Resource View
вызовите контекстное меню на узле дерева IDВ_РАТ1 и выберите команду Insert
Copy.
- Измените язык копии на
тот, который поддерживается системой, например English (United States), иначе
не получится, и нажмите ОК.
- Теперь вы имеете копию
изображения с теми же размерами и идентификатором. Здесь удобно перевести
окно Properties в режим Floating или сдвинуть его нижнюю границу вверх. Измените
идентификатор нового изображения на юв_РАТ2 и, при желании, возвратите язык
ресурса.
- Измените узор второго
изображения и повторите пункты 7-10, задав идентификатор ЮВ_РАТЗ для третьего
изображения.
Возвратитесь
в окно API.CPP и введите в число локальных переменных функции wndProc новые
массивы:
//=====
Массив идентификаторов
bitmap
static
UINT nPatterns[] =
{
IDB_PAT1,
IDB_PAT2, IDB_PAT3
};
static
string bitmap!] =
{
"BS_PATTERN,
1", "BS_PATTERN, 2", "BS_PATTERN, 3"
);
Вслед за фрагментом,
моделирующим стиль PS_USERSTYLE , вставьте следующий код:
//=======
Геометричесое перо (bitmap)
Ib.lbStyle
= BS_PATTERN;
sText
= "Стили на основе bitmap-узора (Geometric pen)";
GetTextExtentPoint(hdc,sText.c_str(),
sText.size 0,SszText);
iYPos
+= 2 * szText.cy;
iXPos
= iXCenter - szText.cx/2;
TextOut(hdc,
iXPos, iYPos, sText.c_str(), sText. size () ) ;
nLines
= sizeof(nPatterns)/sizeof(nPatterns[0]);
for
(i =0; i < nLines; i++)
{
HBITMAP
hBmp;
hBmp
= LoadBitmap(GetModuleHandle(NULL), (char*)nPatterns[i]);
Ib.lbHatch
= long(hBmp);
HPEN
hp = ExtCreatePen(PS_GEOMETRIC, 5, &lb, 0, 0) ;
HPEN
hOld = (HPEN)SelectObject(hdc, hp) ;
iYPos
+= szText.cy;
MoveToEx(hdc,
10, iYPos, NULL);
LineTofhdc,
iXMax,iYPos);
SelectObject(hdc,
hOld);
DeleteObject(hp);
TextOut(hdc,
10, iYPos, bitmap[i].c_str(),
bitmap[i]
.size () ) ;
}
Запустите на
выполнение и проверьте результат. Вы должны получить окно, которое выглядит
так, как показано на рис. 3.3. Отметьте, что остались неисследованными еще несколько
возможностей по управлению пером — это стили типа PS_ENDCAP_* и PS_JOIN_*. Вы,
вероятно, захотите их исследовать самостоятельно. При этом можете использовать
уже надоевшую, но достаточно эффективную схему, которой мы пользуемся сейчас.
Рис. 3.3.
Стили пера в Win32
Теперь ответим
на один из вопросов, которые были заданы по ходу текста этой главы. Для того
чтобы изменился цвет текста, надо вставить вызов API-функции SetTextColor. И
сделать это надо в ветви обработки сообщения WM_PAINT перед вызовом функции
TextOut.
SetTextColor(hdc,
color) ;
Подведем итоги.
Наш пример иллюстрирует характерные особенности строения приложения, управляемого
событиями:
- оно должно состоять как
минимум из двух функций: winMain и регистрируемой оконной процедуры;
- последняя имеет вид отдельных
ветвей, обрабатывающих те команды пользователя или сообщения Windows, которые
выбрал разработчик;
- в более сложных случаях
для обработки событий, конечно же, необходимо предусмотреть множество отдельных
функций или модулей программы;
- приложения Win32, разработанные
по рассмотренной схеме, имеют то преимущество, что они не несут дополнительной
нагрузки в виде скрытого от ваших глаз каркаса приложения, поэтому дают очень
быстрый код;
- недостатком приложения
Win32 является то, что для их разработки необходимо ориентироваться в мире
из тысяч API-функций, вспомогательных структур, макросов и интерфейсов.