为什么在这里需要两次函数Ellipse(...)来绘制椭圆?

时间:2012-09-21 14:24:37

标签: c++ mfc cdc

MFC: 我读了这个用于绘制椭圆(不是实心内部)的代码,但我不明白为什么函数“pDC-> Ellipse(...)”需要两次? (sol == 0,do_what == DRAW_ELLIPSE)

void CMy078207017Dlg::OnLButtonUp(UINT nFlags, CPoint point) 
{
        flag = 0;
    end = point;
    assist = point;
    if(p != NULL)
    {
        CDC* pDC = GetDC();
        CPen pen;
        CBrush brush;
        getpen(pen, pDC, col, bol);
        if(do_what >= DRAW_LINE && do_what <= DRAW_RRECT)
        {
            p->p[0] = start;
            p->p[1] = end;
        }

        if(sol == 1)
        {
            getbrush(brush, pDC, col);
        }

        if(do_what == DRAW_LINE)
        {
            pDC->MoveTo(start);
            pDC->LineTo(end);
        }
        else
        {
            if(do_what == DRAW_ELLIPSE || do_what == DRAW_CIRCLE)
            {

                assist = start;
                if(do_what == DRAW_CIRCLE)
                {
                    assist.y = end.y - end.x + start.x;
                }


                pDC->SetROP2(R2_NOT);
                pDC->Ellipse(start.x, assist.y, end.x, end.y);


                pDC->SetROP2(R2_COPYPEN);
                if(sol == 0)
                {
                    pDC->SelectStockObject(NULL_BRUSH);
                }
                pDC->Ellipse(start.x, assist.y, end.x, end.y);


                end = point;
            }

        }
        ReleaseDC(pDC);
    }
    CDialog::OnLButtonUp(nFlags, point);
}

如果我删除第一次调用pDC-&gt; Ellipse(...),椭圆将在内部为黑色实体。 如果我删除了对pDC-&gt; Ellipse(...)的第二次调用,则永远不会绘制椭圆,但是当鼠标左键按下时椭圆会消失。

对话框:    移动鼠标时:        enter image description here 鼠标移动(笔是绿色)

鼠标按钮弹出时:         enter image description here 鼠标按钮弹出(笔是绿色)

此外,如果我使用的话,CBrush的颜色是什么 “CBrush brush; pDC-&gt; Ellipse(start.x,assist.y,end.x,end.y);”

当谈到矩形时,策略可能会更清晰:

             ...
    else if(do_what==DRAW_RECT||do_what==DRAW_RRECT){

            pDC->SetROP2(R2_NOT);
            if(do_what==DRAW_RECT)
            {
                pDC->Rectangle(start.x,start.y,end.x,end.y);
            }
            else if(do_what==DRAW_RRECT)
            {
                pDC->RoundRect(start.x,start.y,end.x,end.y,20,20);
            }


            pDC->SetROP2(R2_COPYPEN);
            if(sol==0)
            {   
                pDC->SelectStockObject(NULL_BRUSH);
            }
            if(do_what==DRAW_RECT)
            {
                pDC->Rectangle(start.x,start.y,point.x,point.y);
            }
            else if(do_what==DRAW_RRECT)
            {
                pDC->RoundRect(start.x,start.y,point.x,point.y,20,20);
            }
            end=point;
        } 
            ...

3 个答案:

答案 0 :(得分:1)

这是因为对pDC->SetROP2(R2_NOT)的调用。根据MSDN,R2_NOT标志意味着“Pixel保持不变。”您可以在此处阅读文档 - http://msdn.microsoft.com/en-us/library/99ax95h9.aspx

答案 1 :(得分:0)

  

用当前笔绘制椭圆,其内部用当前笔刷填充。

来自MSDN

CDC::Ellipse()参考
 pDC->SetROP2(R2_NOT);

 // pDC->Ellipse(start.x,assist.y,end.x,end.y);
 pDC->SetROP2(R2_COPYPEN);
 if(sol==0){
           pDC->SelectStockObject(NULL_BRUSH);
     }
 if(do_what==DRAW_CIRCLE){
           assist.y=point.y-point.x+start.x;
     }
 pDC->Ellipse(start.x,assist.y,point.x,point.y);

所以我们的ROP是R2_COPYPENstates要使用的像素是当前的笔颜色。我的猜测是笔是黑色的,椭圆被填充为黑色(读取上面关于用于填充椭圆的画笔的椭圆描述)。

 pDC->SetROP2(R2_NOT);

 pDC->Ellipse(start.x,assist.y,end.x,end.y);
 pDC->SetROP2(R2_COPYPEN);
 if(sol==0){
           pDC->SelectStockObject(NULL_BRUSH);
     }
 if(do_what==DRAW_CIRCLE){
           assist.y=point.y-point.x+start.x;
     }
 // pDC->Ellipse(start.x,assist.y,point.x,point.y);

因此,如果我们删除第二个Ellipse调用,那么我们使用R2_NOT,因此像素保持不变(因此灰色背景),因此我们最终使用与此颜色相同的笔绘制椭圆背景,所以它从未见过。

你真的需要调试才能看到发生了什么,但如果你能找到每个点上的笔颜色和刷子颜色,你应该知道发生了什么。

答案 2 :(得分:0)

我终于摆脱了麻烦:     其他地方的代码:

void CDraw2009303476Dlg::OnMouseMove(UINT nFlags, CPoint point) 
{
    if(flag == 1)   
    {
        CDC* pDC = GetDC();
        CPen pen;
        CBrush brush;
        getPen(pen, pDC, col, bol);

        if(sol == 1)
        {
            getBrush(brush, pDC, col);
        }
        if(type >= DRAW_LINE && type <= DRAW_RRECT)
        {
            pDC->SetROP2(R2_NOT);
            if(type == DRAW_LINE)
            {
                p->drawLine(point, pDC);
            }
            else if(type == DRAW_ELLIPSE)
            {
                p->drawEllipse(point, pDC);
            }
            else if(type == DRAW_CIRCLE)
            {
                p->drawEllipse(point, pDC, 1);
            }
            else if(type == DRAW_RECT)
            {
                p->drawRect(point, pDC);
            }
            else if(type == DRAW_RRECT)
            {
                p->drawRect(point, pDC, 1);
            }
        }
        ReleaseDC(pDC);
    }
    CDialog::OnMouseMove(nFlags, point);
}

所以,策略是:使用“pDC-&gt; SetROP2(R2_NOT);”一次和“p-&gt; drawEllipse(point,pDC,1);”在同一个地方两次保存原始像素以获得线条绘制效果。 最后调用“pDC-&gt; SetROP2(R2_COPYPEN); p-&gt; drawEllipse(point,pDC,1)”是我们真正需要看到的省略号。 感谢您的帮助。