Иллюстрированный самоучитель по Visual Studio .NET

Косметическое перо

Комментарии в тексте поясняют суть происходящего. Отметьте, что здесь применена стандартная тактика работы с ресурсами 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 ());
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.