MFC中CDC类及其派生类
- CDC类(设备上下文类)用于绘图
CDC派生类 | 封装的GDI函数 | 功能说明 |
CPaintDC类 |
BeginPaint EndPaint |
标准客户区绘图,窗口刷新时不消失。 只在WM_PAINT消息下使用(OnPaint()) |
CWindowDC类 |
GetWindowDC ReleaseDC |
非客户区绘图,窗口刷新时不消失, 在WM_NCPAINT消息下使用 |
CClientDC类 |
GetDC ReleaseDC |
临时客户区绘图,窗口刷新时消失, 在任何情况下都可以使用 |
CMemDC类 |
CreateCompatibleDC DeleteDC |
VC6.0未实现,网上可以找到。 |
CMemDC类:
#ifndef __MEMDC_H__ #define __MEMDC_H__ //Author:www.baojy.com class CMemDC :public CDC { CSize m_size; public: void BitRgn( CRgn &rgn, //目标区域 COLORREF crTrans // 透明色 ) { int i = 0,j=0; rgn.CreateRectRgn(0,0,0,0); while(i<m_size.cx) { j = 0; while(j<m_size.cy) { if(GetPixel(i,j) - crTrans) { CRgn r; r.CreateRectRgn(i,j,i+1,j+1); rgn.CombineRgn(&rgn,&r,RGN_OR); } ++j; } ++i; } } void BitTrans( int nXDest, // 目标起点X int nYDest, // 目标起点Y int nWidthDest, // 目标宽度 int nHeightDest,// 目标高度 CDC* pDC, // 目标DC int nXSrc, // 来源起点X int nYSrc, // 来源起点Y COLORREF crTrans// 透明色 ) { CMemDC dcImage(nWidthDest, nHeightDest,pDC);//临时DC CBitmap bmpMask; bmpMask.CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL); // 创建单色掩码位图 CDC dcMask;//掩码DC dcMask.CreateCompatibleDC(pDC); dcMask.SelectObject(bmpMask); //将载入位图的内存DC中的位图,拷贝到临时DC中 dcImage.BitBlt( 0, 0, nWidthDest, nHeightDest, this, nXSrc, nYSrc, SRCCOPY); // 设置临时DC的透明色 dcImage.SetBkColor(crTrans); //掩码DC的透明区域为白色其它区域为黑色 dcMask.BitBlt(0, 0, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCCOPY); //临时DC透明区域为黑色,其它区域保持不变 dcImage.SetBkColor(RGB(0,0,0)); dcImage.SetTextColor(RGB(255,255,255)); dcImage.BitBlt( 0, 0, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND); // 目标DC透明部分保持屏幕不变,其它部分变成黑色 pDC ->SetBkColor(RGB(255,255,255)); pDC ->SetTextColor(RGB(0,0,0)); pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND); pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCPAINT); } void StretchTrans( int nXDest, // 目标起点X int nYDest, // 目标起点Y int nWidthDest, // 目标宽度 int nHeightDest, // 目标高度 CDC* pDC, // 目标DC int nXSrc, // 来源起点X int nYSrc, // 来源起点Y int nWidthSrc, // 来源宽度 int nHeightSrc, // 来源高度 COLORREF crTrans // 透明色 ) { CMemDC dcImage(nWidthDest, nHeightDest,pDC);//临时DC CBitmap bmpMask; // 创建单色掩码位图 bmpMask.CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL); CDC dcMask; dcMask.CreateCompatibleDC(pDC); dcMask.SelectObject(bmpMask); // 将载入位图的内存DC中的位图,拷贝到临时DC中 if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc) dcImage.BitBlt(0, 0, nWidthDest, nHeightDest, this, nXSrc, nYSrc, SRCCOPY); else dcImage.StretchBlt(0, 0, nWidthDest, nHeightDest, this, nXSrc, nYSrc, nWidthSrc, nHeightSrc, SRCCOPY); // 设置临时DC的透明色 dcImage.SetBkColor( crTrans); //掩码DC的透明区域为白色其它区域为黑色 dcMask.BitBlt(0,0,nWidthDest, nHeightDest,&dcImage,0,0,SRCCOPY); //临时DC透明区域为黑色,其它区域保持不变 dcImage.SetBkColor(RGB(0,0,0)); dcImage.SetTextColor(RGB(255,255,255)); dcImage.BitBlt(0, 0, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND); // 目标DC透明部分保持屏幕不变,其它部分变成黑色 pDC ->SetBkColor(RGB(255,255,255)); pDC ->SetTextColor(RGB(0,0,0)); pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND); pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCPAINT); } CMemDC() { m_size.cx = m_size.cy = 0; } //从资源中加载位图 BOOL LoadBitmap(UINT nBitmapID,CDC* pDC=NULL) { CBitmap bitmap; bitmap.LoadBitmap(nBitmapID); BITMAP bm; bitmap.GetBitmap(&bm); m_size.cx = bm.bmWidth; m_size.cy = bm.bmHeight; CreateCompatibleDC(pDC); SelectObject(bitmap); return TRUE; } CMemDC(UINT nBitmapID,CDC* pDC=NULL) { LoadBitmap(nBitmapID,pDC); } //从.bmp文件中加载位图 BOOL LoadBitmap(LPCSTR szBitmapFile,CDC* pDC=NULL) { HBITMAP hBitmap = (HBITMAP)LoadImage(AfxGetInstanceHandle(), szBitmapFile,IMAGE_BITMAP,0,0,LR_LOADFROMFILE); BITMAP bm; GetObject(hBitmap,sizeof(bm),&bm); m_size.cx = bm.bmWidth; m_size.cy = bm.bmHeight; CreateCompatibleDC(pDC); SelectObject(hBitmap); return TRUE; } CMemDC(LPCSTR szBitmapFile,CDC* pDC=NULL) { LoadBitmap(szBitmapFile,pDC); } //创建一张空白内存画布 BOOL Create(int cx,int cy,CDC* pDC = NULL) { CreateCompatibleDC(pDC); CBitmap bitmap; if(pDC) bitmap.CreateCompatibleBitmap(pDC,cx,cy); else bitmap.CreateCompatibleBitmap(&CClientDC(NULL),cx,cy); m_size.cx = cx; m_size.cy = cy; SelectObject(bitmap); return TRUE; } CMemDC(int cx,int cy,CDC* pDC = NULL) { Create(cx,cy,pDC); } //摧毁 BOOL DeleteDC() { if(!GetSafeHdc()) return TRUE; CBitmap * pBitmap = GetCurrentBitmap(); pBitmap ->DeleteObject(); return CDC::DeleteDC(); } ~CMemDC() { DeleteDC(); } inline int Width(){return m_size.cx;} inline int Height(){return m_size.cy;} }; #endif //__MEMDC_H__
例子:
/* Pen Styles */ #define PS_SOLID 0 #define PS_DASH 1 /* ------- */ #define PS_DOT 2 /* ....... */ #define PS_DASHDOT 3 /* _._._._ */ #define PS_DASHDOTDOT 4 /* _.._.._ */ #define PS_NULL 5
// CPaintDC 是标准客户区绘画。刷新不消失。CPaintDC中封装了BeginPaint(),EndPaint() // 而CClientDC 是临时客户区绘图,刷新会消失。封装了GetDC(),ReleaseDC() CPaintDC dc(this); // device context for painting CRect rect; GetClientRect(&rect); dc.Ellipse(rect);//画椭圆 //画线 dc.MoveTo(0,0); dc.LineTo(rect.right,rect.bottom); //画矩形,利用当前画笔绘制矩形,内部由当前画刷填充。 dc.Rectangle(20,20,100,80); //画圆角矩形 dc.RoundRect(20,90,100,150,10,10);//前4个数是矩形坐标,后2个是圆角的大小 --------------------------------- /* rect.bottom = 30; dc.FillSolidRect(&rect,RGB(0,100,255)); CString str = "测试CPaintDC类"; dc.DrawText(str,&rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); // DT_VCENTER | DT_SINGLELINE 配合使用才有上下居中的效果 */ /* 调用FillSolidRect时,以前用SetBkColor设置的背景色,被设置为clr指定的颜色。 就是说你的背景色已经变成了FillSolidRect设置的颜色了。 也许正常是看不出来的。 但当以再用画笔画PS_DOT类的线时, 你会发现你虚线原来的空白地方变成了FillSolidRect设置的颜色了。 用FillSolidRect时一定要注意。 可以用CDC::FillRect() */ rect.bottom = 30; CBrush brush; brush.CreateSolidBrush(RGB(0,100,255)); dc.FillRect(&rect,&brush); CString str = "测试CPaintDC类"; dc.SetBkMode(TRANSPARENT); dc.DrawText(str,&rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); // DT_VCENTER | DT_SINGLELINE 配合使用才有上下居中的效果 dc.MoveTo(20,120); dc.LineTo(120,120); CPen p1(PS_SOLID, 3, RGB(0,0,255)); CPen* pOldPen = dc.SelectObject(&p1); // 返回前一个画笔 dc.MoveTo(20,140); dc.LineTo(120,140); // CPen p2(PS_DASHDOTDOT, 1, RGB(255,0,0)); // 注意,虚线只有在宽度为1时,才有效 CPen p2; LOGPEN logPen = {PS_DASHDOTDOT, 1}; logPen.lopnColor = RGB(255,0,0); p2.CreatePenIndirect(&logPen); dc.SelectObject(&p2); dc.MoveTo(20,150); dc.LineTo(120,150); dc.Rectangle(20,160,120,200); dc.Ellipse(20,160,110,200); CPen p3; p3.CreatePen(PS_DASH, 1, RGB(255,0,0)); dc.SelectObject(&p3); // 画多边形 CPoint ps[] = {CPoint(70,200), CPoint(20,300),CPoint(120,300)}; dc.Polygon(ps, sizeof(ps)/sizeof(ps[0])); CRect rect2(150,50,300,150); dc.Ellipse(150,50,300,150); dc.SelectObject(&p1); CPoint pt1(100,50),pt2(300,200); // dc.Arc(&rect2,pt1,pt2); // 画弧线(非闭合) dc.Chord(&rect2,pt1,pt2); // 画弧线(闭合) dc.MoveTo(pt1); dc.LineTo(rect2.CenterPoint()); dc.LineTo(pt2); LOGPEN pl; p3.GetLogPen(&pl); HPEN hPen = p3;// HPEN hPen = (HPEN)p3.GetSafeHandle(); CPen* pPen; pPen = CPen::FromHandle(hPen); /* CPen p4(PS_NULL,666,RGB(55,55,55)); // 空画刷,就是后面的宽度和颜色无效, dc.SelectObject(&p4); // dc.Rectangle(150,50,300,150); // 无边框默认填充白色 CBrush br(RGB(255,0,255)); dc.SelectObject(&br); dc.Rectangle(150,50,300,100); // 无边框填充紫色 相当于 dc.FillSolidRect(CRect(150,50,300,100),RGB(255,0,255)); */
常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。
昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。