MFC之画刷绘图

前言


MFC提供了一个CBrush类,可以用来创建画刷对象,通过MSDN我们知道CBrush类的构造函数有以下三种:

CBrush(COLORREF crColor);             // CreateSolidBrush
CBrush(int nIndex, COLORREF crColor); // CreateHatchBrush
explicit CBrush(CBitmap* pBitmap);          // CreatePatternBrush
从入参来看,CBrush画图可以采用RGB颜色填充和位图填充两个方式,下面讨论以画刷填充一个矩形区域为例进行介绍。


背景知识:

     一个矩形可以由左上角和右下角两个点确定,我们在鼠标左键按下和弹起的两个事件中就有了这两个点位置消息,从而确定一个矩形区域,我们在OnLButtonUp和OnLBttonDown两个消息响应函数完成绘图。


在MFC中利用Crect类来构造矩形区域,其构造函数有以下几种:

CRect() throw();
// from left, top, right, and bottom
CRect(int l, int t, int r, int b) throw();
// copy constructor
CRect(const RECT& srcRect) throw();
// from a pointer to another rect
CRect(LPCRECT lpSrcRect) throw();
// from a point and size
CRect(POINT point, SIZE size) throw();
// from two points
CRect(POINT topLeft, POINT bottomRight) throw();

RGB颜色画图


RGB颜色画图代码如下:

//nFlags:Indicates whether the user pressed modifier keys(Alt,Shift,Ctrl..)
//point: specify current cursor the position when left button down
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    //保存起点位置
    m_ptOrigin = point;
    CView::OnLButtonDown(nFlags, point);
}

//nFlags:Indicates whether the user pressed modifier keys(Alt,Shift,Ctrl..)
//point: specify current cursor the position when left button up
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{	
	//红色画刷
	CBrush brush(RGB(255,0,0));
	//创建DC
    CClientDC dc(this);
	//直接用画笔填充矩形区域,不用将画笔选入DC
    dc.FillRect(CRect(m_ptOrigin, point), &brush);
	CView::OnLButtonUp(nFlags, point);
}
运行效果:



透明画刷


下面利用CDC类的Rectangle函数绘制一个矩形,Rectangle函数是利用当前的画刷完成矩形绘制,而默认的画刷是白色。因此利用Rectangle函数绘图也会存在相同的问题,即矩形交叠部分存在被覆盖的情况。

如果矩形区域内部是透明的,就可以解决这个问题,但是在CBrush类中不存在这个接口,可以利用GetStockObjec函数,这个函数可以获得一个黑色或白色等画刷句柄。从MSDN发现fnObject可以是NULL_BRUSH,该值就是空画刷的意思。

Draws a rectangle using the current pen. 
//GDI对象句柄,可以是pens, brushes, fonts, or palettes.
HGDIOBJ GetStockObject(int fnObject// stock object type);
具体代码实现如下:

//nFlags:Indicates whether the user pressed modifier keys(Alt,Shift,Ctrl..)
//point: specify current cursor the position when left button up
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{	
	CClientDC dc(this);
	//获得空画刷指针,利用FromHandle函数完成句柄和指针的转换
	CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));   
	//空画刷载入设备描述表
	CBrush* pOldBrush = dc.SelectObject(pBrush);
	//虚线画笔
	CPen pen(PS_DASH,1,RGB(255,0,0));
	CPen* pOldPen = dc.SelectObject(&pen);

	//绘制矩形
	dc.Rectangle(CRect(m_ptOrigin, point));

	//还原画笔和画刷
	dc.SelectObject(pOldBrush);
	dc.SelectObject(pOldPen);
	CView::OnLButtonUp(nFlags, point);
}

运行效果:



位图画刷


在CBrush的的构造函数中,我们可以传入CBitmap指针参数,完成画刷的构造,其函数声明如下:

explicit CBrush(CBitmap* pBitmap);    // CreatePatternBrush
该构造函数要求传入一个CBitmap指针,我们可以定义一个CBitmap对象,来完成CBrush的创建。然而,我们在创建一个CBitmap对象时,还需要完成位图的初始化,才能生成有效的CBitmap对象,CBitmap对象的初始化函数有CreateCompatibleBitmap、LoadBitmap、LoadMappedBitmap等,

这里利用LoadBitmap对象完成初始化工作,函数声明如下:

BOOL LoadBitmap(LPCTSTR lpszResourceName);
BOOL LoadBitmap(UINT nIDResource);

在VS2008中Bitmap位图创建步骤:

        资源文件->右键添加->资源->Bitmap->新建,这创建一个”中“字的位图效果如下。


有了以上的内容,我们就可以完成位图绘图功能,具体代码如下:

//nFlags:Indicates whether the user pressed modifier keys(Alt,Shift,Ctrl..)
//point: specify current cursor the position when left button up
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{	
	//创建位图对象
	CBitmap bitmap;
	//加载位图资源
	bitmap.LoadBitmap(IDB_BITMAP2);
	//创建位图画刷
	CBrush brush(&bitmap);
	//创建DC并得到DC
	CClientDC dc(this);
	//位图填充区域
	dc.FillRect(CRect(m_ptOrigin, point), &brush); 
	CView::OnLButtonUp(nFlags, point);
}

运行效果:



posted @ 2016-09-15 16:13  小怪兽&奥特曼  阅读(870)  评论(0编辑  收藏  举报