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; }
画无边框的矩形:
方法说明:利用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));
CClientDC dc(this); CBrush *pBrush=CBrush::FromHandle((HBRUSH) GetStockObject(NULL_BRUSH)); CBrush *pOldBrush=dc.SelectObject(pBrush); dc.Rectangle(CRect(m_ptOrigin,point)); pOldBrush=pBrush;
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) ;