unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 =
class(TForm)
procedure FormPaint(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var
bf: _BLENDFUNCTION = (
BlendOp: AC_SRC_OVER;
BlendFlags: 0;
SourceConstantAlpha: 255;
AlphaFormat: AC_SRC_ALPHA);
type
TGFillMode = (GRADIENT_FILL_RECT_H, GRADIENT_FILL_RECT_V);
function GradientFill(
DC: HDC; pTriVertex: Pointer; dwNumVertex: DWORD;
pMesh: Pointer; dwNumMesh, dwMode: DWORD): BOOL;
stdcall;
external '
msimg32.dll'
name '
GradientFill';
function GradientFill4c(
DC: HDC; fillRect: TRect; Col:
array of COLORREF; FillMode: TGFillMode): Boolean;
type
_TTRIVERTEX =
packed record
X, Y: DWORD;
Red, Green, Blue, Alpha: Word;
end;
var
tv:
array[0..3]
of _TTRIVERTEX;
gr:
array[0..1]
of GRADIENT_RECT;
i: integer;
begin
if length(col) = 4
then
begin
// fillmode direction
gr[0].UpperLeft := 0;
gr[0].LowerRight := 1;
gr[1].UpperLeft := 2;
gr[1].LowerRight := 3;
ZeroMemory(@tv, sizeof(tv));
// eckpunkte festlegen
if FillMode = GRADIENT_FILL_RECT_V
then
begin
tv[0].x := fillRect.Left;
tv[0].y := fillRect.Top;
tv[1].x := fillRect.Right;
tv[1].y := (fillRect.Top + fillRect.Bottom)
div 2;
tv[2].x := fillRect.Left;
tv[2].y := (fillRect.Top + fillRect.Bottom)
div 2;
tv[3].x := fillRect.Right;
tv[3].y := fillRect.Bottom;
end
else
begin
tv[0].x := fillRect.Left;
tv[0].y := fillRect.Top;
tv[1].x := (fillRect.Left + fillRect.Right)
div 2;
tv[1].y := fillRect.Bottom;
tv[2].x := (fillRect.Left + fillRect.Right)
div 2;
tv[2].y := fillRect.Top;
tv[3].x := fillRect.Right;
tv[3].y := fillRect.Bottom;
end;
for i := 0
to high(Col)
do
begin
tv[i].Red := BYTE(col[i])
shl 8;
// get Color's and Byteswap for Color-Word
tv[i].Green := BYTE(col[i]
shr 8)
shl 8;
tv[i].Blue := BYTE(col[i]
shr 16)
shl 8;
tv[i].Alpha := BYTE(col[i]
shr 24)
shl 8;
end;
Result := GradientFill(
DC, @tv, length(tv), @gr, length(gr), DWORD(FillMode));
end
else
Result := False;
end;
// Note that GradientFill does not use the Alpha member of the TRIVERTEX structure.
// To use GradientFill with transparency, call GradientFill and then call AlphaBlend
// with the desired values for the alpha channel of each vertex.
function GradientFill4cT(
DC: HDC; fillRect: TRect; Col:
array of COLORREF; FillMode: TGFillMode; bf: _BLENDFUNCTION): Boolean;
var
w, h: integer;
hBmpDC: HDC;
hBmp: HBITMAP;
begin
w := fillRect.Right - fillRect.Left;
h := fillRect.Bottom - fillRect.Top;
hBmpDC := CreateCompatibleDC(
DC);
//todo: Achtung: keine Fehlerprüfung !
hBmp := CreateBitmap(w, h, 1, 32,
nil);
SelectObject(hBmpDC, hBmp);
Result := GradientFill4c(hBmpDC, RECT(0, 0, w, h), Col, FillMode);
with fillRect
do
Result := Result
and Windows.AlphaBlend(
DC,
Left, Top, Right - Left, Bottom - Top,
hBmpDC,
0, 0, w, h,
bf);
DeleteObject(hBmp);
DeleteDC(hBmpDC);
end;
procedure TForm1.FormPaint(Sender: TObject);
var
pr: TRect;
begin
pr := RECT(20,20,160,180);
GradientFill4c(Self.Canvas.Handle, pr, [$000000FF, $008080FF, $000000FF, $000000C8], GRADIENT_FILL_RECT_V);
OffSetRect(pr, 50, 50);
GradientFill4c(Self.Canvas.Handle, pr, [$00FFFFFF, $00FFFFFF, $00FFFFFF, $00C00000], GRADIENT_FILL_RECT_H);
// GradientFill with transparency
OffSetRect(pr, 50, 50);
GradientFill4cT(Self.Canvas.Handle, pr,[$FF0000FF, $A08080FF, $B00000FF, $FF0000C8], GRADIENT_FILL_RECT_V, bf);
end;
end.