怎样设置颜色渐变效果?
最好写详细些!

解决方案 »

  1.   

    你可以在对话框的EraseBkgnd消息处理中用如下函数来绘制渐变效果
    DrawGradient(HDC pDC,const RECT& rectClient,const int & nMaxWidth) 
    {
    RECT rectFill; //显示区域
    float fStep; //每一步的幅宽
    HBRUSH hBrush; //显示的颜色画刷 int nRed = 0, nGreen=0, nBlue = 0;
    float fRefStep = 0.0, fGreenStep=0.0, fBlueStep=0.0; //得到不同颜色并相减,返回颜色之间的最大差值
    nRed = (GetRValue(m_nShadowEndColor)-GetRValue(m_nShadowBeginColor));
    nGreen = (GetGValue(m_nShadowEndColor)-GetGValue(m_nShadowBeginColor));
    nBlue = (GetBValue(m_nShadowEndColor)-GetBValue(m_nShadowBeginColor));

    //使进程条显示的总数 等于最大的颜色差值
    int nSteps=max(abs(nRed),max(abs(nGreen),abs(nBlue)));

    //确定每一颜色填充多大的矩形区域
    //以下两种计算步长方式均成立,视个人喜好而定
    //fStep = (float)rectClient.right / (float)nSteps;
    fStep = (float)nMaxWidth / (float)nSteps;
    //设置每一颜色填充的步数
    fRefStep = nRed / (float)nSteps;
    fGreenStep = nGreen / (float)nSteps;
    fBlueStep = nBlue / (float)nSteps; nRed = GetRValue(m_nShadowBeginColor);
    nGreen = GetGValue(m_nShadowBeginColor);
    nBlue = GetBValue(m_nShadowBeginColor);
    //绘制颜色渐变的进程条
    for(int nOnBand=0 ; nOnBand < nSteps ; nOnBand++)
    {
    //本质为使用一个一个的小RECT填充客户区,而每次填充使用不同的颜色(BRUSH),从而达到渐变的效果
    ::SetRect(&rectFill,
    //填充矩形区域的左上角x,y和右下角x,y
    (int)(nOnBand*fStep),
    0,
    (int)((nOnBand+1)*fStep),
    rectClient.bottom+1);

    hBrush = CreateSolidBrush(RGB(nRed + fRefStep*nOnBand,
        nGreen + fGreenStep*nOnBand,
      nBlue + fBlueStep*nOnBand));
    HBRUSH oldBrush = (HBRUSH)::SelectObject(pDC, hBrush);
    FillRect(pDC , &rectFill, hBrush);
    ::SelectObject(pDC, oldBrush);
    DeleteObject(hBrush);
    }
    }
      

  2.   

    你可以在对话框的EraseBkgnd消息处理中用如下函数来绘制渐变效果
    DrawGradient(HDC pDC,const RECT& rectClient,const int & nMaxWidth) 
    {
    RECT rectFill; //显示区域
    float fStep; //每一步的幅宽
    HBRUSH hBrush; //显示的颜色画刷 int nRed = 0, nGreen=0, nBlue = 0;
    float fRefStep = 0.0, fGreenStep=0.0, fBlueStep=0.0; //得到不同颜色并相减,返回颜色之间的最大差值
    nRed = (GetRValue(m_nShadowEndColor)-GetRValue(m_nShadowBeginColor));
    nGreen = (GetGValue(m_nShadowEndColor)-GetGValue(m_nShadowBeginColor));
    nBlue = (GetBValue(m_nShadowEndColor)-GetBValue(m_nShadowBeginColor));

    //使进程条显示的总数 等于最大的颜色差值
    int nSteps=max(abs(nRed),max(abs(nGreen),abs(nBlue)));

    //确定每一颜色填充多大的矩形区域
    //以下两种计算步长方式均成立,视个人喜好而定
    //fStep = (float)rectClient.right / (float)nSteps;
    fStep = (float)nMaxWidth / (float)nSteps;
    //设置每一颜色填充的步数
    fRefStep = nRed / (float)nSteps;
    fGreenStep = nGreen / (float)nSteps;
    fBlueStep = nBlue / (float)nSteps; nRed = GetRValue(m_nShadowBeginColor);
    nGreen = GetGValue(m_nShadowBeginColor);
    nBlue = GetBValue(m_nShadowBeginColor);
    //绘制颜色渐变的进程条
    for(int nOnBand=0 ; nOnBand < nSteps ; nOnBand++)
    {
    //本质为使用一个一个的小RECT填充客户区,而每次填充使用不同的颜色(BRUSH),从而达到渐变的效果
    ::SetRect(&rectFill,
    //填充矩形区域的左上角x,y和右下角x,y
    (int)(nOnBand*fStep),
    0,
    (int)((nOnBand+1)*fStep),
    rectClient.bottom+1);

    hBrush = CreateSolidBrush(RGB(nRed + fRefStep*nOnBand,
        nGreen + fGreenStep*nOnBand,
      nBlue + fBlueStep*nOnBand));
    HBRUSH oldBrush = (HBRUSH)::SelectObject(pDC, hBrush);
    FillRect(pDC , &rectFill, hBrush);
    ::SelectObject(pDC, oldBrush);
    DeleteObject(hBrush);
    }
    }
      

  3.   

    请问SoLike(是我) 
    你所说的EraseBkgnd函数我怎么找不到,在那里?
    还有DrawGradient(HDC pDC,const RECT& rectClient,const int & nMaxWidth) 函数是自己定义的吗?
      

  4.   

    参考:
    用渐变色填充背景 
      Windows的图形界面为我们提供了无穷的方便和视觉上的快感,由浅及深的颜色给我们无尽的遐想。渐变色的实现有多种方法,好多资料上介绍了利用调色板的方法实现,其过程及其的复杂,需要我们具有一定的图形编程的基础,下面我将向大家介绍一种比较简单的方法,即使你一点都不了解图形编程和调色板的概念。  第一步:新建单文档工程,一切参数都取默认值。  第二步:在shadowview.h中定义变量如下:private:
    int ColorR;
    int ColorG;   第三步:在shadowview.cpp的构造函数中初始化变量如下:CShadowView::CShadowView()
    {
     // TODO: add construction code here
     ColorR = 255;
     ColorG = 255;
    }
       第四步:在Ondraw()中添加如下的实现代码:void CShadowView::OnDraw(CDC* pDC)
    {
     CShadowDoc* pDoc = GetDocument();
     ASSERT_VALID(pDoc);
     // TODO: add draw code for native data here
     CRect m_rcClient;
     file://得到客户区域的填充矩形
     GetClientRect(&m_rcClient);
     int nWidth = m_rcClient.Width();
     int nHeight = m_rcClient.Height();
     CRect rectangle;
     file://分割客户区域成小矩形,逐个填充 
     for(int i = 0;i < nWidth;i++ )
     {
      rectangle.SetRect(i, 0, i+1, nHeight);
      pDC->FillSolidRect(&rectangle, RGB(ColorR, ColorG, 255-MulDiv(i, 255, nWidth)));
      }
    }  
      现在编译、运行程序,我们可以发现单文档界面的背景已经被黄渐变色填充。接下来,我们实现在界面上点击鼠标左键,实现背景颜色的改变。  第五步:在ClassWizard中添加鼠标左键的消息处理映射函数,并添加如下代码:void CShadowView::OnLButtonDown(UINT nFlags, CPoint point)
    {
     file://生成小于255的随机数,给ColorR和ColorG赋值
     int nRand = rand();
     float fMap = (float)255/RAND_MAX;
     ColorR = (UINT)(float)nRand*fMap + 0.5f;
     nRand = rand();
     fMap = (float)255/RAND_MAX;
     ColorG = (UINT)(float)nRand*fMap + 0.5f;
     file://更新界面
     Invalidate();
     CView::OnLButtonDown(nFlags, point);
    }
       好了,所有的功能都实现了,在界面上点击鼠标左键,我们可以发现,背景以不同的渐变色填充。 
      

  5.   

    pDC->FillSolidRect(&rectangle, RGB(ColorR, ColorG, 255-MulDiv(i, 255, nWidth)));中的255-MulDiv(i, 255, nWidth))什么意思?
      

  6.   

    SoLike(是我) :升猩了,不散分?不够意思吧~~~
      

  7.   

    To feiniaoliang(飞鸟良)
    散了、散了,这事我那敢忘呢 ^&^。
    不过和你比起来就差远了。
    谢谢哥们还记得我呀!!!!
      

  8.   

    OnEraseBkgnd函数可以通过向导,或手工添加。
    手工:
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);ON_WM_ERASEBKGND()BOOL CMyDialog::OnEraseBkgnd(CDC* pDC) 
    {
       CRect rc;
       pDC->GetClipBox(&rc);   DrawGradient(pDC->GetSafeHdc(), rc, RGB(0,0,0), RGB(0,0,255), 30, FALSE);
       return TRUE;
    }
      

  9.   

    OnEraseBkgnd函数可以通过向导或手工添加。
    手工:
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);ON_WM_ERASEBKGND()BOOL CMyDialog::OnEraseBkgnd(CDC* pDC) 
    {
      CRect rc;
      pDC->GetClipBox(&rc);  DrawGradient(pDC->GetSafeHdc(), rc, RGB(0,0,0), RGB(0,0,255), 1, FALSE);
      return TRUE;
    }把上面的粘到声明,映射表,和定义中
      

  10.   

    SoLike(是我) :
    能说明白些吗?你所说的OnEraseBkgnd是自定义吗?
    还有DrawGradient函数也是自定义的
      

  11.   

    OnEraseBkgnd是背景重绘消息WM_ERASEBKGND的响应函数,手工添加和向导一样。
    DrawGradient是一个自定函数
      

  12.   

    void DrawGradient(HDC pDC,const RECT& rectFill,COLORREF clrBegin, COLORREF clrEnd, const int & nMaxWidth, BOOL bHor)
    {
    RECT rectStep; //显示区域
    HBRUSH hBrush;

    int nFillB, nFillE;
    float fSteps = 0;
    int nRed = 0, nGreen=0, nBlue = 0;
    float fRefStep = 0.0, fGreenStep=0.0, fBlueStep=0.0; //得到不同颜色并相减,返回颜色之间的最大差值
    nRed = (GetRValue(clrEnd)-GetRValue(clrBegin));
    nGreen = (GetGValue(clrEnd)-GetGValue(clrBegin));
    nBlue = (GetBValue(clrEnd)-GetBValue(clrBegin));

    //计算分多少步填充
    if(bHor) fSteps = (float)abs(rectFill.right-rectFill.left) / (float)nMaxWidth;
    else fSteps = (float)abs(rectFill.top-rectFill.bottom) / (float)nMaxWidth;

    //设置每一颜色填充的步数
    fRefStep = nRed / (float)fSteps;
    fGreenStep = nGreen / (float)fSteps;
    fBlueStep = nBlue / (float)fSteps; nRed = GetRValue(clrBegin);
    nGreen = GetGValue(clrBegin);
    nBlue = GetBValue(clrBegin); //绘制颜色渐变的进程条
    for(int nOnBand=0 ; nOnBand <= fSteps ; nOnBand++)
    {
    //本质为使用一个一个的小RECT填充客户区,而每次填充使用不同的颜色(BRUSH),从而达到渐变的效果
    if(bHor)
    {
    nFillB = min((int)(rectFill.left+nOnBand*nMaxWidth), rectFill.right);
    nFillE = min((int)(rectFill.left+(nOnBand+1)*nMaxWidth), rectFill.right);
    ::SetRect(&rectStep, nFillB, rectFill.top,nFillE,rectFill.bottom+1);
    }
    else
    {
    nFillB = min((int)(rectFill.top+nOnBand*nMaxWidth), rectFill.bottom);
    nFillE = min((int)(rectFill.top+(nOnBand+1)*nMaxWidth), rectFill.bottom);
    ::SetRect(&rectStep,rectFill.left,nFillB,rectFill.right+1,nFillE);
    }

    hBrush = CreateSolidBrush(RGB(nRed + fRefStep*nOnBand,
        nGreen + fGreenStep*nOnBand,
      nBlue + fBlueStep*nOnBand));
    HBRUSH oldBrush = (HBRUSH)::SelectObject(pDC, hBrush);
    FillRect(pDC , &rectStep, hBrush);
    ::SelectObject(pDC, oldBrush);
    DeleteObject(hBrush);
    }
    }