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(...)的第二次调用,则永远不会绘制椭圆,但是当鼠标左键按下时椭圆会消失。
对话框: 移动鼠标时: 鼠标移动(笔是绿色)
鼠标按钮弹出时: 鼠标按钮弹出(笔是绿色)
此外,如果我使用的话,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;
}
...
答案 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_COPYPEN
,states要使用的像素是当前的笔颜色。我的猜测是笔是黑色的,椭圆被填充为黑色(读取上面关于用于填充椭圆的画笔的椭圆描述)。
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)”是我们真正需要看到的省略号。 感谢您的帮助。