图形简单绘制擦除

    现在流行的VC书上基本都有简单的绘图程序,但是大都是先点一个点,再点一个点,这样要画的图形就出来了。这中间没有任何的演示过程,不到最后不知道自己画的是什么。本章想要显示给大家绘图程序应该显示绘制的过程,鼠标移动时绘制的是什么图形要实时显示出来。我先做一个平常书上的画图程序给大家看。

1,首先建一个名为“bookGraphic”的单文档应用程序。在ResourcesView下的菜单IDR_MAINFRAME中添加几个菜单,如下:

子菜单:画图

菜单项:直线        IDM_DRAW_LINE

矩形        IDM_DRAW_RECT

此系统只绘制直线和矩形,看看效果而已。

2,现在添加消息响应,因为要绘制图形,而绘制图形要在视区中显示,所以把消息响应到View类中,此系统是CBookGraphicView类。利用ClassWizard添加消息响应。响应的消息中应该标识选中了哪个功能。因为这两个功能是不能同时存在的,所以可以用一个变量来分辨,如m_nDrawType。我们为了比较容易阅读程序,这里定义一个枚举,如下:

int m_nDrawType;

enum DRAWTYPE

{

    DRAW_NONE       = 0,    // 不绘制图形

    DRAW_LINE       = 1,    // 绘制直线

    DRAW_RECT       = 2,    // 绘制矩形

};

这样就避免了用12来表示选择的是直线还是矩形。

3,绘制直线和矩形都是需要两点来确定的,为了保存第一个点---起始点,所以在CBookGraphicView类中要定义一个CPoint类的对象,CPoint m_ptOrign。因为起始点和终止点都是在鼠标弹起的消息中进行的,所以要区分当时处于哪个状态,是取起始点还是确定绘制。需要定义一个变量来区分:int m_nStep;

到现在需要的变量已经定义好了,需要在CBookGraphicView类中初始化:

CBookGraphicView::CBookGraphicView()

{

    // TODO: add construction code here

    m_ptOrign = 0;

    m_nDrawType = DRAW_NONE;    // 这个是必须的,因为系统刚开始时是没有选择绘制的图形的。我没有设置默认O(_)O~ 

m_nStep = 0;                // 0---表示没有开始步骤,1---代表绘制了第一步,2---代表绘制了第二步,3---代表绘制了第三步,此系统只有两步就完成绘制。

}

4,现在对上面的两个消息响应函数进行处理,很简单,只是指定选择绘制的是什么图形和让绘制的步骤归0即可。

void CBookGraphicView::OnDrawLine()

{

    // TODO: Add your command handler code here

    m_nDrawType = DRAW_LINE;

    m_nStep = 0;

}

 

void CBookGraphicView::OnDrawRect()

{

    // TODO: Add your command handler code here

    m_nDrawType = DRAW_RECT;

    m_nStep = 0;

}

5,在CBookGraphicView类中响应OnLButtonUp消息做绘图过程:

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

{

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

    ASSERT(m_nDrawType >= DRAW_NONE);

    if (m_nDrawType < DRAW_NONE)

    {

        CView::OnLButtonUp(nFlags, point);

        return;

    }

    if (DRAW_NONE == m_nDrawType)

    {// 没有选择要绘制的图形,所以直接退出函数

        CView::OnLButtonUp(nFlags, point);

        return;

    }

    if (0 == m_nStep)

    {

        m_ptOrign = point;

        ++m_nStep;      // 标记已经过了第一步

    }

    else if (1 == m_nStep)

    {

        CClientDC dc(this);

        switch (m_nDrawType)

        {

        case DRAW_NONE:

            break;

        case DRAW_LINE:

            dc.MoveTo(m_ptOrign);

            dc.LineTo(point);

            m_nStep = 0;

            break;

        case DRAW_RECT:

            dc.SelectStockObject(NULL_BRUSH);   // dc置空画刷

            dc.Rectangle(CRect(m_ptOrign, point));

            m_nStep = 0;

            break;

        default:break;

        }

    }

    CView::OnLButtonUp(nFlags, point);

}

这样超简单的绘图程序就完成了。。。。。。。

现在要制作新的系统了,注意看…….

首先新建一个名为myGraphic的单文档应用程序,按照上面得步骤做到第3步。我们要实现在绘制过程中图形是出现的,而且是跟这鼠标一起走的,这里要定义一个记录在鼠标移动过程中的点,CPoint m_prPreMoving;在构造函数中置零。第4不也同上…….

现在看绘图过程,其实实现上面的效果很简单只是第一次擦除上次画的图形,第二次绘制新的图形。只是改了一下绘图的模式,具体代码如下:

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

{

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

    ASSERT(m_nDrawType >= DRAW_NONE);

    if (m_nDrawType < DRAW_NONE)

    {

        CView::OnLButtonUp(nFlags, point);

        return;

    }

    if (0 == m_nStep)

    {

        m_ptOrign = point;

        m_ptPreMoving = point;

        m_nStep = 1;

    }

    else if (1 == m_nStep)

    {

        CClientDC dc(this);

        int nOldMode = dc.SetROP2(R2_NOTXORPEN);// 去系统的反色

        switch (m_nDrawType)

        {

        case DRAW_NONE:

            break;

        case DRAW_LINE:

// 擦除图形

            dc.MoveTo(m_ptOrign);

            dc.LineTo(m_ptPreMoving);

// 绘制新的图形

            dc.MoveTo(m_ptOrign);

            dc.LineTo(point);

            break;

        case DRAW_RECT:

            dc.SelectStockObject(NULL_BRUSH);

            dc.Rectangle(CRect(m_ptOrign, m_ptPreMoving));

            dc.Rectangle(CRect(m_ptOrign, point));

            break;

        default:

            break;

        }

        m_nStep = 0;

        dc.SetROP2(nOldMode);

    }

    CView::OnLButtonUp(nFlags, point);

}

 

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

{

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

    if (m_nDrawType <= 0 || 0 == m_nStep)

    {

        CView::OnMouseMove(nFlags, point);

        return;

    }

    if (1 == m_nStep)

    {

        CClientDC dc(this);

        int nOldMode = dc.SetROP2(R2_NOTXORPEN);

        switch (m_nDrawType)

        {

        case DRAW_NONE:

            break;

        case DRAW_LINE:

            // 擦除图形

            dc.MoveTo(m_ptOrign);

            dc.LineTo(m_ptPreMoving);

            // 绘制新的图形

            dc.MoveTo(m_ptOrign);

            dc.LineTo(point);

            break;

        case DRAW_RECT:

            // 擦除图形

            dc.Rectangle(CRect(m_ptOrign, m_ptPreMoving));

            // 绘制新的图形

            dc.Rectangle(CRect(m_ptOrign, point));

            break;

        default:

            break;

        }

        m_ptPreMoving = point;

        dc.SetROP2(R2_NOTXORPEN);

    }

    CView::OnMouseMove(nFlags, point);

}

到这里可以看到绘制的效果了,和上面的不一样吧,O(_)O~。主要是使用了CClient类的SetROP2函数改变了绘制的模式,但是绘制完成后要把dc的绘制模式还原。这里只是简单的绘制图形,还未实现重绘,未使用类的继承、多态,等下次有时间吧。过不了几天的。。。。。。。

写完时,听到了刘德华的《冰雨》,很好听的一首歌。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值