Косметическое перо
Комментарии в тексте поясняют суть происходящего. Отметьте, что здесь применена стандартная тактика работы с ресурсами GDI, которая состоит из последовательности следующих шагов:
- создаем свой инструмент;
- выбираем его в контекст устройства (SelectObject) и одновременно запоминаем тот инструмент, который используется в контексте в настоящий момент;
- рисуем с помощью нашего инструмента;
- возвращаем в контекст прежний инструмент;
- освобождаем память, занимаемую нашим инструментом.
Так как система работает с ресурсами GDI динамически, то нарушение этой тактики может привести к недостатку памяти и непредсказуемому поведению приложения. Перед тем как запустить проект, попробуйте ответить на вопросы:
- Будет ли изменяться цвет линий при пользовании стандартным диалогом, который мы уже реализовали?
- Будет ли изменяться цвет текста при тех же условиях?
Теперь запустите приложение и протестируйте его, изменяя размеры окна и пользуясь диалогом. Как вы узнали из документации, косметическое перо может иметь толщину только в 1 пиксел. Если косметическое перо имеет еще один атрибут PS_ALTERNATE, то каждый второй пиксел линии пропускается (не выводится) и создается иллюзия, что перо стало тоньше, чем 1 пиксел. Опробуем эту возможность в нашем примере. Для этого введите в функцию WndProc еще один локальный массив подсказок.
static string ALT[ ] = {"PS_ALTERNATE", "PS_COSMETIC" };
Вставьте следующий код в ветвь WM_PAINT перед вызовом EndPaint, затем запустите и проверьте результат:
//======= Косметическое перо (ALTernate – solid) Ib.lbStyle = BS_SOLID; sText = "Косметическое перо ALTernate или solid"; GetTextExtentPoint(hdc,sText.c_str(), sText.size(),SszText); iYPos += 2 * szText.cy; iXPos = iXCenter – szText.cx/2; TextOut(hdc, iXPos, iYPos, sText.c_str(), sText.size()); for (i = 0; i < 2; i+ +) { DWORD dw = i? PS_COSMETIC: PS_COSMETIC I PS_ALTERNATE; HPEN hp = ExtCreatePen(dw, 1, &lb, 0, NULL); HPEN hOld = (HPEN)SelectObject(hdc, hp); iYPos += szText.cy; MoveToEx(hdc, 10, iYPos, NULL); LineTo(hdc, iXMax,iYPos); SelectObject(hdc, hold); DeleteObject(hp); TextOut(hdc, 10, iYPos, ALT[i].c str(), ALT [i] .size ());