用RGB颜色逐点画,RGB(0,0,0)--RGB(255,255,255)为从黑到白,依此类推,RGB(255,0,0)为纯红,RGB(255,255,0)为黄色,逐渐变化就行了。

解决方案 »

  1.   

    /*********************感谢观注***********************/
    /////////////////////Creamdog////////////////////////用算法控制吧,自创源码如下。鄙人水平实在有限,加之时间紧,错误之处在所难免,还望各路英雄豪杰予以指正,在下感激不尽!typedef struct COLOR24{
    unsigned char blue;
    unsigned char green;
    unsigned char red;
    }C24,*PC24;HBITMAP Shade( HDC hdc, C24 c1, C24 c2, RECT rect, LPBITMAPINFO lpbmi )
    {
    //变量定义
    int i,j,k;
    int width = rect.right - rect.left;
    int height = rect.bottom - rect.top; //测量四字节边界对齐的值
    int AlignByte = 4-(width*3)%4;
    if(AlignByte==4)
    AlignByte = 0; //计算需要的字节数并分配内存
    long imagesize = (width*3+AlignByte)*height;
    char* outdata = new char[imagesize];
    char* buffer = new char[width*3]; //初始化位图信息BITMAPINFO
    lpbmi->bmiHeader.biSize = sizeof(BITMAPINFO);
    lpbmi->bmiHeader.biWidth = width;
    lpbmi->bmiHeader.biHeight = height;
    lpbmi->bmiHeader.biPlanes = 1;
    lpbmi->bmiHeader.biBitCount = 24;
    lpbmi->bmiHeader.biCompression = BI_RGB;
    lpbmi->bmiHeader.biSizeImage = imagesize;
    lpbmi->bmiHeader.biXPelsPerMeter = 0;
    lpbmi->bmiHeader.biYPelsPerMeter = 0;
    lpbmi->bmiHeader.biClrUsed = 0;
    lpbmi->bmiHeader.biClrImportant = 0; //初始化输出内存堆
    for(i = 0; i<imagesize; i++)
    {
    *(outdata+i) = 0;
    }
    //计算渐变步长
    float stepred = (float(c2.red - c1.red))/width/3;
    float stepgreen = (float(c2.green - c1.green))/width/3;
    float stepblue = (float(c2.blue - c1.blue))/width/3; //为提高较率,只生成第一行象素的缓冲堆其它行按此进行复制
    for(i = 0; i<width*3; i+=3)
    {
    *(buffer + i + 0) = c1.blue + (char)(stepblue*i);
    *(buffer + i + 1) = c1.green + (char)(stepgreen*i);
    *(buffer + i + 2) = c1.red + (char)(stepred*i);
    } //拷贝缓冲行到输出内存堆,并为输出变量数据添加对齐字节
    for(i = 0, k = 0; i<height; i++)
    {
    for(j = 0; j<width*3; j++, k++)
    {
    if(j%(width*3)==0 && k!=0)
    k+=AlignByte;
    *(outdata+k) = *(buffer+j);
    }
    } //创建位图并返回位图句柄
    return CreateDIBitmap(hdc,
    &(lpbmi->bmiHeader),
    CBM_INIT,
    LPVOID(outdata),
    lpbmi,
    DIB_RGB_COLORS
    );
    }
      

  2.   

    void CGradientProgressCtrl::DrawGradient(CPaintDC *pDC, const RECT &rectClient, const int &nMaxWidth)
    {
    RECT rectFill;    // Rectangle for filling band
    double fStep;              // How wide is each band?
    CBrush brush; // Brush to fill in the bar
    CMmDC memDC(pDC); // First find out the largest color distance between the start and end colors.  This distance
    // will determine how many steps we use to carve up the client region and the size of each
    // gradient rect.
    int r, g, b; // First distance, then starting value
    double rStep, gStep, bStep; // Step size for each color // Get the color differences
    r = (GetRValue(m_clrEnd) - GetRValue(m_clrStart));
    g = (GetGValue(m_clrEnd) - GetGValue(m_clrStart));
    b =  (GetBValue(m_clrEnd) - GetBValue(m_clrStart));
    // Make the number of steps equal to the greatest distance
    int nSteps = max(abs(r), max(abs(g), abs(b))); // Determine how large each band should be in order to cover the
    // client with nSteps bands (one for every color intensity level)
    fStep = (double)rectClient.right / (double)nSteps; // Calculate the step size for each color
    rStep = r/(double)nSteps;
    gStep = g/(double)nSteps;
    bStep = b/(double)nSteps; // Reset the colors to the starting position
    r = GetRValue(m_clrStart);
    g = GetGValue(m_clrStart);
    b = GetBValue(m_clrStart);    if(m_clrStart==m_clrEnd)
    {
       memDC.FillSolidRect(0,0,nMaxWidth,rectClient.bottom,m_clrStart);
       memDC.FillSolidRect(nMaxWidth,0,rectClient.right,rectClient.bottom,m_clrBkGround);
       return;
    }
    // Start filling bands
    for (int iOnBand = 0; iOnBand < nSteps; iOnBand++) 
    {

    ::SetRect(&rectFill,
    (int)(iOnBand * fStep),       // Upper left X
     0,  // Upper left Y
    (int)((iOnBand+1) * fStep),          // Lower right X
    rectClient.bottom); // Lower right Y

    // CDC::FillSolidRect is faster, but it does not handle 8-bit color depth
    VERIFY(brush.CreateSolidBrush(RGB(r+rStep*iOnBand, g + gStep*iOnBand, b + bStep *iOnBand)));
    memDC.FillRect(&rectFill,&brush);
    VERIFY(brush.DeleteObject());
    // If we are past the maximum for the current position we need to get out of the loop.
    // Before we leave, we repaint the remainder of the client area with the background color.
    if (rectFill.right > nMaxWidth)
    {
    ::SetRect(&rectFill, nMaxWidth, 0, rectClient.right, rectClient.bottom);
    VERIFY(brush.CreateSolidBrush(m_clrBkGround));
    memDC.FillRect(&rectFill, &brush);
    VERIFY(brush.DeleteObject());
    return;
    }
    }
    }