0

MFC:我读到这段代码是为了绘制一个椭圆(不是实心内部),但我不明白为什么这里需要两次函数“pDC->Ellipse(...)”?(溶胶 == 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->Ellipse(...) 的第一次调用,椭圆内部将是黑色实心。如果我删除对 pDC->Ellipse(...) 的第二次调用,椭圆将永远不会被绘制,但会在鼠标左键向上时消失。

对话框:移动鼠标时: 在此处输入图像描述 鼠标移动(笔为绿色)

鼠标按钮弹出时: 在此处输入图像描述 鼠标按钮弹出(笔为绿色)

另外,如果我使用“CBrush画笔;pDC->Ellipse(start.x,assist.y,end.x,end.y);”,CBrush是什么颜色?

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

             ...
    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;
        } 
            ...
4

3 回答 3

1

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

于 2012-09-21T14:30:33.567 回答
0

椭圆是用当前画笔绘制的,它的内部是用当前画笔填充的。

来自MSDNCDC::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);

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

 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,所以像素保持不变(所以灰色背景)所以我们最终用与背景颜色相同的笔绘制椭圆,所以它从未见过。

您确实需要调试以查看发生了什么,但如果您可以找出每个点的笔颜色和画笔颜色,您应该对正在发生的事情有一个很好的了解。

于 2012-09-21T15:36:08.500 回答
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->SetROP2(R2_NOT);” 一次和“p->drawEllipse(point, pDC, 1);” 在同一个地方两次保存原始像素以获得画线效果。最后调用“pDC->SetROP2(R2_COPYPEN); p->drawEllipse(point, pDC, 1)”是我们真正需要看到省略号的地方。感谢您的所有帮助。

于 2012-09-23T02:04:38.143 回答