你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 图形图象处理与游戏编程
在GDI+中利用双缓存技术实现橡皮筋效果(二)
 

4)在CDBufferView中添加成员变量:

    int m_nDrawTool;    //绘图工具选择

    int m_nButtonDown;  //按钮按下次数

    Bitmap* m_pBitmap;  //虚拟画布

    Graphics* m_pGP;    //虚拟画布图像对象指针

    CArray<CPoint,CPoint> m_PointList; //记录图形各顶点坐标

5)在CDBufferView::CDBufferView()中添加初始化代码:

    m_nDrawTool=0;

    m_nButtonDown=0;

    m_pBitmap=NULL;

    m_pGP=NULL;

    CDBufferView::OnInitialUpdate()中创建虚拟画布(缓存):

    m_pBitmap = new Bitmap(800,600,PixelFormat32bppARGB);//建立800×600的图像

    m_pGP=new Graphics(m_pBitmap);//建立图像对象,用于在虚拟画布上绘制图像

    m_pGP->Clear(Color::White);//必须有,用背景色填充画布;

    CDBufferView::~CDBufferView()中释放占用的资源:

    if(m_pBitmap!=NULL) delete m_pBitmap;

    if(m_pGP!=NULL) delete m_pGP;

    if(m_PointList.GetCount()>0)m_PointList.RemoveAll();

6)分别建立直线、矩形、椭圆和曲线的菜单命令方法:

void CDBufferView::OnDrawLine()

{   this->m_nDrawTool=0;} //当前状态设为画直线

void CDBufferView::OnUpdateDrawLine(CCmdUI *pCmdUI)

{   pCmdUI->SetCheck(this->m_nDrawTool==0);}

void CDBufferView::OnDrawRectangle()

{   this->m_nDrawTool=1;} //当前状态设为画矩形

void CDBufferView::OnUpdateDrawRectangle(CCmdUI *pCmdUI)

{   pCmdUI->SetCheck(this->m_nDrawTool==1);}

void CDBufferView::OnDrawEllipse()

{   this->m_nDrawTool=2;} //当前状态设为画椭圆

void CDBufferView::OnUpdateDrawEllipse(CCmdUI *pCmdUI)

{   pCmdUI->SetCheck(this->m_nDrawTool==2); }

void CDBufferView::OnDrawCurve()

{   this->m_nDrawTool=3;}//当前状态设为画曲线

void CDBufferView::OnUpdateDrawCurve(CCmdUI *pCmdUI)

{   pCmdUI->SetCheck(this->m_nDrawTool==3);}

7)建立鼠标左键按下事件响应函数,并添加如下代码:

void CDBufferView::OnLButtonDown(UINT nFlags, CPoint point)

{   if(m_nDrawTool>=0 && m_nDrawTool<=3)

    {

        if(m_nButtonDown==0)

        {   if(m_PointList.GetCount()>0) m_PointList.RemoveAll();}

        m_PointList.Add(point);//记录鼠标单击点

        m_nButtonDown++;

    }

    CView::OnLButtonDown(nFlags, point);

}

8)建立鼠标移动事件响应函数,并添加如下代码:

void CDBufferView::OnMouseMove(UINT nFlags, CPoint point)

{

    Bitmap* tempBitmap=m_pBitmap->Clone(0,0,m_pBitmap->GetWidth(), m_pBitmap->GetHeight(), PixelFormat32bppARGB); //建立虚拟画布副本

    Graphics* pgp=new Graphics(tempBitmap);

    PointF* tempPoint;

    CPoint tempP;

    switch(this->m_nDrawTool)

    {

    case 0:

        if(m_nButtonDown>=1)

        {

            tempPoint=new PointF[2];

            tempP=m_PointList.GetAt(0);

            tempPoint[0].X=(REAL)tempP.x; tempPoint[0].Y=(REAL)tempP.y;

            tempPoint[1].X=(REAL)point.x; tempPoint[1].Y=(REAL)point.y;

            Pen pen(Color::Black,1.0f);

            pgp->DrawLine(&pen,tempPoint[0],tempPoint[1]);//画布副本上绘制直线

            delete[] tempPoint;

        }

        break;

    case 1:

        if(m_nButtonDown>=1)

        {

            tempP=m_PointList.GetAt(0);

            Pen pen(Color::Black,1.0f);

            REAL tempX=(REAL)min(tempP.x,point.x);

            REAL tempY=(REAL)min(tempP.y,point.y);

            REAL tempW=(REAL)(tempP.x>point.x?tempP.x-point.x:point.x-tempP.x);

            REAL tempH=(REAL)(tempP.y>point.y?tempP.y-point.y:point.y-tempP.y);

            pgp->DrawRectangle(&pen,tempX,tempY,tempW,tempH);//副本画布上绘制矩形

        }

        break;

    case 2://绘制椭圆,方法与矩形类似,省略

        break;

    case 3://绘制曲线,略

        break;

    }

    Graphics gp(this->GetSafeHwnd());

    gp.DrawImage(tempBitmap,0,0);//将画布副本复制到屏幕

    delete tempBitmap;  delete pgp;

    CView::OnMouseMove(nFlags, point);

}

9)建立鼠标左键按下事件响应函数,并添加如下代码:

void CDBufferView::OnLButtonUp(UINT nFlags, CPoint point)

{

    // TODO: Add your message handler code here and/or call default

    ::SetCursor(s_Cross);

    Graphics gp(this->GetSafeHwnd());

    PointF* tempPoint;

    CPoint tempP;

    switch(this->m_nDrawTool)

    {

    case 0://在虚拟画布上画直线并将虚拟画布复制到屏幕上

        if(m_nButtonDown>=1)

        {

            tempPoint=new PointF[2];

            tempP=m_PointList.GetAt(0);

            tempPoint[0].X=(REAL)tempP.x;

            tempPoint[0].Y=(REAL)tempP.y;

            tempPoint[1].X=(REAL)point.x;

            tempPoint[1].Y=(REAL)point.y;

            Pen pen(Color::Black,1.0f);

            m_pGP->DrawLine(&pen,tempPoint[0],tempPoint[1]);

            m_nButtonDown=0;

            delete[] tempPoint;

        }

        gp.DrawImage(m_pBitmap,0,0);//复制缓存区数据到屏幕

        break;

    case 1://在虚拟画布画矩形并复制到屏幕上,略

        break;

    case 2://在虚拟画布画椭圆并复制到屏幕上,略

        break;

    }

    CView::OnLButtonUp(nFlags, point);

}

程序在Visual Studio2005Windows2003环境调试通过,下面是运行效果图,如图2,图3,图4,图5所示。


2 画直线


3 画矩形


4 画椭圆


5 画曲线

  

六、总结

在交互式绘图系统中,使用橡皮筋技术是经常遇到的一个实际问题,而GDI+具有比GDI更方便的开发方法和更美观的图像效果,在软件开发中应用得越来越广泛。本文应用双缓存技术解决在GDI+绘图过程中的橡皮筋技术问题,使图形的绘制过程更加直观。
  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089