Display-GradientFill()

本文尝试从一个简单的例子入手,来讲述GDI API GradientFill()的妙用。

问题:

如何给自绘菜单加上绚丽的背景

 

这个问题如果是在PC上讨论,那么几乎没什么价值。因为PC的内存较大,CPU的速度也较快,所以可以采用任何你想要的方式绘制。比如说下面就是一种很常见的思路:
1.得到菜单矩形区域和上下文设备。
2。根据矩形区域的大小,起始色和最终色计算每一像素的颜色,从而创建响应的画笔在该矩形的顶端和低端画一条线。
下面是源代码:

void CCustomMenu::DrawBk(CDC *pDC, CRect rect, COLORREF cr1,COLORREF cr2)
{
int r1 = GetRValue(cr1);//Red color1
int g1 = GetGValue(cr1);//Green color1
int b1 = GetBValue(cr1);//blue color1
int r2 = GetRValue(cr2);//red color2
int g2 = GetGValue(cr2);//green color2
int b2 = GetBValue(cr2);//blue color2
float dr = ((float)(r2 - r1))/(float)(rect.Width());
float dg = ((float)(g2 - g1))/(float)(rect.Width());
float db = ((float)(b2 - b1))/(float)(rect.Width());
for(int i = rect.left; i < rect.right; i ++)
{
   int r = r1 + (int)(dr*((float)(i - rect.left)));
   int g = g1 + (int)(dg*((float)(i - rect.left)));
   int b = b1 + (int)(db*((float)(i - rect.left)));
   CPen pen(PS_SOLID, 1, RGB(r, g, b));
   CPen *old = pDC->SelectObject(&pen);
   pDC->MoveTo(i, rect.top);
   pDC->LineTo(i, rect.bottom);
   pDC->SelectObject(old);
}
效果很好,的确很绚丽。但是很慢。从代码中可以看到,还是有一定的计算量的。那么我们就应该寻求更好的方法。其实也就是个函数而已。

寻求更优解决方法:

GradientFill


GradientFill(HDC hdc,PTRIVERTEX,ULONG,PVOID,ULONG,ULONG);
参数的意义:
HDC:设备上下文句柄
PTRIVERTEX:TRIVERTEX结构指针.


typedef struct _TRIVERTEX {
  LONG
x;//矩形左坐标
  LONG
y;//上坐标
  COLOR16
Red;//颜色
  COLOR16
Green;
  COLOR16
Blue;
  COLOR16
Alpha;//透明
} TRIVERTEX,*PTRIVERTEX,*LPTRIVERTEX;

第三个参数:TRIVERTEX结构个数.由于我们是从起始颜色慢慢绘制到终止颜色,所以这个结构的个数至少是2,不然就和普通的设置背景色没什么区别了。
第四个参数:GRADIENT_RECT结构
typedef struct _GRADIENT_RECT {
ULONG
UpperLeft;//指定TRIVERTEX结构数组中哪个元素用来作为左上
ULONG
LowerRight;
}GRADIENT_RECT, *PGRADIENT_RECT;
第五个参数
GRADIENT_RECT结构的个数
第六个参数   标志从上往下画 还是从左到右画.

简单的例子:
TRIVERTEX tri[2];

tri[0].Alpha=20;
tri[0].Blue=0xff00;
tri[0].Green=0x0000;
tri[0].Red=0x0000;
tri[0].x=lpStruct->rcItem.left;
tri[0].y=lpStruct->rcItem.top;

tri[1].Alpha=20;
tri[1].Blue=0x0000;
tri[1].Green=0xff00;
tri[1].Red=0x0000;
tri[1].x=lpStruct->rcItem.right;
tri[1].y=lpStruct->rcItem.bottom;


GRADIENT_RECT gRect;
gRect.LowerRight=1;
gRect.UpperLeft=0;


GradientFill(pDC->GetSafeHdc(),tri,2,&gRect,1,GRADIENT_FILL_RECT_H);

你可能感兴趣的:(struct,api,float)