Работа с Visual Studio.Net

         

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

Косметические перья работают значительно быстрее, чем другие, но это имеет значение только для сложных рисунков. Геометрическое перо может иметь любую толщину и любые атрибуты Windows-кисти (dither и pattern). Введем дополнения, которые позволят исследовать свойства геометрического пера. В число локальных переменных функции WndProc введите новые сущности:

//====== Узоры штрихов (hatch) кисти, на основе

//====== которых будет основано перо

static UINT uHatch[] =

{


HS_BDIAGONAL, HS_CROSS, HS_DIAGCROSS,

HS_FDIAGONAL, HS_HORIZONTAL, HS_VERTICAL

};

//===== Строки текста для пояснений

static string brush[] =

{

"HS_BDIAGONAL", "HS_CROSS", "HS_DIAGCROSS",

"HS_FDIAGONAL", "HS_HORIZONTAL", "HS_VERTICAL"

};

Вставьте следующий код в ветвь WM_PAINT перед вызовом EndPaint. Этот фрагмент по структуре такой же, как и предыдущий, но здесь мы создаем перо, используя штриховую (hatched) кисть. Запустите и проверьте, что получилось. Попробуйте объяснить, почему линия со штрихом типа HS_HORIZONTAL невидима. Замените строку

LineTo(hdc, iXMax, iYPos);

на

LineTo(hdc, iXMax, iYPos + 3);

и запустите вновь. Теперь линия должна быть видна. Найдите объяснение и попробуйте обойтись без последнего изменения кода, то есть уберите +3:

//======== геометричесое перо

Ib.lbStyle = BS_HATCHED; // Узорная кисть

sText = "Стили на основе кисти (Geometric pen)";

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 ());

nLines = sizeof(brush)/sizeof(brush[0]);

for (i = 0; i < nLines; i ++ )

{

//======= Выбираем узор штриха кисти

Ib.lbHatch = uHatch[i];

//== Создаем на его основе перо тощиной 5 пиксел

HPEN hp = ExtCreatePen(PS_GEOMETRIC, 5, Sib,0,0);

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, brush[i].c_str(), brush[i].size());

}

Геометрическое перо может быть создано на основе заданного пользователем или программистом узора (PS_USERSTYLE). Узор задается с помощью массива переменных типа DWORD. Элементы массива определяют циклический алгоритм закраски линии по схеме «играем — не играем». Например, массив DWORD а [ ] = { 2,3,4 } определяет линию, у которой 2 пиксела закрашены, 3 — не закрашены, 4 — закрашены. Затем цикл (2,3,4) повторяется. Для моделирования этой возможности введите в WndProc еще один двухмерный массив (так как линия будет не одна):

//======= три узора геометрического пера

static DWORD dwUser[3][4] =

{

{ 8, 3, 3, 3),

{ 3, 3, 3, 3),

(15, 4, 3, 4}

};

Затем добавьте вслед за фрагментом, моделирующим штриховую линию, следующий код:

//======= Геометричесое перо (user-defined)

Ib.lbStyle - BS_SOLID;

sText = "Стили на основе узора (Geometric pen)";

GetTextExtentPoint(hdc,sText.c_str(), sText.size(),SszText);

iYPos += 2 * szText.cy;

iXPos = iXCenter - szText.cx/2;

TextOutfhdc, iXPos, iYPos,

sText.c_str(), sText .size () } ,

nLines = sizeof(dwUser)/sizeof(dwUser[0]) ;

//====== Перебираем узоры пользователя

//====== (строки массива dwUser)

for (i = 0; i < nLines; i++)

{

DWORD dw = PS_GEOMETRIC | PS_USERSTYLE | PS_ENDCAP_FLAT;

HPEN hp = ExtCreatePen(dw, i+2, Sib, 4, dwUser[i]);

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, user[i].c_str(), user[i].size());

}

Запустите и проверьте результат. Здесь следует отметить, что узор имеет возможность развиться (разогнаться) только на достаточно большом промежутке между точками. Для вывода графиков функциональных зависимостей он, к сожалению, не пригоден, так как графики имеют большое количество точек. Точки расположены тесно, а узор начинается заново после каждой пары точек. Как ни странно, косметическое перо толщиной в 1 пиксел выдерживает подобное испытание и его можно использовать для графиков функций.

Содержание раздела