【Demo 0008】绘图对象–画刷
前文中我们讲述了GDI绘图对象之一画笔, 今天继续学习绘图对象之二画刷,画刷通常用于将特定的颜色或图案填充到封闭式区域的图形中,封闭式图形有矩形,圆形,多边形, 路径等; 它和画笔一样也具备自身的属性: 样式(风格,图案)和行为.
一、创建画刷
GDI 提供四种方法创建画刷:
1. HBRUSH CreateSolidBrush(COLORREF crColor)
crColor -- 画刷的颜色
创建特定颜色实心风格的画刷
{
InflateRect(&rtGrid, -5, -5);
int nSavedDC = SaveDC(hDC);
HBRUSH hBrush = CreateSolidBrush(RGB(255, 128, 128));
HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, hBrush);
SetBkMode(hDC, TRANSPARENT);
Rectangle(hDC, rtGrid.left, rtGrid.top, rtGrid.right, rtGrid.bottom);
DrawText(hDC, _T("To Paint this rectangle with Solid Brush"), -1, &rtGrid, DT_VCENTER|DT_CENTER|DT_SINGLELINE);
SelectObject(hDC, hOldBrush);
RestoreDC(hDC, nSavedDC);
return;
}
2. HBRUSH CreatePatternBrush(HBITMAP hBitmap)
hBitmap -- 位图
创建指定位图的画刷,若位图小于绘图区时位图将平铺到整个区域;
void CDemoWnd::DemoPatternBrush(HDC hDC, RECT& rtGrid)
{
int nSavedDC = SaveDC(hDC);
HBITMAP hBmp = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_PATTERN));
HBRUSH hBrush = CreatePatternBrush(hBmp);
HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, hBrush);
InflateRect(&rtGrid, -5, -5);
Rectangle(hDC, rtGrid.left, rtGrid.top, rtGrid.right, rtGrid.bottom);
SetBkColor(hDC, RGB(255, 0, 255));
DrawText(hDC, _T("To Paint this rectangle with Pattern Brush"), -1, &rtGrid, DT_VCENTER|DT_CENTER|DT_SINGLELINE);
SelectObject(hDC, hOldBrush);
DeleteObject(hBmp);
DeleteObject(hBrush);
RestoreDC(hDC, nSavedDC);
return;
}
3. HBRUSH CreateHatchBrush(int nStyle, COLORREF crColor)
nStyle -- 画刷风格
HS_BDIAGONAL 45-degree upward left-to-right hatch
HS_CROSS Horizontal and vertical crosshatch
HS_DIAGCROSS 45-degree crosshatch
HS_FDIAGONAL 45-degree downward left-to-right hatch
HS_HORIZONTAL Horizontal hatch
HS_VERTICAL Vertical hatch
crColor -- 画刷颜色
创建特定风格及颜色的画笔
void CDemoWnd::DemoHatchBrush(HDC hDC, RECT& rtGrid)
{
int nSavedDC = SaveDC(hDC);
const int nHatchType[] = {
HS_BDIAGONAL, // 45-degree upward left-to-right hatch
HS_CROSS, // Horizontal and vertical crosshatch
HS_DIAGCROSS, // 45-degree crosshatch
HS_FDIAGONAL, // 45-degree downward left-to-right hatch
HS_HORIZONTAL, // Horizontal hatch
HS_VERTICAL // Vertical hatch
};
InflateRect(&rtGrid, -5, -5);
const int nBlank = 10;
const int nBlockCount = sizeof(nHatchType) / sizeof(*nHatchType);
const int nBlockWidth = (rtGrid.right - rtGrid.left) / nBlockCount;
for (int ii = 0; ii < nBlockCount; ii++)
{
HBRUSH hBrush = CreateHatchBrush(nHatchType[ii], RGB(30, 33, 120));
HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, hBrush);
int nLeft = rtGrid.left + ii * nBlockWidth;
Rectangle(hDC, nLeft + nBlank, rtGrid.top, nLeft + nBlockWidth, rtGrid.bottom);
SelectObject(hDC, hOldBrush);
DeleteObject(hBrush);
}
SetBkColor(hDC, RGB(128, 128, 0));
DrawText(hDC, _T("To Paint this rectangle with Hatch Brush"), -1, &rtGrid, DT_VCENTER|DT_CENTER|DT_SINGLELINE);
RestoreDC(hDC, nSavedDC);
}
4. HBRUSH CreateBrushIndirect(LOGBRUSH LogBrush)
LogBrush – 逻辑画刷
typedef struct tagLOGBRUSH { UINT lbStyle; COLORREF lbColor; LONG lbHatch; } LOGBRUSH, *PLOGBRUSH;
此方法除可创建以上3种画刷风格外还支持其他风格和样式(LOGBRUSH 功能比较使用比较复杂详见MSDN
void CDemoWnd::DemoKindOfBrush(HDC hDC, RECT& rtGrid)
{
int nSavedDC = SaveDC(hDC);
InflateRect(&rtGrid, -5, -5);
const int nBlockCount = 4;
const int nBlank = 10;
const int nBlockW = (rtGrid.right - rtGrid.left) / nBlockCount;
RECT rtBlocks[nBlockCount];
for (int ii = 0; ii < nBlockCount; ii++)
{
int nLeft = rtGrid.left + ii * nBlockW;
SetRect(&rtBlocks[ii], nLeft + ((0 != ii) ? nBlank : 0), rtGrid.top, nLeft + nBlockW, rtGrid.bottom);
}
LOGBRUSH LogBrush[nBlockCount];
//--: Solid Brush
LogBrush[0].lbStyle = BS_SOLID;
LogBrush[0].lbColor = RGB(234, 233, 21);
LogBrush[0].lbHatch = 0;
//--: Pattern Brush
LogBrush[1].lbStyle = BS_PATTERN;
LogBrush[1].lbColor = DIB_RGB_COLORS;
LogBrush[1].lbHatch = (ULONG_PTR)LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_PATTERN));
//--: Hatch Brush
LogBrush[2].lbStyle = BS_HATCHED;
LogBrush[2].lbColor = RGB(234, 233, 21);
LogBrush[2].lbHatch = HS_CROSS;
//--: Transparent Brush
LogBrush[3].lbStyle = BS_NULL;
LogBrush[3].lbColor = 0;
LogBrush[3].lbHatch = 0;
for (int ii = 0; ii < nBlockCount; ii++)
{
HBRUSH hBrush = CreateBrushIndirect(&LogBrush[ii]);
HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, hBrush);
Rectangle(hDC, rtBlocks[ii].left, rtBlocks[ii].top, rtBlocks[ii].right, rtBlocks[ii].bottom);
SelectObject(hDC, hOldBrush);
DeleteObject(hBrush);
}
DeleteObject((HBITMAP)LogBrush[1].lbHatch);
SetBkColor(hDC, RGB(128, 128, 128));
DrawText(hDC, _T("To Paint this rectangle with a kind of brush"), -1, &rtGrid, DT_VCENTER|DT_CENTER|DT_SINGLELINE);
RestoreDC(hDC, nSavedDC);
return;
}
二、画刷的使用
画刷与其他的GDI绘图对象一样, 创建画刷后都须先通过SelectObject函数选入设备DC中,当GDI在当前设备环境中绘制图形时它将使用被选入的画刷进行喷绘.
HBRUSH hBrush = CreateSolidBrush(RGB(255, 128, 128));
HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, hBrush);
Rectangle(hDC, rtGrid.left, rtGrid.top, rtGrid.right, rtGrid.bottom);
SelectObject(hDC, hOldBrush);
三、常用方法
COLORREF SetDCBrushColor(HDC hDC, COLORREF crColor)
设置当前默认的画刷颜色,使用此函数前如画笔一样先将备用画刷选入设备环境中如: SelectObject(hDC, GetStockObject(DC_BRUSH));
注: 在本例中我们使用另外二个DC函数:
int SaveDC(HDC ) 保存此函数调用前的DC设备环境,并返回保存的次数以备后期恢复
BOOL RestoreDC(HDC hDC, int nSavedDC) 恢复第几次保存的DC设备环境
通常使用时两函数都成对使用.