visual c++中的画刷类CBrush使用实例

来源:互联网 发布:mac sed命令应用 编辑:程序博客网 时间:2024/06/04 19:05

画刷类CBrush
利用画笔可以画图形的边框,而用画刷就可以在图形内着色。大多数的GDI绘图函数既使用画笔又使用画刷,它们用画笔绘制各种图形的周边,而用画刷填充图形,因而可以用一种颜色和风格去设置画笔,而用另一种颜色和风格去设定画刷,通过一次函数调用就可以绘制出形状复杂的图形。
画刷是由CBrush类管理的,创建画刷有两种方法:一种是调用构造函数,另一种是调用相关的成员函数。
1.CBrush的构造函数
CBrush类的结构函数定义如下:
① CBrush( );
② CBrush( COLORREF crColor );
throw( CResourceException );
③ CBrush( int nIndex, COLORREF crColor );
throw( CResourceException );
④ CBrush( CBitmap* pBitmap );
throw( CResourceException );
参数说明:
crColor:设定画笔颜色。
NIndex:如果画刷是带花纹的,则该参数设定画刷的花纹类型,其取值如下:
         HS_BDIAGONAL:为左高右低的45度斜花纹。
         HS_CROSS:为由水平线和垂直线构成的方格花纹。
         HS_DIAGCROSS:为斜45度方格花纹。
         HS_FIDAGONAL:为右高左低的45度斜花纹。
         HS_HORIZONTAL:为水平线花纹。
         HS_VERTICAL:为垂直线花纹。
PBitmap:为CBitmap类的指针,用于指定填充时所使用的位图。
2.CBrush提供的创建画笔的成员函数
除了构造函数,CBrush还提供了6个创建画刷的成员函数:
BOOL CreateSolidBrush( COLORREF crColor )
该函数创建一个实填充的画刷。crColor为填充色。
BOOL CreateHatchBrush( int nIndex, COLORREF crColor )
该函数创建一个带花纹的画刷,nIndex为花纹类型,crColor为画刷颜色。
BOOL CreateBrushIndirect( const LOGBRUSH* lpLogBrush )
调用该函数可以通过LOGBRUSH结构生成一个画刷,LOGBRUSH结构的定义如下:
typedef struct tag LOGBRUSH {
UINT    lbStyle;
COLORREF      lbColor;
LONG   lbHatch;
} LOGBRUSH;
其中lbStyle指定的是画刷的类型,lbColor指定画刷的颜色,lbHatch指定的是画刷的花纹类型。
BOOL CreatePatternBrush( CBitmap* pBitmap )
创建一个使用位图填充的画刷,画刷的位图由pBitmap指定,位图大小必须8×8。
BOOL CreateDIBPatternBrush( HGLOBAL hPackedDIB, UINT nUsage )
BOOL CreateDIBPatternBrush( const void* lpPackedDIB, UINT nUsage )
创建使用DIB(设备无关位图)的画刷,其中hPackedDIB指向存储位图数据的内存块的地址,lpPackedDIB指向DIB位图数据的指针,nUsage用于设定调色板的属性。
BOOL CreateSysColorBrush( int nIndex )
该函数设定带有系统色的画刷,nIndex指定为画刷的花纹类型。
3.CBrush演示实例
(1)创建一个基于对话框的应用程序BrushDemo。
(2)向CBrushDemoDlg类中添加一个成员函数RunBrush(),它主要完成在指定区域绘制指定矩形的功能。添加RunBrush()成员函数的代码如下:
void CBrushDemoDlg::RunBrush(CPaintDC* dc,CRect rect, COLORREF col,CString text, LONG lbHatch)
{
CBrush cbrush;
CBrush* pBrush; //旧笔刷
cbrush.CreateHatchBrush(lbHatch,col);    //建立带花纹笔刷
dc->DrawText(text,&rect,DT_CENTER|DT_WORDBREAK);    //写提示文本
rect.top=rect.top+40;       //调整矩形区域
pBrush=dc->SelectObject(&cbrush);     //载入笔刷
dc->Rectangle(&rect);    //绘制矩形
dc->SelectObject(pBrush);    //恢复笔刷
cbrush.DeleteObject();
pBrush->DeleteObject();
}
(3)找到CBrushDemoDlg::OnDrow()函数,修改这个函数的内容:
void CBrushDemoDlg::OnPaint()
{
CPaintDC dc(this);
//背景填充为白色
CRect rect,fillrect;
CBrush brush;
brush.CreateSolidBrush(RGB(255,255,255));
this->GetClientRect(&rect);
dc.FillRect(&rect,&brush);    //用FillRect成员函数利用笔刷填充指定区域
brush.DeleteObject();
//画矩形区域
int left=10;
const int MAX=6;
fillrect.top=rect.top+10;
fillrect.bottom=rect.bottom-10;
long style[MAX]={HS_BDIAGONAL,HS_CROSS,HS_DIAGCROSS,\
HS_FDIAGONAL,HS_HORIZONTAL,HS_VERTICAL};            //笔刷的花纹类型

CString text[MAX]={"剖 面 线\n从左到右","网 格 线",\
"斜网格线","剖 面 线\n从右到左","水 平 线","垂 直线"};        //提示文本
for(int i=0;i<MAX;i++)
{
fillrect.left=left;
fillrect.right=fillrect.left+100;
left=fillrect.right+10;
//利用"RGB((i+1)*255/MAX,0,(MAX-i)*255/MAX)"产生不同的颜色
RunBrush(&dc,fillrect,RGB((i+1)*255/MAX,0,(MAX-i)*255/MAX),text[i],style[i]);
}
}

1.新建BrushDemo

在ChildView 中声明函数 void RunBrush(CPaintDC* dc,CRect rect, COLORREF col,CString text, LONG lbHatch);

实现如下:

先创建(新)画刷和旧画刷指针,旧画刷用来保存(新)画刷应用之前,画刷的属性

CBrush cbrush; //(新)

CBrush* pOldBrush; //(旧) 这里创建的是指针 上面是变量 原因稍后介绍

现在给(新)画刷 创建 花纹 和 画刷前景颜色 , 用到函数如下:

HBRUSH CreateHatchBrush(

int fnStyle , // hatch style 花纹样式

COLORREF clrref // foreground color

);

cbrush.CreateHatchBrush(lbHatch,col);

现在画刷准备好了, 在绘制之前 我们为将要绘制的矩形准备标题

用DrawText()函数来做, 原型如下:

int DrawText(

const CString&  str, // 所显示的标题文字

LPRECT lpRect, //要把文字绘制到这个矩形区域

UINT nFormat); // 文本的格式化方法

如果绘制成功,将返回文本的高度

dc->DrawText(text,&Rect,DT_CENTER|DT_WORDBREAK);

这里选择的格式化方式:居中对齐文本,如果这个字在这个矩形的一行中容不下,则自动断开,在下一行中显示出来

 

到目前为止, 准备了新旧画刷,建好了新画刷的花纹和颜色,同时为将要绘制的矩形绘制好了标题,下面进入矩形的绘制部分

矩形绘制分两部分, 画笔和画刷 , 画笔用来绘制矩形的边框, 画刷用来填充矩形内部的颜色

要绘制矩形,我们可以创建一只画笔,设定为白色

CPen penwhite;

penwhite.CreatePen(PS_SOLID,RGB(255,255,255));

在使用这个新画刷之前,我们将当前画刷先保存好,同时将创建好的白色画笔载入到当前内存DC中

CPen* pOldPen = dc->SelectObject(&penwhite);

 

设置将会绘制的矩形离窗体上部的高度

rect.top = rect.top+50;

保存好当前画刷,并载入新画刷

pOldBrush=dc->SelectObject(&cbrush);

现在绘制一个白色边界,内部填充为了col颜色的矩形

dc->Rectangle(&rect);

绘制完成之后,我们重新载入之前保存的画笔和画刷

dc->SelectObject(pOldBrush);

dc->SelectObejct(pOldPen);

绘制完的画刷和画笔对象不再需要,就应该释放掉, 以免造成内存泄露

cbrush.DeleteObject();

pOldBrush->DeleteObject();

好了到目前位置 RunBrush() 实现完毕了

 

为了能绘制成功, 还需要为ChildView类添加一个 WM_PAINT 消息响应函数OnPaint()

OnPaint()实现如下:

首先创建一个绘制矩形框对象 rect, 然后再创建一个用来填充矩形框的对象fillrect

在绘制矩形之前,我们把当前ChildView 客服区域用白色填充, 既然是填充就要用的画刷

CBrush brush;

brush.CreateSolidBrush(RGB(255,255,255)); // 创建画刷

this->GetClientRect(&rect); // 获取当前客服区域

dc.FillRect(&rect,&brush);// 在获取的矩形区域中填充

用完之后 同样要销毁掉brush对象

brush.DeleteObject();

 

先设置矩形绘制最左边的边界

int left = 150;

总共要绘制6个矩形, 采用循环来完成, 设置一个常量

const int MAX =6;

填充区域与获取的客户区域顶部的距离 以及底部的距离设置

fillrect.top= rect.top+10;

fillrect.bottom=rect.bottom-10;

设置一个花纹数组和每个花纹对于的标题

long style[MAX]={HS_BDIAGONAL,HS_CROSS,HS_DIAGCROSS,HS_FDIAGONAL,HS_HORIZONTAL,HS_VERTICAL};

 CString text[MAX]={L"剖面线\n\n从左到右\n",L"网格线",L"斜网格线",L"剖面线\n\n从右到左\n",L"水平线",L"垂直线"};

 

用for来实现6个矩形的绘制

for(int i=0;i<MAX,i++)

    fillrect.left=left;// 设置左边的开始边界

    fillrect.right=fillrect.left+100;//设置画的宽度

left=fillrect.right+10;//重新设置左边的边界

绘制

RunBrush(&dc,fillrect,RGB((i+1)*255/MAX,0,(MAX-i)*255/MAX),text[i],style[i]);

 

 

运行结果: