MFC画图方法汇总

1. 画线

方法I:使用HDC (SDK模式)

HDC hDC;
hDC = ::GetDC(m_hWnd);                    //此处要用全局的::GetDC,否则默认用CDC的。
MoveToEx(hDC, point1.x, point1.y, NULL);  //MoveToEx,先移到初始点,然后再画线
LineTo(hDC, point2.x, point2.y);
::ReleaseDC(m_hWnd, hDC);                 //释放也要用全局::ReleaseDC

方法II:使用CDC(MFC模式)

CDC *pdc=GetDC();  
pdc->MoveTo(point1);  
pdc->LineTo(point2);  
ReleaseDC(pdc);  


方法III:使用CClientDC(CClientDC继承自CDC,不需要手动GetDC和ReleaseDC,传递this或GetParent())

CClientDC dc(GetParent());  //可以在Frame下画线  
dc.MoveTo(m_ptOrigin);    
dc.LineTo(point);  

方法IV:使用CWindowDC(CWindowDC继承自CDC,包含客户区和非客户区,可以在整个屏幕下画线 ,不需要手动GetDC和ReleaseDC)

CWindowDC dc(GetDesktopWindow());
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);

2. 包含画笔(颜色,样式,宽度)

方法1:

CDC *pDC = GetDC();
CPen pen(PS_SOLID, 2, RGB(200,200,200));  //定义一个画笔,样式为实线,颜色为灰色,宽度为2像素  
CPen *pOldPen = pDC->SelectObject(&pen);  //将新画笔选入设备描述表,并返回之前的画笔
pDC->MoveTo(m_ptOrign);
pDC->LineTo(point);
pDC->SelectObject(pOldPen);               //还原旧画笔
ReleaseDC(pDC);

方法2:

CClientDC dc(this);                   //不需要ReleaseDC
CPen pen(PS_DASH,1,RGB(255,0,0));     //定义一个画笔,样式为破折号,颜色为红色,宽度为1像素  
CPen *cOldPen=dc.SelectObject(&pen);  //将新画笔选到dc中,并保存之前的画笔  
dc.MoveTo(point1);  
dc.LineTo(point2);  
dc.SelectObject(cOldPen);             //还原旧画笔 

方法3:

CWindowDC dc(GetDesktopWindow());     //CWindowDC继承自CDC,包含客户区和非客户区,GetDesktopWindow()获取桌面
CPen pen(PS_SOLID, 5, RGB(255,0,0));
CPen *pOldPen = dc.SelectObject(&pen);
dc.MoveTo(point1);
dc.LineTo(point2);
dc.SelectObject(pOldPen);


3. 画刷

CBrush brush(RGB(255,0,0));
CClientDC dc(this);            //CClientDC传递this
dc.FillRect(CRect(point1, point2), &brush);     //FillRect填充

透明画刷:
CClientDC dc(this);
CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); //创建透明画刷
CBrush *pOld = dc.SelectObject(pBrush);
dc.Rectangle(CRect(point1, point2));   //画矩形
dc.SelectObject(pOld);                 //最后返还画刷

4. 画圆角矩形

//圆角大小
POINT pt;
pt.x = 5;
pt.y = 5;

//窗口尺寸
CRect rc;
GetClientRect(&rc);

//画圆角矩形,然后还原旧画笔
CDC *pDC = GetDC();
pDC->RoundRect(&rect, pt);
pDC->SelectObject(hOldPen);

//新画笔:实线,线宽5,红色
CPen pen(PS_SOLID, 5, RGB(255, 0, 0));
CPen* hOldPen = pDC->SelectObject(&pen);

//通过朝CRect的中心移动边以缩小CRect,SM_CXEDGE表示缩小一个边框大小,相反函数nflateRect
rect.DeflateRect(CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));

//填充颜色
CBrush brush(RGB(200,200,200));
pDC->FillRect(rect, &brush);
brush.DeleteObject();

例如:给窗体加上圆角矩形的窗体

需要重载消息 WM_ERASEBKGND,在函数OnEraseBkgnd(CDC* pDC)中实现,才能保证在窗体被遮盖重现后,窗体上画的线条及加载的图片被正常显示

//绘图
BOOL CDelTaskDlg::OnEraseBkgnd(CDC* pDC)
{
	// TODO:  在此添加消息处理程序代码和/或调用默认值

	CDialogEx::OnEraseBkgnd(pDC);

	CRect rc;
	GetClientRect(&rc);
	rc.right -= 1;
	rc.bottom -= 1;

	//画圆角矩形
	POINT pt;
	pt.x = 5;
	pt.y = 5;
	CPen hNewPen(PS_SOLID, 1, RGB(170, 170, 170));
	CPen* hOldPen = pDC->SelectObject(&hNewPen);
	pDC->RoundRect(&rc, pt);
	pDC->SelectObject(hOldPen);

	return TRUE;
}


5. 创建任意线条

(1)创建基于单文档工程:Draw

CDrawView类中添加成员变量:

CPoint m_ptOrigin;
BOOL m_bDraw;

(2)CDrawView()中初始化:

m_ptOrigin = point;
m_bDraw = false;

(3)添加消息响应函数:

WM_LBUTTONDOWN    
WM_LBUTTONUP  
WM_MOUSEMOVE
(4)左键按下时:
m_ptOrigin = point;
m_bDraw = true;
(5)左键抬起:
m_bDraw = false;
(6)鼠标移动时:

//画连续线条
CClientDC dc(this);
if(m_bDraw)
{
	 dc.MoveTo(point1);
	 dc.LineTo(point2);
	 m_ptOrigin = point2;   //必须的
}

//画扇形线条
CClientDC dc(this);
if(m_bDraw)
{
	 dc.MoveTo(m_ptOrigin);
	 dc.LineTo(point);
}

//画带外包线的扇形线条
析:画带外包线的扇形线条,不光记录初始位置,还要记录鼠标移动上一位置。
添加成员变量:
CPoint m_ptOld;
在鼠标左键按下时初始化:
m_ptOld = point;
在鼠标移动时进行改变:
CClientDC dc(this);
if(m_bDraw)
{
   dc.MoveTo(m_ptOrigin);
   dc.LineTo(m_ptOld);
   dc.MoveTo(m_ptOld);
   dc.LineTo(point);
   m_ptOld = point;
}

6. 画矩形

画无边框的矩形:

方法说明:利用FillRect函数填充矩形。填充内容为画刷的内容,即画刷对象的指针

CBrush brush(RGB(5,255,255));
CClientDC dc(this);
dc.FillRect(CRect(m_ptOrigin,point),&brush);

以位图作为画刷的资源:

CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
CBrush brush(&bitmap);  //定义画刷的同时初始化
CClientDC dc(this);
dc.FillRect(CRect(m_ptOrigin,point),&brush);
bitmap.DeleteObject();  //可以调用DeleteObject删除由LoadBitmap加载的位图,否则CBitmap的析构函数将删除该位图对象

或者:

CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
CBrush brush;			   //先声明
brush.CreatePatternBrush(&bitmap); //再初始化
CClientDC dc(this);
dc.FillRect(CRect(m_ptOrigin,point),&brush);
bitmap.DeleteObject();             //可以调用DeleteObject删除由LoadBitmap加载的位图,否则CBitmap的析构函数将删除该位图对象

画有边框的矩形:

方法说明:利用Rectangle方法来画矩形。其中CBrush与CPen类分别负责矩形内部和矩形边框的属性

(1) 画中心为白色的矩形

CClientDC dc(this);
dc.Rectangle(CRect(point1,point2));

(2)画中心为透明的矩形(空笔刷)
CClientDC dc(this);
CBrush *pBrush=CBrush::FromHandle((HBRUSH)
GetStockObject(NULL_BRUSH));
CBrush *pOldBrush=dc.SelectObject(pBrush);
dc.Rectangle(CRect(m_ptOrigin,point));
pOldBrush=pBrush;

(3)画中心为透明边为任意颜色的矩形
CClientDC dc(this);
CPen pen(PS_SOLID,1,RGB(234,23,53));
CPen *pOldPen=dc.SelectObject(&pen);
CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH))
CBrush *pOldBrush=dc.SelectObject(pBrush);
dc.Rectangle(CRect(m_ptOrigin,point));
dc.SelectObject(pOldPen);
dc.SelectObject(pOldBrush);


总结:
使用画笔:

CClientDC dc(this);
CPen pen(PS_SOLID,1,RGB(234,23,53));
CPen *pOldPen=dc.SelectObject(&pen);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
dc.SelectObject(pOldPen);

使用画刷填充:
CBrush brush(RGB(0,255,0));
CClientDC dc(this);
CRect rect(point1,point2);
dc.FillRect(&rect,&brush);

使用位图创建画刷进行填充:
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
CBrush brush(&bitmap);
CClientDC dc(this);
CRect rect(point1,point2);
dc.FillRect(&rect,&brush);

使用空笔刷画透明矩形:
CBrush *brush;
brush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
CClientDC dc(this);
CBrush *pOldBrush =dc.SelectObject(brush) ;
dc.Rectangle(CRect(point1,point2));
dc.SelectObject(pOldBrush) ;



你可能感兴趣的:(MFC画图方法汇总)