C++MFC编程笔记day06 MFC向导、MFC绘图类使用

简介:  MFC绘图    MFC绘图类包括绘图设备类和绘图对象类    1 绘图设备类      CDC类-父类是CObject,封装的是一般的绘图设备,例如:显示器,            打印机等。
 MFC绘图
   MFC绘图类包括绘图设备类和绘图对象类
   1 绘图设备类
     CDC类-父类是CObject,封装的是一般的绘图设备,例如:显示器,
           打印机等。
     CWindowDC类-父类是CDC类,封装的是窗口对象,包括客户区和非
           客户区。
     CClientDC类-父类是CDC类,封装的仍然是窗口,但是只包括客户区。
     CPaintDC类-父类是CDC类,封装的是窗口的客户区。但是,它只用
             在窗口的WM_PAINT消息处理函数中。
     CMetaFileDC类-父类是CDC类,作用保存绘制命令。
   2 使用
    创建MFC AppWizard(exe)工程,添加菜单项,然后使用类向导生成消息命令的函数体框架。
     2.1 CDC::CreateDC()-创建绘图设备
     virtual BOOL CreateDC(
        LPCTSTR lpszDriverName,//设备的驱动名称
        LPCTSTR lpszDeviceName,//设备名称
        LPCTSTR lpszOutput,//接口
        const void* lpInitData//设备的初始化参数
     );
     设备为显示器时,("DISPLAY",NULL,NULL,NULL);
     2.2 使用
        ....
     2.3 CDC::DeleteDC()-删除设备
     2.4 CDC的子类CWindowDC、CClientDC、CPaintDC,在构造函数中
        调用CreateDC(),在析构函数中调用DeleteDC(),所以,子类使用
        只需要构造对象即可。

     2.5 CMetaFileDC类的使用
        2.5.1 创建
              CMetaFileDC::Create
        2.5.2 绘制
              ....
        2.5.3 关闭,返回句柄 HMETAFILE
              CMetaFileDC::Close
        2.5.4 使用
              CDC::PlayMetaFile
        2.5.5 删除
              DeleteMetaFile
    3 绘图对象类
      3.1 CPen-画笔
      3.2 CBrush-画刷
      3.3 CFont-字体
      3.4 CBitmap-位图
      3.5 CRgn-区域
      3.6 CPalette-调色板
          RGB(0~255,0~255,0~255),每个颜色值占3个字节。
      彩色位图,800*600像素,位图大小是:800*600*3 字节
      颜色表大小 48*3 +800*600*1
      3.7 使用
      3.7.1 CPen、CBrush、CFont的使用

      3.7.2 CBitmap的使用

      3.7.3 CRgn的使用
            1 创建
              CRgn::CreateXXX
            2 将两个CRgn对象进行几何运算
              CRgn::CombineRgn
            3 填充
              CDC::FillRgn
            4 填充边框

              CDC::FrameRgn

程序示例:


在****view类中,定义一个成员变量:

HMETAFILE m_hMetafile;


//功能实现部分主要代码

void CMFCdrawView::OnDcCwindowdc() 
{
	// TODO: Add your command handler code here
	CWindowDC dc(AfxGetMainWnd());
	dc.TextOut(0,0,"Hello CWindowDC");

}

void CMFCdrawView::OnDcCmetafiledc() 
{
	// TODO: Add your command handler code here
	//创建
	CMetaFileDC dc;
	dc.Create();
	//绘制命令
	dc.TextOut(100,100,"DcCmetafile");
	dc.MoveTo(150,150);
	dc.LineTo(200,200);
	//关闭,并返回句柄
	m_hMetafile= dc.Close();
	CClientDC dc2(this);
	dc2.PlayMetaFile(m_hMetafile);
}

void CMFCdrawView::OnDcCclientdc() 
{
	// TODO: Add your command handler code here
	CClientDC dc(this);
	dc.TextOut(0,0,"Hello CClientDC");
}

void CMFCdrawView::OnDcCdc() 
{
	// TODO: Add your command handler code here
	CDC dc;
	dc.CreateDC("DISPLAY",NULL,NULL,NULL);//打印到屏幕上
	RECT rc={0};
	rc.left=0;rc.right=200;rc.top=0;rc.bottom=100;
	dc.DrawText("hello cdc",&rc,DT_MODIFYSTRING);
	dc.DeleteDC();
}

void CMFCdrawView::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	dc.TextOut(0,20,"Hell0 Paint");
	//使用CMetaFile
	if(m_hMetafile)	dc.PlayMetaFile(m_hMetafile);
	//OnGdiBitmap();
	// Do not call CView::OnPaint() for painting messages
}

void CMFCdrawView::OnGdiBitmap() 
{
	// TODO: Add your command handler code here
	CClientDC dc(this);
	CDC dcBitmap;//内存dc
	dcBitmap.CreateCompatibleDC(&dc);
	CBitmap bmp;//位图对象
	bmp.LoadBitmap(IDB_BITMAP1);//插入的图片资源
	CBitmap*oldbmp=dcBitmap.SelectObject(&bmp);//放入内存dc
	//dc.BitBlt(300,300,110,37,&dcBitmap,0,0,SRCCOPY);//成像
	RECT rc={0};
	GetClientRect(&rc);
	//拉伸成像
	dc.StretchBlt(0,0,rc.right,rc.bottom,&dcBitmap,0,0,101,37,SRCCOPY);
	dcBitmap.SelectObject(oldbmp);
	dcBitmap.DeleteDC();//删除内存dc
	bmp.DeleteObject();//删除位图对象
	
}

void CMFCdrawView::OnGdiBrush() 
{
	// TODO: Add your command handler code here
	//CBrush brush(HS_CROSS,RGB(0,255,0));//普通画刷
	CBitmap bmp;bmp.LoadBitmap(IDB_BITMAP2);
	CBrush brush(&bmp);//位图画刷
	CClientDC dc(this);
	CBrush*oldbrush=dc.SelectObject(&brush);
	dc.RoundRect(50,50,220,220,2,2);
	dc.SelectObject(oldbrush);
	brush.DeleteObject();
	
}

void CMFCdrawView::OnGdiFont() 
{
	// TODO: Add your command handler code here
	CFont font;
	font.CreatePointFont(500,"黑体");
	CClientDC dc(this);
	CFont*oldfont=dc.SelectObject(&font);
	dc.TextOut(150,150,"OnGdiFont");
	dc.SelectObject(oldfont);
	font.DeleteObject();
}

void CMFCdrawView::OnGdiPen() 
{
	// 创建画笔
	CPen pen(PS_SOLID,5,RGB(255,0,0));
	//将画笔选择当前设备
	CClientDC dc(this);
	CPen * oldpen=dc.SelectObject(&pen);
	dc.TextOut(10,10,"OnGdiPen");
	dc.RoundRect(100,100,200,200,2,2);
	dc.SelectObject(oldpen);
	pen.DeleteObject();
	
}

void CMFCdrawView::OnGdiRgn() 
{
	CRgn rgn1,rgn2;
	//创建
	rgn1.CreateEllipticRgn(100,100,300,300);
	rgn2.CreateEllipticRgn(150,100,350,300);
    //几何运算
	rgn1.CombineRgn(&rgn1,&rgn2,RGN_XOR);
	//填充
	CClientDC dc(this);
	CBrush brush(RGB(255,0,0));
	CBrush brush2(RGB(0,0,255));
	dc.FillRgn(&rgn1,&brush);
	//dc.FillRgn(&rgn2,&brush2);
	//填充边框
	dc.FrameRgn(&rgn1,&brush2,5,1);
	//将窗口的区域设置成rgn1
	AfxGetMainWnd()->SetWindowRgn(rgn1,TRUE);
}
效果:



2、

简单的鼠标绘图的例子
   1 图形数据,1 起点和终点,CPoint;
              2 使用整数变量确定当前绘制的图形
                 UINT m_nType;
                 m_nType=1;直线
                 m_nType=2;矩形
                 m_nType=3;椭圆
                 m_nType=0;不绘制图形
               3 BOOL m_bFlag;//标识是否开始画线
   2 绘制过程
     2.1 LBUTTONDOWN消息
         m_bFlag=TRUE;//开始绘图
         m_ptBegin=m_ptEnd=point; //确定起点位置
     2.2 MOUSEMOVE消息
         if(m_bFlag)
         {
            //擦线

            //画线
         }
     2.3 LBUTTONUP消息
         m_bFlag=FALSE;//结束画线

模拟绘图软件,鼠标点下进行绘图,放开则绘制指定的图形。

新建立 MFC 应用程序,并按照如下操作:






在****view 中,加入成员变量:

    CPoint m_ptBegin;//起点坐标
    CPoint m_ptEnd;//终点坐标
    UINT m_nType;//类型:1-直线,2-距形,3-圆
    BOOL m_bFlag;//是否开始画线


****view中主要实现代码:

//构造函数
CMFCdraw2View::CMFCdraw2View()
{
	// TODO: add construction code here
	m_nType=0;
	m_bFlag=FALSE;
	m_ptBegin=m_ptEnd=0;
}

void CMFCdraw2View::OnDrawElipse() 
{
	// TODO: Add your command handler code here
	m_nType=3;
}

void CMFCdraw2View::OnDrawLine() 
{
	// TODO: Add your command handler code here
	m_nType=1;
}

void CMFCdraw2View::OnDrawRect() 
{
	// TODO: Add your command handler code here
	m_nType=2;
}

void CMFCdraw2View::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	m_bFlag=TRUE;//开始绘图
    m_ptBegin=m_ptEnd=point; //确定起点位置 
	CView::OnLButtonDown(nFlags,point);
}


void CMFCdraw2View::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	m_bFlag=FALSE;//结束画线
	CView::OnLButtonUp(nFlags, point);
}

void CMFCdraw2View::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CClientDC dc(this);
	if(m_bFlag)
	{
		//擦线
		DrawShape(&dc,m_ptBegin,m_ptEnd);
		//画线
		DrawShape(&dc,m_ptBegin,point);
		//保存终点位置,为擦线准备
		m_ptEnd=point;
    }
	CView::OnMouseMove(nFlags, point);
}
void CMFCdraw2View::DrawShape(CDC *pDC, CPoint p1, CPoint p2)
{
	//设置绘图模式,R2_NOT与当前画线处颜色相反
	pDC->SetROP2(R2_NOT);
	//设置画刷为透明画刷
	CBrush *pOldBrush=
		(CBrush*)pDC->SelectStockObject(NULL_BRUSH);
	switch (m_nType)
	{
	case 1://直线
		pDC->MoveTo(p1);
		pDC->LineTo(p2);
		break;
	case 2://矩形
		pDC->Rectangle(p1.x,p1.y,p2.x,p2.y);
		break;
	case 3://椭圆
		pDC->Ellipse(p1.x,p1.y,p2.x,p2.y);
		break;
	}
	//恢复默认画刷
	pDC->SelectObject(pOldBrush);
	
}

void CMFCdraw2View::OnUpdateDrawElipse(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetRadio(m_nType==3);//更改选中的状态
}

void CMFCdraw2View::OnUpdateDrawLine(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetRadio(m_nType==1);
}

void CMFCdraw2View::OnUpdateDrawRect(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetRadio(m_nType==2);
}

效果:






相关文章
|
28天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
50 2
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
103 5
|
1月前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
89 4
|
1月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
108 4
|
2月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
32 4
|
2月前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
32 4
|
2月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
29 1
|
2月前
|
存储 编译器 C++
【C++类和对象(下)】——我与C++的不解之缘(五)
【C++类和对象(下)】——我与C++的不解之缘(五)
|
2月前
|
编译器 C++
【C++类和对象(中)】—— 我与C++的不解之缘(四)
【C++类和对象(中)】—— 我与C++的不解之缘(四)
|
2月前
|
存储 编译器 C语言
【C++类和对象(上)】—— 我与C++的不解之缘(三)
【C++类和对象(上)】—— 我与C++的不解之缘(三)