前文中我们讲述了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设备环境
通常使用时两函数都成对使用.