Zeichnen - Brush mit 2 Farben



  • Hi,
    gibts irgend ne möglichkeit mit reiner MFC (bitte keine GDI+) ein Rect oder Chord mit 2 Farben zu füllen die ineinander fließen? Das Obejkt sollte links mit grün anfangen und bis zum anderen ende 100% durchsichtig sein.
    Hat die MFC da irgend was? Oder muss ich wirklich wegen dem einen ding GDI+ oder DirectX mit hinein nehmen.. 😕



  • Ich hab sowas ma geschrieben 😉



  • meine e-mail addy kennst ja :p



  • int Round(double dToRound)
    {
        int iTmp=dToRound;
        double dTmp=(dToRound-iTmp);
        if(dTmp<0)
            dTmp*=-1.0;
        if(dTmp<0.5)
            return iTmp;
        if(dToRound<0)
            return iTmp-1;
        return iTmp+1;
    }
    
    #define VERT 0
    #define HOR  1
    
    void DrawGradient(CDC *pDC, CRect Rect, COLORREF Color1, COLORREF Color2, bool bDirection)
    {
        float blue1,blue2,green1,green2,red1,red2;
        float blue_change,green_change,red_change;
    
        blue1=GetBValue(Color1);
        green1=GetGValue(Color1);
        red1=GetRValue(Color1);
    
        blue2=GetBValue(Color2);
        green2=GetGValue(Color2);
        red2=GetRValue(Color2);
    
        int nDiv = 0;
        if(bDirection == VERT)
            nDiv = Rect.Height();
        else
            nDiv = Rect.Width();
    
        blue_change=float(blue2-blue1)/float(nDiv-1);
        green_change=float(green2-green1)/float(nDiv-1);
        red_change=float(red2-red1)/float(nDiv-1);
    
        for (int x=0;x<nDiv;++x)
        {
            CPen Pen, *pOldPen=NULL;
            Pen.CreatePen(PS_SOLID,1,RGB(red1, green1, blue1));
            pDC->SelectObject(&Pen);
            if(bDirection == VERT)
            {
                pDC->MoveTo(Rect.left,x+Rect.top);
                pDC->LineTo(Rect.right,x+Rect.top);
            }
            else
            {
                pDC->MoveTo(x+Rect.left,Rect.top);
                pDC->LineTo(x+Rect.left,Rect.bottom);
            }
            pDC->SelectObject(pOldPen);
    
            blue1+=blue_change;
            green1+=green_change;
            red1+=red_change;
        }
    }   
    
    void DrawDiagonalGradient(CDC *pDC,CPoint UpperLeftCorner, int nLength, COLORREF Color1, COLORREF Color2)
    {
        float blue1,blue2,green1,green2,red1,red2;
        float blue_change,green_change,red_change;
    
        blue1=GetBValue(Color1);
        green1=GetGValue(Color1);
        red1=GetRValue(Color1);
    
        blue2=GetBValue(Color2);
        green2=GetGValue(Color2);
        red2=GetRValue(Color2);
    
        blue_change=float(blue2-blue1)/float(nLength*2-1);
        green_change=float(green2-green1)/float(nLength*2-1);
        red_change=float(red2-red1)/float(nLength*2-1);
    
        for (int x=0;x<nLength*2;++x)
        {
            CPen Pen, *pOldPen=NULL;
            Pen.CreatePen(PS_SOLID,1,RGB(red1, green1, blue1));
            pDC->SelectObject(&Pen);
            if(x<nLength)
            {
                pDC->MoveTo(UpperLeftCorner.x+x,UpperLeftCorner.y);
                pDC->LineTo(UpperLeftCorner.x-1,UpperLeftCorner.y+x+1);
            }
            else
            {
                pDC->MoveTo(UpperLeftCorner.x+nLength,UpperLeftCorner.y+x-nLength);
                pDC->LineTo(UpperLeftCorner.x+x-nLength,UpperLeftCorner.y+nLength);
            }
            pDC->SelectObject(pOldPen);
    
            blue1+=blue_change;
            green1+=green_change;
            red1+=red_change;
        }
    }
    
    void DrawGradientCircle(CDC *pDC, CPoint UpperLeftCorner, int nLength, COLORREF Color1, COLORREF Color2, COLORREF PenColor=-1)
    {
        CBitmap Bmp;
        Bmp.CreateCompatibleBitmap(pDC,nLength,nLength);
        CDC dc;
        dc.CreateCompatibleDC(pDC);
        dc.SelectObject(&Bmp);
        DrawDiagonalGradient(&dc,CPoint(0,0),nLength,Color1,Color2);
        CBitmap BmpMask;
        BmpMask.CreateBitmap(nLength,nLength,1,1,NULL);
        CBitmap BmpMaskTmp;
        BmpMaskTmp.CreateCompatibleBitmap(pDC,nLength,nLength);
        CDC dcMask;
        dcMask.CreateCompatibleDC(pDC);
        dcMask.SelectObject(&BmpMaskTmp);
        dcMask.FillSolidRect(0,0,nLength,nLength,0);
        CPen Pen;
        Pen.CreatePen(PS_SOLID,1,(COLORREF)0);
        CBrush Brush;
        Brush.CreateSolidBrush(1);
        dcMask.SelectObject(&Pen);
        dcMask.SelectObject(&Brush);
        dcMask.Ellipse(0,0,nLength,nLength);
        int *pnBits = new int[nLength*nLength];
        BmpMaskTmp.GetBitmapBits(nLength*nLength*4,pnBits);
        float fNeededBytes = (float)nLength/8.0;
        int nBytesPerRow = 0;
        int nTmp = (int)fNeededBytes%2;
        if(!((int)fNeededBytes%2))
        {
            if((int)fNeededBytes==fNeededBytes)
                nBytesPerRow = (int)fNeededBytes;
            else
                nBytesPerRow = (int)fNeededBytes+2;
        }
        else
        {
            nBytesPerRow=(int)fNeededBytes+1;
        }
        char *pcBits = new char[nBytesPerRow*nLength];
        char cTmp=0;
        char cTmp2=0;
        int nRemainingBits = 0;
        for(int i=1,j=1,n=0;i<=nLength*nLength;++i,++j)
        {
            if(pnBits[i-1]>0)
                cTmp2=1;
            else
                cTmp2=0;
            cTmp = cTmp+cTmp2*pow(2,8-j);
            if(j==8)
            {
                j=0;
                pcBits[n] = cTmp;
                cTmp = cTmp2 = 0;
                ++n;
            }
            if(!(i%nLength)&&i)
            {
                nRemainingBits = (nBytesPerRow*8-nLength);
                for(int k=nRemainingBits;k>0;k-=8)
                {
                    pcBits[n] = cTmp;
                    cTmp=cTmp2=0;
                    ++n;
                }
                j=0;
                cTmp=0;
            }
        }
        if(j>1)
            pcBits[n] = cTmp;
        BmpMask.SetBitmapBits(nBytesPerRow*nLength,pcBits);
        int nX = UpperLeftCorner.x;
        int nY = UpperLeftCorner.y;
        if(PenColor>=0)
        {
            CPen DCPen, *pOldPen=NULL;    
            DCPen.CreatePen(PS_SOLID,1,PenColor);
            pOldPen = pDC->SelectObject(&DCPen);
            pDC->Ellipse(nX,nY,nX+nLength,nY+nLength);
            pDC->SelectObject(pOldPen);
        }
        else
            pDC->Ellipse(nX,nY,nX+nLength,nY+nLength);
        pDC->MaskBlt(nX,nY,nLength,nLength,&dc,0,0,BmpMask,0,0,0xAACC0020);
        delete[] pcBits;
        delete[] pnBits;
    }
    

    Ist n bissle umfangreich, vielleicht kann mans kürzen ...



  • Ich stimme für eine Verchiebung in die FAQ!!!!



  • Die GDI hat doch auch ein GradientFill.



  • Aloha

    ich schließe mich mit Beifall an.

    Das muß in die FAQ, damit kann man ja wunderbare hintergründe zaubern.

    Fühle Dich virtuell geküßt DEUS.

    Grüße

    BOA



  • .... schrieb:

    Die GDI hat doch auch ein GradientFill.

    Tatsächlich ... Meine ist aber wahrscheinlich einfacher zu handhaben.


Anmelden zum Antworten