0

MFC: 楕円 (中実ではない) を描画するこのコードを読みましたが、関数 "pDC->Ellipse(...)" がここで 2 回必要な理由がわかりません。(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->Ellipse(...) への最初の呼び出しを削除すると、楕円は内側が黒く塗りつぶされます。pDC->Ellipse(...) への 2 番目の呼び出しを削除すると、楕円は描画されず、マウスの左ボタンを離すと消えます。

ダイアログ: マウスの移動時: ここに画像の説明を入力 マウスの移動 (ペンは緑色)

マウス ボタン ポップ時: ここに画像の説明を入力 マウス ボタン ポップ (ペンは緑色)

また、「CBrush brush; 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

楕円は現在のペンで描画され、その内部は現在のブラシで塗りつぶされます。

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。私の推測では、ペンは黒で、楕円は黒で塗りつぶされます (楕円を塗りつぶすために使用されるブラシについては、上記の楕円の説明をお読みください)。

 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);

したがって、2 番目の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);」元のピクセルを保存して線画効果を得るために同じ場所で 2 回。そして、"pDC->SetROP2(R2_COPYPEN); p->drawEllipse(point, pDC, 1)" への最後の呼び出しは、省略記号を表示するために本当に必要なものです。いつもお世話になっております。

于 2012-09-23T02:04:38.143 に答える