3,881
社区成员
发帖
与我相关
我的任务
分享
public sealed class 渐变颜色填充
{
public enum FillDirection
{
//
// The fill goes horizontally
//
LeftToRight = GRADIENT_FILL_RECT_H,
//
// The fill goes vertically
//
TopToBottom = GRADIENT_FILL_RECT_V
}
public static bool Fill(
Graphics gr, Rectangle rc, Color[] ColorArray, FillDirection fillDir,
float[] PositionArray)
{
int nSize = PositionArray.Length;
int i;
if (nSize <= 0)
return false;
Rectangle[] rects = new Rectangle[nSize];
for (i = 0; i < nSize - 1; i++)
{
rects[i] = rc;
if (fillDir == FillDirection.LeftToRight)
{
rects[i].X = (int)(PositionArray[i] * rc.Width);
rects[i].Width = (int)((PositionArray[i + 1] - PositionArray[i]) * rc.Width) + 1;
}
else //if (fillDir == FillDirection.TopToBottom)
{
rects[i].Y = (int)(PositionArray[i] * rc.Height);
rects[i].Height = (int)((PositionArray[i + 1] - PositionArray[i]) * rc.Height) + 1;
}
Fill(gr, rects[i], ColorArray[i], ColorArray[i + 1], fillDir);
}
return true;
}
// This method wraps the PInvoke to GradientFill.
// Parmeters:
// gr - The Graphics object we are filling
// rc - The rectangle to fill
// startColor - The starting color for the fill
// endColor - The ending color for the fill
// fillDir - The direction to fill
//
// Returns true if the call to GradientFill succeeded; false
// otherwise.
public static bool Fill(
Graphics gr,
Rectangle rc,
Color startColor, Color endColor,
FillDirection fillDir)
{
// Initialize the data to be used in the call to GradientFill.
渐变颜色填充.TRIVERTEX[] tva = new 渐变颜色填充.TRIVERTEX[2];
tva[0] = new 渐变颜色填充.TRIVERTEX(rc.X, rc.Y, startColor);
tva[1] = new 渐变颜色填充.TRIVERTEX(rc.Right, rc.Bottom, endColor);
渐变颜色填充.GRADIENT_RECT[] gra = new 渐变颜色填充.GRADIENT_RECT[] {
new 渐变颜色填充.GRADIENT_RECT(0, 1)};
// Get the hDC from the Graphics object.
IntPtr hdc = gr.GetHdc();
// PInvoke to GradientFill.
bool b;
b = GradientFill(
hdc,
tva,
(uint)tva.Length,
gra,
(uint)gra.Length,
(uint)fillDir);
//System.Diagnostics.Debug.Assert(b, string.Format(
// "GradientFill failed: {0}",
// System.Runtime.InteropServices.Marshal.GetLastWin32Error()));
// Release the hDC from the Graphics object.
gr.ReleaseHdc(hdc);
return b;
}
public struct TRIVERTEX
{
public int x;
public int y;
public ushort Red;
public ushort Green;
public ushort Blue;
public ushort Alpha;
public TRIVERTEX(int x, int y, Color color)
: this(x, y, color.R, color.G, color.B, color.A)
{
}
public TRIVERTEX(
int x, int y,
ushort red, ushort green, ushort blue,
ushort alpha)
{
this.x = x;
this.y = y;
this.Red = (ushort)(red << 8);
this.Green = (ushort)(green << 8);
this.Blue = (ushort)(blue << 8);
this.Alpha = (ushort)(alpha << 8);
}
}
public struct GRADIENT_RECT
{
public uint UpperLeft;
public uint LowerRight;
public GRADIENT_RECT(uint ul, uint lr)
{
this.UpperLeft = ul;
this.LowerRight = lr;
}
}
[DllImport("coredll.dll", SetLastError = true, EntryPoint = "GradientFill")]
public extern static bool GradientFill(
IntPtr hdc,
TRIVERTEX[] pVertex,
uint dwNumVertex,
GRADIENT_RECT[] pMesh,
uint dwNumMesh,
uint dwMode);
public const int GRADIENT_FILL_RECT_H = 0x00000000;
public const int GRADIENT_FILL_RECT_V = 0x00000001;
}
void DrawGradientRect(CDC* pDC, CRect rectGradient, COLORREF clrBegin, COLORREF clrEnd)
{
int nRBegin = GetRValue(clrBegin);
int nGBegin = GetGValue(clrBegin);
int nBBegin = GetBValue(clrBegin);
int nREnd = GetRValue(clrEnd);
int nGEnd = GetGValue(clrEnd);
int nBEnd = GetBValue(clrEnd);
int nWidth = rectGradient.Width();
int nHeight = rectGradient.Height();
CRect rectSingle;
for(int i=0 ; i<=nHeight-1; i++)
{
COLORREF clrFillColor;
clrFillColor = RGB(nRBegin+(nREnd-nRBegin)*i/nHeight, nGBegin+(nGEnd-nGBegin)*i/nHeight, nBBegin+(nBEnd-nBBegin)*i/nHeight);
rectSingle.SetRect(rectGradient.left, rectGradient.top+i, rectGradient.right, rectGradient.top+i+1);
pDC->FillSolidRect(&rectSingle, clrFillColor);
}
}