问题
MFC: I read this code which is to draw an ellipse (not solid interior), but I cannot understand why function "pDC->Ellipse(...)" is needed twice here? (sol == 0, and 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);
}
If I remove the first call to pDC->Ellipse(...), the ellipse will be black solid inside. If I remove the second call to pDC->Ellipse(...), the ellipse will never be drawn but disappears when left mouse button is up.
the dialog: when moving mouse:
mouse moving(the pen is green)when mouse button pops:
mouse button pops(the pen is green)Besides, what color of CBrush is if I use "CBrush brush; pDC->Ellipse(start.x,assist.y,end.x,end.y);"
the strategy may be more clear when it comes to rectangle:
...
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;
}
...
回答1:
It's because of the call to pDC->SetROP2(R2_NOT)
. The R2_NOT
flag means "Pixel remains unchanged.", according to MSDN. You can read the documentation here - http://msdn.microsoft.com/en-us/library/99ax95h9.aspx.
回答2:
The ellipse is drawn with the current pen, and its interior is filled with the current brush.
From the CDC::Ellipse()
reference from MSDN
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);
So our ROP is R2_COPYPEN
which states that the pixel to use is the current pen color. My guess is that the pen is black and the ellipse gets filled in as black (read ellipse description above about brush being used to fill 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);
So if we delete the 2nd Ellipse
call then we use R2_NOT
, so the pixel remains the same (so the gray background) so we end up drawing the ellipse with a pen the same color as the background, so it's never seen.
You really need to debug to see what's going on but if you can find out the pen color and brush color at each point, you should get a good idea of what's going on.
回答3:
I finally get out of the trouble: codes elsewhere:
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);
}
So, the strategy is: Using "pDC->SetROP2(R2_NOT);" once and "p->drawEllipse(point, pDC, 1);" twice in the same place to save the original pixels to get the line-drawing effects. And the final call to "pDC->SetROP2(R2_COPYPEN); p->drawEllipse(point, pDC, 1)" is what we really need to see the ellipsis. Thank you for all your helps.
来源:https://stackoverflow.com/questions/12532470/why-function-ellipse-are-needed-twice-here-to-draw-an-ellipse