VC++颜色渐变实现的3种方法

要实现窗口(如菜单、按钮、主背景等)背景颜色的多样化,有很多种实现方法,其中颜色渐变就是一种比较常见的方法。它简单实用,即改变了窗口背景颜色的单调,又实现简单。主要方法有很多种,各有各的算法和特点。我在此给大家介绍3种比较简单的方法,且是2种颜色之间的渐变。
1.自绘法:首先获取两种颜色的R、G、B分量的差值,然后获取显示区域的距离,用R、G、B值除以区域的距离获得每一个像素点R、G、B的变化值(即步长),将起始值颜色的R、G、B值+每个像素点的变化值就得到了当前位置的颜色值。程序如下:
void CDrawColorDlg::DrawGradientColor(COLORREF StartColor,COLORREF EndColor)
{
 CRect rect;
 GetClientRect(rect);//获取窗口的大小
//得到开始颜色值得R、G、B分量
 BYTE r1 = GetRValue(StartColor);
 BYTE g1 = GetGValue(StartColor);
 BYTE b1 = GetBValue(StartColor);
//得到结束颜色值得R、G、B分量
 BYTE r2 = GetRValue(EndColor);
 BYTE g2 = GetGValue(EndColor);
 BYTE b2 = GetBValue(EndColor);
计算两个颜色各个分量的差值
 double r,g,b;
 r = (double)(r2-r1)/rect.Width();
 g = (double)(g2-g1)/rect.Width();
 b = (double)(b2-b1)/rect.Width();
 BYTE r3;
 BYTE g3 ;
 BYTE b3;
 CDC* pDC = GetDC();//得到DC
//画背景
 for (int i = 0 ; i<rect.Width();i++)
 {
//计算当前位置的R、G、B分量
  r3 = r1+ i*r;
  g3 = g1+i*g;
  b3 = b1+i*b;
  CPen pen(PS_SOLID,1,RGB(r3,g3,b3));
  pDC->SelectObject(&pen);
  pDC->MoveTo(i,0);
  pDC->LineTo(i,rect.Height());
 }
 pDC->DeleteDC();
}
该方法的优点就是比较灵活。缺点就是当区域比较大时,绘制比较慢。
2.使用windows的提供的一个API函数GradientFill(): 可以绘制三角形或矩形区域。具体使用可以参考MSDN。具体代码为:
void CDrawColorDlg::DrawGradientColor(COLORREF StartColor,COLORREF EndColor)
{
 CRect rect;
 GetClientRect(rect);//获取窗口的大小
 CDC* pDC = GetDC();//得到DC
//画背景
 GradientFillRect(pDC->m_hDC,rect, GRADIENT_FILL_RECT_H, StartColor, EndColor);
 pDC->DeleteDC();
}
该方法的优点是最简单有效,缺点是不灵活且该API函数已经快过时了。
3.直接加载外部图片:用第三方工具(特别多且非常强大)将背景做成一张BMP背景图,然后在程序中通过API函数加载显示到背景上。
 
void CDrawColorDlg::DrawGradientColor()
{
 CRect rect;
 GetClientRect(rect);//获取窗口的大小
 CDC* pDC = GetDC();//得到DC
 CDC memDC;
 memDC.CreateCompatibleDC(pDC);
 BITMAP bm;
 HBITMAP hBitmap = (HBITMAP)::LoadImage(NULL, m_strBitmap, IMAGE_BITMAP, 0, 0,    LR_DEFAULTSIZE|LR_LOADFROMFILE);
 ASSERT(hBitmap);
 if (bitmap.m_hObject)
      bitmap.Detach();
 bitmap.Attach(hBitmap);
 bitmap.GetBitmap(&bm);
 CBitmap *pOldBitmap = (CBitmap*)memDC.SelectObject(&bitmap);
//pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0, SRCCOPY);
 pDC->StretchBlt(0, 0, rect.Height(), rect.Width(),&memDC, 0, 0,bm.bmWidth,bm.bmHeight, SRCCOPY);  
 pDC->SelectObject(pOldBitmap);
 memDC.DeleteDC();
  pDC->DeleteDC();
}
该方法的优点是背景可以借助第三方工具做的非常漂亮,并可以动态改变,缺点是要出硬盘加载图片到内存,相对比较慢(也可以直接放在资源中加载)。
4.GDI+ 函数LinearGradientBrush:不但可以实现两种颜色的渐变,还可以实现3种颜色的渐变。该方法就不具体介绍了。具体可以参看GDI+的介绍。
本文提供了以上3种渐变方法的测试工程,检验证均能满足要求。
工程源码下载地址:http://download.csdn.net/source/2836144
转载请说明出处:http://blog.csdn.net/mycaibo

你可能感兴趣的:(windows,api,vc++,工具,byte,GDI+)