终极渐变填充解决方案:
由Windows提供的渐变填充方法,属于非公开函数。
定义在MSIMG32.DLL中,Win98以上可采用。
函数定义:
BOOL GradientFill( HDC hdc, // DC句柄
PTRIVERTEX pVertex, // 顶点矩阵
ULONG dwNumVertex, // 顶点个数
PVOID pMesh, // 填充渐变梯度矩阵
ULONG dwNumMesh, // 填充渐变梯度矩阵尺寸
ULONG dwMode // 填充方式
);
其它详细信息可以从MSDN上查找,用GradientFill作关键词搜索即可。
GradientFill不仅速度快,还可以实现无数特技,只要你能想到。
我只是在BCB中用它,没提供它的Delphi描述,好事者不防试试。
在BCB中所有信息定义在WinGdi.h文件内,如果不以调DLL的方式使用,则需要将MsImg32.lib加到工程内,应该在BCB安装目录的LIB/PSDK下。
下面是用BCB写的两个示例:
//---------------------------------------------------------------------------
// 矩形填充
void __fastcall GradientFillRect( HDC dc, TRect& rect, TColor beg,
TColor end, TOGGradientRectMode mode )
{
if( mode == ogrmVert || mode == ogrmHori )
{
TRIVERTEX vert[2] ;
GRADIENT_RECT gRect;
vert [0] .x = rect.Left;
vert [0] .y = rect.Top;
vert [0] .Red = GetRValue( beg ) * 0x100;
vert [0] .Green = GetGValue( beg ) * 0x100;
vert [0] .Blue = GetBValue( beg ) * 0x100;
vert [0] .Alpha = 0x0000;
vert [1] .x = rect.Right;
vert [1] .y = rect.Bottom;
vert [1] .Red = GetRValue( end ) * 0x100;
vert [1] .Green = GetGValue( end ) * 0x100;
vert [1] .Blue = GetBValue( end ) * 0x100;
vert [1] .Alpha = 0x0000;
gRect.UpperLeft = 0;
gRect.LowerRight = 1;
ULONG dwMode = (mode == ogrmVert)? GRADIENT_FILL_RECT_V : GRADIENT_FILL_RECT_H;
#ifdef SEM_USE_MSIMG32DIRECT
GradientFill( dc, vert, 2, &gRect, 1, dwMode );
#else
HINSTANCE DLLHandle = LoadLibrary("MSIMG32.DLL");
if( DLLHandle != NULL )
{
FGradientFill proc = (FGradientFill)GetProcAddress(DLLHandle,"GradientFill");
if( proc )
proc(dc, vert, 2, &gRect, 1, dwMode);
FreeLibrary( DLLHandle );
}
#endif
}
else if( mode == ogrmCenter )
{
TPoint p[9];
TColor c[9];
p[0].x = (rect.Left + rect.Right) / 2;
p[0].y = (rect.Top + rect.Bottom) / 2;
p[1].x = rect.Left;
p[1].y = rect.Top;
p[2].x = rect.Right;
p[2].y = rect.Top;
p[3].x = rect.Right;
p[3].y = rect.Top;
p[4].x = rect.Right;
p[4].y = rect.Bottom;
p[5].x = rect.Right;
p[5].y = rect.Bottom;
p[6].x = rect.Left;
p[6].y = rect.Bottom;
p[7].x = rect.Left;
p[7].y = rect.Bottom;
p[8].x = rect.Left;
p[8].y = rect.Top;
c[0] = beg;
for( int i = 1; i < 9; i++ )
c = end;
GradientFillTriangle( dc, p, c, 9 );
}
}
//---------------------------------------------------------------------------
// 三角形填充,可用于渲染任何形状图形或进行三维渲染。
void __fastcall GradientFillTriangle( HDC dc, Windows::TPoint *points,
Graphics::TColor *colors,
int num )
{
if( num < 3 )
return;
TRIVERTEX *vert = new TRIVERTEX[num] ;
int nTri = (num - 1) / 2;
GRADIENT_TRIANGLE *gTri = new GRADIENT_TRIANGLE[nTri];
try
{
TColor color;
for( int i = 0; i < num; i++ )
{
color = colors;
vert .x = points.x;
vert .y = points.y;
vert .Red = GetRValue( color ) * 0x100;
vert .Green = GetGValue( color ) * 0x100;
vert .Blue = GetBValue( color ) * 0x100;
vert .Alpha = 0x0000;
}
for( int i = 0; i < nTri; i++ )
{
gTri.Vertex1 = 0;
gTri.Vertex2 = i * 2 + 1;
gTri.Vertex3 = i * 2 + 2;
}
#ifdef SEM_USE_MSIMG32DIRECT
GradientFill( dc, vert, num, gTri, nTri, GRADIENT_FILL_TRIANGLE );
#else
HINSTANCE DLLHandle = LoadLibrary("MSIMG32.DLL");
if( DLLHandle != NULL )
{
FGradientFill proc = (FGradientFill)GetProcAddress(DLLHandle,"GradientFill");
if( proc )
proc(dc, vert, num, gTri, nTri, GRADIENT_FILL_TRIANGLE);
FreeLibrary( DLLHandle );
}
#endif
}
__finally
{
delete[] vert;
delete[] gTri;
}
}