1、第五节 CView和GDI以及类与继承第4节 CView和GDI以及类与继承一建立MFC单文档首先打开VS2008,在“文件”中新建项目,选择visualC+中的“MFC应用程序”命名为“Five”确认,弹出“MFC应用程序向导”;点击下一步,在应用程序类型中选择“单文档”,在“用户功能界面”中勾选“最大化”;点击下一步,在生成的类中的 基类选择“CView”,点击完成单文档CView的建立。然后像以前一样将工程属性中的常规中使用的字符集改为“使用多字节字符集”。2熟悉CView的结构CView不像前面所说的CFromView,在CView中没有对话框,没有可以从工具箱拖动的控件等,只能在自己
2、利用代码创建一个控件并为其添加事件。下面我们以建立一个CTreeCtrl,即树状控件。首先在FiveView.h中实例化一个控件对象,代码如下:CTreeCtrl m_tree;然后再FiveView.cpp中创建一个CTreeCtrl,创建前需要先为FiveView.cpp添加一个OnCreat()事件,创建方法在前面几节中有介绍,下面创建CTreeCtrl,代码如下:int CFiveView:OnCreate(LPCREATESTRUCT lpCreateStruct) if (CView:OnCreate(lpCreateStruct) = -1) return -1;m_tree.C
3、reate(WS_VISIBLE|WS_CHILD|WS_BORDER|TVS_HASLINES|TVS_HASBUTTONS|TVS_EDITLABELS|TVS_LINESATROOT|TVS_CHECKBOXES,CRect(0,0,0,0),this,IDC_TREECTRL);m_tree.ModifyStyle(TVS_CHECKBOXES,0);return 0;如果直接写上面的程序会报出错误,因为没有IDC_TREECTRL,其中IDC代表资源文件。因此我们需要现在resources.h中声明此ID,代码如下:#define IDC_TREECTRL 130不能与resourc
4、es.h中的其他重复。另外我需要介绍下m_tree.Creat方法中的相关内容,代表了创建的CTreeCtrl拥有的样式,而后面的m_tree.ModifyStyle()的作用是对CTreeCtrl的样式进行增加或删除,其定义为:BOOL ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0);dwRemove是进行删除的项,若没有,设为0;dwAdd是进行添加的项,同样,没有则设为0。上面的功能就是移除已经定义了的TVS_CHECKBOXES。其中的CRect(0,0,0,0)代表建立一个确定坐标的矩形。当改变窗体大小时,树状控件也
5、随其变化,并充满窗体。首先为FiveView.cpp添加一个OnSize()事件,写下如下代码: if(m_tree.m_hWnd) m_tree.SetWindowPos(NULL,0,0,cx,cy,SWP_NOZORDER);在属性为FiveView.cpp添加一个OnInitialUpdate()方法,通过此方法为树状控件添加节点,代码如下:void CFiveView:OnInitialUpdate() CView:OnInitialUpdate(); HTREEITEM m_node=m_tree.InsertItem(根节点,TVI_ROOT); m_tree.InsertIte
6、m(第一层节点,m_node); m_tree.InsertItem(根节点2,TVI_ROOT);运行效果如图:3基于CView的GDI绘图新建一个工程,命名为“Five_GDI”,方法与上面一样。找到Five_GDIView.cpp中的OnDraw()方法,其中的CDC就是进行绘图的类,1)下面在指定坐标上输出文字,代码如下:void CFive_GDIView:OnDraw(CDC* pDC) CFive_GDIDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; pDC-TextOut(100,100,Hel
7、lo,World!);效果如图2)在窗口中画线,代码如下:pDC-MoveTo(100,200); pDC-LineTo(500,600);效果如图3)在窗口画矩形和椭圆pDC-Rectangle(100,100,200,200); pDC-Ellipse(400,200,500,400);效果如图4)画红色边框的矩形 CPen pPen,*oldPen; pPen.CreatePen(1,2,RGB(255,0,0); oldPen=pDC-SelectObject(&pPen); pDC-Rectangle(100,100,200,300); pDC-SelectObject(oldPen
8、); pPen.DeleteObject();5)画内部填充颜色的矩形框 CPen pPen,*oldPen; pPen.CreatePen(1,2,RGB(255,0,0); oldPen=pDC-SelectObject(&pPen); CBrush pBrush,*oldBrush; pBrush.CreateSolidBrush(RGB(0,225,0); oldBrush=pDC-SelectObject(&pBrush); pDC-Rectangle(100,100,200,300); pDC-SelectObject(oldPen); pPen.DeleteObject(); p
9、DC-SelectObject(oldBrush); pBrush.DeleteObject();其中外框属于CPen类,而内部为CBrush类注:在将新画笔使用完成后,需要还原为默认颜色,否则画笔颜色会被更改。另外使用完成后要删除对象,否则可能会引起内存泄露。6)创建没有边框的内有填充的矩形 CPen pPen,*oldPen; oldPen=(CPen*)pDC-SelectStockObject(NULL_PEN); CBrush pBrush,*oldBrush; pBrush.CreateSolidBrush(RGB(255,0,0); oldBrush=pDC-SelectObje
10、ct(&pBrush); pDC-Rectangle(100,200,200,400); pDC-SelectObject(oldBrush);pDC-SelectObject(oldPen); pBrush.DeleteObject();其中外框选择NULL_PEN,因此不需要为其设定颜色。7)创建只有边框没有内部填充的矩形CPen pPen,*oldPen;pPen.CreatePen(1,2,RGB(255,0,0); oldPen=pDC-SelectObject(&pPen); CBrush pBrush,*oldBrush;oldBrush=(CBrush*)pDC-SelectS
11、tockObject(NULL_BRUSH); pDC-Rectangle(100,100,200,300);pDC-SelectObject(oldPen); pPen.DeleteObject(); pDC-SelectObject(oldBrush); pBrush.DeleteObject();此情况与6)情况相同。8)关于用户坐标与窗口坐标的转换 CRect winrt; GetWindowRect(winrt); ScreenToClient(winrt); CRect rt; GetClientRect(rt);在应用中要注意我们所使用的坐标系统,并成功进行转换。4利用类与继承画
12、矩形和椭圆首先在工程的包含.h文件目录下建立一个文件夹,命名为“include”;然后在VS05中“解决方案资源管理器”中的工程中添加一个类,选择“C+类”,类名为:RectPainter,.h文件中输入includeRectpainter.h,确定。然后再添加两个筛选器,分别命名为:include.cpp和include.h。然后将生成的Rectpainter.cpp和Rectpainter.h分别拖入其中。如图:1)类:在Rectpainter.h中声明类的方法和属性,代码如下:class RectPainterpublic: RectPainter(void); virtualRectP
13、ainter(void); void SetRect(double left,double top,double right,double bottom); inline void SetBackColor(COLORREF cr,COLORREF cb) backColor=cr; backColor2=cb; void Draw(CDC*pDC);protected: DOUBLE l,t,r,b; COLORREF backColor; COLORREF backColor2;然后在Rectpainter.cpp中实现上面的方法:RectPainter:RectPainter(void)
14、RectPainter:RectPainter(void)void RectPainter:SetRect(double left,double top,double right,double bottom) l=left; t=top; r=right; b=bottom;void RectPainter:Draw(CDC*pDC) CPen pPen,*oldPen; pPen.CreatePen(0,2,backColor); oldPen=pDC-SelectObject(&pPen); CBrush pBrush,*oldBrush; pBrush.CreateSolidBrush(
15、backColor2); oldBrush=pDC-SelectObject(&pBrush); pDC-Rectangle(l,t,r,b); pDC-SelectObject(oldPen); pPen.DeleteObject();上面我们完成了Rectpainter类的建立,下面我们来实例化该类并应用在Five_GDI2View.h实例化,并添加头文件,代码如下:#include includeRectPainter.h.Rectpainter pPainter;然后在OnCreat事件中写下如下代码int CFive_GDI2View:OnCreate(LPCREATESTRUCT
16、lpCreateStruct). pPainter.SetRect(100,100,200,200); pPainter.SetBackColor(RGB(255,0,0),RGB(0,255,0);.最后绘制图像,即在OnDraw事件中添加代码:void CFive_GDI2View:OnDraw(CDC* pDC) /注意把原有的/*/去掉 pPainter.Draw(pDC);运行效果如图:2)继承:新建一个工程命名为Five_GDI1,建立方法与上面一致。在Rectpainter.h中声明类的方法和属性,class CGeometryPainterpublic: CGeometryPa
17、inter() ; virtual CGeometryPainter() ; void SetRect(double left,double top,double right,double buttom); void SetBackColor(COLORREF cr) backColor=cr; ; virtual void Draw(CDC*pDC)=0;protected: DOUBLE l,t,r,b; COLORREF backColor;class CRectPainter:public CGeometryPainterpublic: CRectPainter(); virtual
18、CRectPainter(); void Draw(CDC*pDC);class CEllipsesPainter:public CGeometryPainterpublic: CEllipsesPainter(); virtual CEllipsesPainter(); void Draw(CDC*pDC);其中CGeometryPainter为基类,而CRectPainter和CEllipsesPainter都继承与它,由于其中的Draw方法具有不同,所以需要在CGeometryPainter将其设为虚方法;virtual void Draw(CDC*pDC)=0;而CGeometryPa
19、inter则为抽象类,不能进行实例化,如果要实例需要用到指针,后面将要使用。然后在Rectpainter.cpp中实现上面的方法:void CGeometryPainter:SetRect(double left,double top,double right,double buttom) l=left; t=top; r=right; b=buttom;CRectPainter:CRectPainter(void)CRectPainter:CRectPainter(void)void CRectPainter:Draw(CDC*pDC) CBrush pBrush,*oldBrush; pB
20、rush.CreateSolidBrush(backColor); oldBrush=pDC-SelectObject(&pBrush); pDC-Rectangle(l,t,r,b); pDC-SelectObject(oldBrush); pBrush.DeleteObject();CEllipsesPainter:CEllipsesPainter(void)CEllipsesPainter:CEllipsesPainter(void)void CEllipsesPainter:Draw(CDC *pDC) CBrush pBrush,*oldBrush; pBrush.CreateSol
21、idBrush(backColor); oldBrush=pDC-SelectObject(&pBrush); pDC-Ellipse(l,t,r,b); pDC-SelectObject(oldBrush); pBrush.DeleteObject();上面我们完成了Rectpainter类的建立,下面我们来实例化该类并应用在Five_GDI2View.h实例化,并添加头文件,代码如下:#include includeRectPainter.hprotected: CArray pGeoPainters;这儿我们使用数组用来存放各个图形。然后在OnCreat事件中写下如下代码CGeometr
22、yPainter *pGeoPainter; /这就是上面所说的抽象类的实例 for(int i=0;iSetRect(100+i*100,100+i*100,200+i*100,200+i*100); pGeoPainter-SetBackColor(RGB(255,0,0); else pGeoPainter=new CEllipsesPainter(); pGeoPainter-SetRect(100+i*100,100+i*100,200+i*100,250+i*100); pGeoPainter-SetBackColor(RGB(0,255,0); pGeoPainters.Add(pGeoPainter); 在此创建图形,最后在OnDraw事件中绘制完成,代码如下:void CFive_GDI1View:OnDraw(CDC* pDC) CFive_GDI1Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; int Size=pGeoPainters.GetSize(); for(int k=0;kDraw(pDC); 运行效果如图:
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1