//
{$N+}
Unit ads_Gradient;
{Copyright(c)2016 Advanced Delphi Systems
Richard Maley
Advanced Delphi Systems
12613 Maidens Bower Drive
Potomac, MD 20854 USA
phone 301-840-1554
dickmaley@advdelphisys.com
The code herein can be used or modified by anyone. Please retain references
to Richard Maley at Advanced Delphi Systems. If you make improvements to the
code please send your improvements to dickmaley@advdelphisys.com so that the
entire Delphi community can benefit. All comments are welcome.
}
(*UnitIndex Master Index Implementation Section Download UnitsDescription: ads_Gradient.pas This unit contains the following routines.
Register TGradient.CreateGradient TGradient.Paint TGradient.SetEndingColor TGradient.SetGradientDirection TGradient.SetStartingColor
*)
interface
uses
WinTypes, WinProcs, Messages,
SysUtils, Classes, Controls,
Forms, Menus, Graphics;
type
TGradientDirection =
(gdTopToBottom,gdLeftToRight,gdInsideOut,gdStretchInsideOut);
TGradient = class(TGraphicControl)
protected
FGradBMP : hBitmap;
fStartingColor : TColor;
fEndingColor: TColor;
fGradientDirection: TGradientDirection;
fGradWidth,fGradHeight:integer;
procedure Paint; override;
procedure SetStartingColor(Value:TColor);
procedure SetEndingColor(Value:TColor);
procedure SetGradientDirection(Value:TGradientDirection);
public
procedure CreateGradient;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property GradientDirection:TGradientDirection read fGradientDirection write SetGradientDirection;
property ColorStart: TColor read fStartingColor write SetStartingColor default clBlue;
property ColorEnd: TColor read fEndingColor write SetEndingColor default clBlack;
property Align;
property DragCursor;
property DragMode;
property OnDragDrop;
property OnClick;
property OnDragOver;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
end;
procedure Register;
implementation
Uses ads_Exception;
Var
ProcName : String = 'Unknown';
UnitName : String = 'ads_Gradient';
//Unit Description UnitIndex Master Index
procedure Register;
begin
ProcName := 'Register'; Try
RegisterComponents('ads',[TGradient]);
Except On E : Exception Do RaiseError(UnitName,ProcName,E);End;
end;
constructor TGradient.Create(AOwner: TComponent);
begin
ProcName := 'TGradient.Create'; Try
inherited Create(AOwner);
fEndingColor := clBlack;
fStartingColor := clBlue;
fGradBMP := 0;
Width := 30;
Height := 30;
Except On E : Exception Do RaiseError(UnitName,ProcName,E);End;
end;
destructor TGradient.Destroy;
begin
ProcName := 'TGradient.Destroy'; Try
if fGradBMP <> 0 then DeleteObject(fGradBMP);
inherited Destroy;
Except On E : Exception Do RaiseError(UnitName,ProcName,E);End;
end;
//Unit Description UnitIndex Master Index
procedure TGradient.SetStartingColor(Value:TColor);
begin
ProcName := 'TGradient.SetStartingColor'; Try
if Value<>fStartingColor then
begin
fStartingColor := Value;
CreateGradient;
Invalidate;
end;
Except On E : Exception Do RaiseError(UnitName,ProcName,E);End;
end;
//Unit Description UnitIndex Master Index
procedure TGradient.SetEndingColor(Value:TColor);
begin
ProcName := 'TGradient.SetEndingColor'; Try
if Value<>fEndingColor then
begin
fEndingColor := Value;
CreateGradient;
Invalidate;
end;
Except On E : Exception Do RaiseError(UnitName,ProcName,E);End;
end;
//Unit Description UnitIndex Master Index
procedure TGradient.SetGradientDirection(Value:TGradientDirection);
begin
ProcName := 'TGradient.SetGradientDirection'; Try
if Value<>fGradientDirection then
begin
fGradientDirection := Value;
CreateGradient;
Invalidate;
end;
Except On E : Exception Do RaiseError(UnitName,ProcName,E);End;
end;
//Unit Description UnitIndex Master Index
procedure TGradient.Paint;
var
MemDC,PaintDC : HDC;
OldBMP : hBitmap;
R : TRect;
begin
ProcName := 'TGradient.Paint'; Try
PaintDC := Canvas.Handle;
if (fGradWidth<>Width) or (fGradHeight<>Height) then
CreateGradient;
if (fGradWidth=0) or (fGradHeight=0) then exit;
MemDC := CreateCompatibleDC(PaintDC);
OldBMP := SelectObject(MemDC,fGradBMP);
R := Rect(Left,Top,Width+1,Height+1);
BitBlt(PaintDC,0,0,Width,Height,MemDC,0,0,SRCCOPY);
SelectObject(MemDC,OldBMP);
DeleteDC(MemDC);
Except On E : Exception Do RaiseError(UnitName,ProcName,E);End;
end;
//Unit Description UnitIndex Master Index
procedure TGradient.CreateGradient;
var
DC,MemDC : hDC;
OldBMP : hBitmap;
Brush : THandle;
i,j : integer;
R : TRect;
XInc,YInc : single;
C,C1 : TColorRef;
RStart,GStart,BStart,RDelta,GDelta,BDelta,
XOfs,YOfs : double;
REnd,BEnd,GEnd,R1,G1,B1 : integer;
CX,CY,GradSz,XNew,YNew:integer;
GradSzMinus1: integer;
Temp : string[20];
begin
ProcName := 'TGradient.CreateGradient'; Try
G1 := 0; B1 := 0; GradSz := 0; XInc := 0; YInc := 0; R1 := 0;
if fGradBMP <> 0 then DeleteObject(fGradBMP);
fGradWidth := Width;
fGradHeight := Height;
if (fGradWidth=0) or (fGradHeight=0) then exit;
DC := GetDC(0);
MemDC := CreateCompatibleDC(DC);
fGradBMP := CreateCompatibleBitmap(DC,fGradWidth,fGradHeight);
OldBMP := SelectObject(MemDC,fGradBMP);
case fGradientDirection of
gdTopToBottom:
GradSz := fGradHeight;
gdLeftToRight:
GradSz := fGradWidth;
gdInsideOut,
gdStretchInsideOut:
begin
if fGradWidth > fGradHeight then
begin
GradSz := fGradWidth;
XInc := 1;
if fGradientDirection = gdStretchInsideOut then
YInc := (fGradHeight / fGradWidth)
else
YInc := 1;
end
else
begin
GradSz := fGradHeight;
YInc := 1;
if fGradientDirection = gdStretchInsideOut then
XInc := (fGradWidth / fGradHeight)
else
XInc := 1;
end;
CX := fGradWidth shr 1;
CY := fGradHeight shr 1;
end;
end;
{}
if fGradientDirection in [gdInsideOut,gdStretchInsideOut] then
begin
REnd := GetRValue(fEndingColor);
GEnd := GetGValue(fEndingColor);
BEnd := GetBValue(fEndingColor);
RStart := GetRValue(fStartingColor);
GStart := GetGValue(fStartingColor);
BStart := GetBValue(fStartingColor);
RDelta :=
(REnd-RStart)/((GradSz) div 2);
GDelta :=
(GEnd-GStart)/((GradSz) div 2);
BDelta :=
(BEnd-BStart)/((GradSz) div 2);
C := fStartingColor;
XOfs := 0;
YOfs := 0;
XNew := 0;
YNew := 0;
With R do begin
Left := CX; Top := CY;
Right := CX+1; Bottom := CY+1;
end;
While (R.Left >=0) or (R.Top>=0) do
begin
Brush := CreateSolidBrush(C);
FrameRect(MemDC,R,Brush);
DeleteObject(Brush);
XOfs := XOfs+XInc;
YOfs := YOfs+YInc;
if (XOfs-XNew) >= 1 then
begin
InflateRect(R,1,0);
Inc(XNew);
end;
if (YOfs-YNew) >= 1 then
begin
InflateRect(R,0,1);
Inc(YNew);
end;
if R1<>REnd then RStart := RStart+RDelta;
if G1<>GEnd then GStart := GStart+GDelta;
if B1<>BEnd then BStart := BStart+BDelta;
R1 := Round(RStart);
G1 := Round(GStart);
B1 := Round(BStart);
C := RGB(R1,G1,B1);
end;
end
else
begin
GradSzMinus1 := GradSz-1;
RDelta := (Integer(GetRValue(fEndingColor))-GetRValue(fStartingColor)) / GradSzMinus1;
GDelta := (Integer(GetGValue(fEndingColor))-GetGValue(fStartingColor)) / GradSzMinus1;
BDelta := (Integer(GetBValue(fEndingColor))-GetBValue(fStartingColor)) / GradSzMinus1;
C := fStartingColor;
C1 := C;
i := 0;
While i <= GradSzMinus1 do
begin
Brush := CreateSolidBrush(C);
case fGradientDirection of
gdTopToBottom:
begin
With R do
begin Left := 0; Right := Width; Top := i; Bottom := i+1; end;
end;
gdLeftToRight:
begin
With R do
begin Left := i; Right := i+1; Top := 0; Bottom := Height; end;
end;
end;
FrameRect(MemDC,R,Brush);
DeleteObject(Brush);
Inc(i);
C := RGB(Trunc(GetRValue(C1)+RDelta*(i-1)),Trunc(GetGValue(C1)+GDelta*(i-1)),Trunc(GetBValue(C1)+BDelta*(i-1)));
end;
end;
SelectObject(MemDC,OldBMP);
DeleteDC(MemDC);
ReleaseDC(0,DC);
Except On E : Exception Do RaiseError(UnitName,ProcName,E);End;
end;
end.
//