//
{$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 Units
Description: 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. //