第5章图形操作内容摘要:1.CD和CDC类2.GDI和CGdiObject类3.绘图程序实例一4.绘图程序实例二返回目录5.1CD和CDC类学习目标1.了解设备环境(DeviceContext,简称DC)和设备环境类(CDC)2.利用设备环境类进行简单绘图5.1返回第5章使用设备环境类绘图的一个简单例子1.利用AppWizard生成基于对话框程序框架(BmpTest)2.添加画线和画椭圆的代码(OnPaint()函数)见下页3.代码解释:(1)CPaintDCdc(this);这句代码是生成一个CPaintDC类的实例dc,生成后就可以调用他的函数来进行绘图了。(2)dc.MoveTo(30,30);调用dc的MoveTo函数把画线的起点定在对话框的(30,30)坐标点。MoveTo函数的一般调用格式为:MoveTo(intx,inty),其中参数x,y是要画直线的起始点坐标。(3)dc.LineTo(30,30);调用dc的LineTo函数画线到(100,100)坐标点。LineTo函数的一般调用格式为:LineTo(intx,inty),其中参数x,y是所画直线的终止点坐标。(4)dc.Ellipse(120,120,160,160);本句代码的作用是调用设备环境对象dc的画椭圆函数Ellipse画椭圆。Ellipse函数的一般调用格式为:Ellipse(LPCRECTlpRect),其中参数lpRect是所画椭圆的外接矩形。5.15.1voidCBmpTestDlg::OnPaint(){if(IsIconic()){CPaintDCdc(this);//devicecontextforpaintingSendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);//CentericoninclientrectangleintcxIcon=GetSystemMetrics(SM_CXICON);intcyIcon=GetSystemMetrics(SM_CYICON);CRectrect;GetClientRect(&rect);intx=(rect.Width()-cxIcon+1)/2;inty=(rect.Height()-cyIcon+1)/2;//Drawtheicondc.DrawIcon(x,y,m_hIcon);}else{CPaintDCdc(this);//devicecontextforpaintingdc.MoveTo(10,10);dc.LineTo(100,100);dc.Ellipse(120,120,160,160);CDialog::OnPaint();}}2.1voidCBmpTestDlg::OnPaint(){if(IsIconic()){//与前一页代码相同;else{CPaintDCdc(this);//devicecontextforpaintingCPennewpen(PS_SOLID,1,RGB(0,255,0));CBrushnewbrush(RGB(0,0,255));CPen*pOldpen=dc.SelectObject(&newpen);CBrush*pOldbrush=dc.SelectObject(&newbrush);dc.MoveTo(10,10);dc.LineTo(100,100);dc.Ellipse(80,80,120,120);dc.SelectObject(pOldpen);dc.SelectObject(pOldbrush);CDialog::OnPaint();}}4.改变画图颜色5.1代码解释:1.CPennewpen(PS_SOLID,1,RGB(0,255,0));生成一支颜色为绿色、宽度为1个像素的实心画笔。2.CBrushnewbrush(RGB(0,0,255));生成一只颜色为蓝色的画刷。3.CPen*pOldpen=dc.SelectObject(&newpen);把刚生成的画笔选进设备环境对象dc,这样再画线就用新的笔了。当SelectObject函数的参数为画笔类型时,返回值为原来所用画笔的指针。4.CBrush*pOldbrush=dc.SelectObject(&newbrush);把刚生成的画刷选进设备环境对象dc。当SelectObject函数的参数为画刷类型时,返回值为原来所用画刷的指针。5.dc.SelectObject(pOldpen);绘图完毕后把原来的画笔再选进设备环境对象。6.dc.SelectObject(pOldbrush);绘图完毕后把原来的画刷再选进设备环境对象。Cpen类的构造函数声明是:CPen(intnPenStyle,intnWidth,COLORREFcrColor);参数nPenStyle指明画笔的风格。nWidth指明以象素为单位的画笔宽度。crColor包含了画笔的RGB值。nPenStyle的取值有以下几种:PS_SOLD:创建一支实线画笔。PS_DASH:创建一支虚线画笔。PS_DOT:创建一支点线画笔。PS_DASHDOT:创建一支虚线和点交替的画笔。PS_DASHDOTDOT:创建一支虚线和两点交替的画笔。5.2GDI和CGdiObject类学习目标1.了解图形设备接口2.了解类CGdiObject极其派生类5.2返回第5章绘图程序实例一1.用应用向导产生单文档程序框架(BmpTest)2.修改、添加资源1.添加菜单1.ID_GRAPH_TRACK轨迹2.ID_GRAPH_MOVE移动2.添加位图1.IDB_BIT12.IDB_BIT23.添加数据类型及变量5.2classCMoveTestView:publicCView{protected://createfromserializationonlyCMoveTestView();DECLARE_DYNCREATE(CMoveTestView)private:CStringflag;BOOLdrawtrack;structpointstruct{CPointpoint;structpointstruct*next;};structpointstruct*pointlisthead,*pointlisttrail;……}5.2flag:判断选择的是“轨道”菜单项还是“车轮”菜单项按钮;drawtrack:当用户选择轨道菜单项时,判断是否画轨道;structpointstruct:用来记录轨道中各个点的结构体;pointlisthead:用户所绘制轨道的点链表的头结点;pointlisttrail:用户所绘制轨道的点链表的尾结点。4.添加函数1.添加菜单响应函数5.2voidCMoveTestView::OnGraphMove(){flag=move;MoveObject();}voidCMoveTestView::OnGraphTrack(){flag=track;}代码解释:1.当选择菜单“轨迹”时,把flag赋值为“track”;2.当选择菜单“移动”时,把flag赋值为“move”;3.MoveObject();调用此函数可产生沿着画好轨道运动的车轮。该函数将在后面给出。2.添加鼠标响应函数5.2voidCMoveTestView::OnLButtonDown(UINTnFlags,CPointpoint){if(flag==track){structpointstruct*temppoint;while(pointlisthead){temppoint=pointlisthead;pointlisthead=pointlisthead-next;deletetemppoint;}drawtrack=true;}CView::OnLButtonDown(nFlags,point);}5.2voidCMoveTestView::OnMouseMove(UINTnFlags,CPointpoint){if(drawtrack){CClientDCdc(this);dc.SetPixel(point.x,point.y,RGB(0,0,0));structpointstruct*newpoint=newstructpointstruct;newpoint-point.x=point.x;newpoint-point.y=point.y;newpoint-next=NULL;if(pointlisthead==NULL){pointlisthead=pointlisttrail=newpoint;}else{pointlisttrail-next=newpoint;pointlisttrail=newpoint;}}CView::OnMouseMove(nFlags,point);}5.2voidCMoveTestView::OnLButtonUp(UINTnFlags,CPointpoint){if(drawtrack)drawtrack=false;CView::OnLButtonUp(nFlags,point);}1.当按下鼠标左键时调用函数,如果当前用户选择的是“轨迹”菜单,说明用户要绘制轨道,则把变量drawtrack赋值为真,此时鼠标移动则绘制轨道。2.当在视图窗口中移动鼠标时,根据变量drawtrack判断是否要绘制轨道,在绘制轨道时首先创建设备环境对象dc。调用函数SetPixel(point.x,point.y,RGB(0,0,0))在鼠标当前点画点。并把鼠标当前点加入轨迹链表。3.当鼠标左键抬起时,如果变量drawtrack为真,把他设置为假以结束轨迹绘制。此后,鼠标再移动,将不再绘制轨迹,除非在flag==“track”时再按下鼠标左键。5.构造函数中将drawtrack初始化为FALSE5.2CMoveTestView::CMoveTestView(){//TODO:addconstructioncodeheredrawtrack=false;pointlisthead=NULL;}6.MoveObject()函数voidCMoveTestView::MoveObject(){structpointstruct*pointtemp=pointlisthead;inti=1;CPointpointold;BOOLfirst=true;while(pointtemp){CClientDCdc(this);CDC*memdc=newCDC;memdc-CreateCompatibleDC(&dc);if(!first){CBitmapbitmap1;if(i%2==0)bitmap1.LoadBitmap(IDB_BIT1);elsebitmap1.LoadBitmap(IDB_BIT2);//DSTINVERTmemdc-SelectObject(&bitmap1);dc.BitBlt(pointold.x-24,pointold.y-24,48,48,memdc,0,0,PATPAINT);}elsefirst=false;CBitmapbitmap;if(i%2)bitmap.LoadBitmap(IDB_BIT1);elsebitmap.LoadBitmap(IDB_BIT2);memdc-SelectObject(&bitmap);dc.BitBlt(pointtemp-point.x-24,pointtemp-point.y-24,48,48,memdc,0,0,SRCAND);pointold.x=pointtemp-point.x;pointold.y=pointtemp-point.y;deletememdc;pointtemp=pointtemp-next;i++;for(intj=0;j5000000;j++);}pointtemp=pointlisthead;while(pointt