4 uses Windows
, Classes
, Graphics
, Controls
, Messages
, Dialogs
,
7 const WM_GETIMAGE
= WM_USER
+ $0429;
9 function BitmapToRegion(Bitmap
: TBitmap
): HRGN
;
10 function CopyToBitmap(Control
: TControl
; Bitmap
: TBitmap
; Anyway
: boolean): boolean;
11 procedure CopyParentImage(Control
: TControl
; Dest
: TCanvas
);
12 procedure RestoreImage(DestDC
: HDC
; SrcBitmap
: TBitmap
; r
: TRect
;
13 dwROP
: dword
); overload
;
14 procedure RestoreImage(DestDC
: HDC
; SrcBitmap
: TBitmap
; l
, t
, w
, h
: integer;
15 dwROP
: dword
); overload
;
16 procedure AjustBitmap(const M
: TBitmap
; S
, C
: TColor
);
17 procedure FadeBitmap(const M
: TBitmap
; C
: TColor
; D
: byte);
18 function IncColor(C
: TColor
; D
: integer): TColor
;
22 function BitmapToRegion(Bitmap
: TBitmap
): HRGN
;
31 TransC
:= Canvas
.Pixels
[0, 0];
32 for Y
:= 0 to Height
- 1 do begin
34 while X
< Width
do begin
35 while (X
< Width
) and (Canvas
.Pixels
[X
, Y
] = TransC
) do Inc(X
);
36 if X
>= Width
then Break
;
38 while (X
< Width
) and (Canvas
.Pixels
[X
, Y
] <> TransC
) do Inc(X
);
39 R
:= CreateRectRgn(XStart
, Y
, X
, Y
+ 1);
40 if Result
= 0 then Result
:= R
42 CombineRgn(Result
, Result
, R
, RGN_OR
);
50 function CopyToBitmap
;
54 if Control
= nil then exit
;
55 x
:= BitMap
.Width
- 2;
56 y
:= BitMap
.Height
- 2;
58 (x
+ 2 <> Control
.Width
) or
59 (y
+ 2 <> Control
.Height
) or
60 (BitMap
.Canvas
.Pixels
[x
, y
] = $FFFFFF) or
61 (BitMap
.Canvas
.Pixels
[x
, y
] = $000000) then begin
62 BitMap
.Width
:= Control
.Width
;
63 BitMap
.Height
:= Control
.Height
;
64 CopyParentImage(Control
, BitMap
.Canvas
);
70 TParentControl
= class(TWinControl
);
72 procedure CopyParentImage(Control
: TControl
; Dest
: TCanvas
);
74 I
, Count
, X
, Y
, SaveIndex
: Integer;
76 R
, SelfR
, CtlR
: TRect
;
78 if (Control
= nil) or (Control
.Parent
= nil) then Exit
;
79 Count
:= Control
.Parent
.ControlCount
;
81 with Control
.Parent
do ControlState
:= ControlState
+ [csPaintCopy
];
84 SelfR
:= Bounds(Left
, Top
, Width
, Height
);
85 X
:= -Left
; Y
:= -Top
;
87 { Copy parent control image }
88 SaveIndex
:= SaveDC(DC
);
90 if TParentControl(Control
.Parent
).Perform(
91 WM_GETIMAGE
, DC
, integer(@SelfR
)) <> $29041961 then begin
92 SetViewportOrgEx(DC
, X
, Y
, nil);
93 IntersectClipRect(DC
, 0, 0, Control
.Parent
.ClientWidth
,
94 Control
.Parent
.ClientHeight
);
95 with TParentControl(Control
.Parent
) do begin
96 Perform(WM_ERASEBKGND
, DC
, 0);
101 RestoreDC(DC
, SaveIndex
);
103 { Copy images of graphic controls }
104 for I
:= 0 to Count
- 1 do begin
105 if Control
.Parent
.Controls
[I
] = Control
then continue
106 else if (Control
.Parent
.Controls
[I
] <> nil) and
107 (Control
.Parent
.Controls
[I
] is TGraphicControl
) then
109 with TGraphicControl(Control
.Parent
.Controls
[I
]) do begin
110 CtlR
:= Bounds(Left
, Top
, Width
, Height
);
111 if Bool(IntersectRect(R
, SelfR
, CtlR
)) and Visible
then begin
112 ControlState
:= ControlState
+ [csPaintCopy
];
113 SaveIndex
:= SaveDC(DC
);
116 WM_GETIMAGE
, DC
, integer(@SelfR
)) <> $29041961 then begin
117 { SaveIndex := SaveDC(DC);}
118 SetViewportOrgEx(DC
, Left
+ X
, Top
+ Y
, nil);
119 IntersectClipRect(DC
, 0, 0, Width
, Height
);
120 Perform(WM_PAINT
, DC
, 0);
123 RestoreDC(DC
, SaveIndex
);
124 ControlState
:= ControlState
- [csPaintCopy
];
131 with Control
.Parent
do ControlState
:= ControlState
- [csPaintCopy
];
135 procedure RestoreImage(DestDC
: HDC
; SrcBitmap
: TBitmap
; r
: TRect
;
136 dwROP
: dword
); overload
;
138 RestoreImage(DestDC
, SrcBitmap
, r
.Left
, r
.Top
,
139 r
.Right
- r
.Left
, r
.Bottom
- r
.Top
, dwROP
);
142 procedure RestoreImage(DestDC
: HDC
; SrcBitmap
: TBitmap
; l
, t
, w
, h
: integer;
143 dwROP
: dword
); overload
;
148 if (SrcBitmap
.Canvas
.Pixels
[x
, y
] <> $FFFFFF) and
149 (SrcBitMap
.Canvas
.Pixels
[x
, y
] <> $000000) then begin
152 if y
+ h
> SrcBitMap
.Height
then begin
153 y
:= SrcBitMap
.Height
- h
;
155 bitblt(DestDC
, l
, t
, w
, h
,
156 SrcBitMap
.Canvas
.Handle
, x
, y
, dwROP
);
160 procedure SplitColor(C
: TColor
; var r
, g
, b
: integer);
162 b
:= (c
and $FF0000) shr 16;
163 g
:= (c
and $00FF00) shr 08;
164 r
:= (c
and $0000FF) shr 00;
167 procedure AjustBitmap
;
178 function CalcColor(c1
, c2
, c3
: integer): integer;
180 if c1
= c3
then begin
190 { Result := 255 * c1 div c3 - c1 * (255 - c1) * (255 - c2) div c3 div (255 - c3);
193 Result
:= c1
* c2
div c3
;
194 if c2
= 0 then Result
:= c1
* 150 div 255;
195 if Result
> 255 then Result
:= 255;
196 if Result
< 50 then Result
:= Result
+ 50;
199 a := c1 * (255 - c1) * c2 * (255 - c2) div c3 div (255 - c3);
200 a := 255 * 255 - 4 * a;
202 x1 := Trunc((255 - sqrt(a)) / 2);
203 x2 := Trunc((255 + sqrt(a)) / 2);
204 if x1 > x2 then Result := Trunc(x1)
205 else Result := Trunc(x2);
213 if m
.Width
= 0 then exit
;
214 if m
.Height
= 0 then exit
;
216 m
.PixelFormat
:= pf24bit
;
218 SplitColor(ColorToRGB(s
), r
, g
, b
);
219 if r
= 0 then r
:= 1;
220 if g
= 0 then g
:= 1;
221 if b
= 0 then b
:= 1;
222 SplitColor(ColorToRGB(c
), r2
, g2
, b2
);
223 for j
:= 0 to t
.Height
- 1 do begin
225 for i
:= 0 to t
.Width
- 1 do begin
226 p
.rgbtRed
:= CalcColor(p
.rgbtRed
, r2
, r
);
227 p
.rgbtGreen
:= CalcColor(p
.rgbtGreen
, g2
, g
);
228 p
.rgbtBlue
:= CalcColor(p
.rgbtBlue
, b2
, b
);
236 procedure FadeBitmap
;
244 function CalcColor(o
: byte; c
: byte; b
: byte): byte;
250 if d
> b
then d
:= b
;
251 Result
:= c
+ c
* d
div 255;
255 if d
> b
then d
:= b
;
256 Result
:= c
- c
* d
div 255;
261 if m
.Width
= 0 then exit
;
262 if m
.Height
= 0 then exit
;
264 m
.PixelFormat
:= pf24bit
;
266 SplitColor(ColorToRGB(c
), r
, g
, b
);
267 if r
= 0 then r
:= 1;
268 if g
= 0 then g
:= 1;
269 if b
= 0 then b
:= 1;
270 for j
:= 0 to t
.Height
- 1 do begin
272 for i
:= 0 to t
.Width
- 1 do begin
273 p
.rgbtRed
:= CalcColor(p
.rgbtRed
, r
, d
);
274 p
.rgbtGreen
:= CalcColor(p
.rgbtGreen
, g
, d
);
275 p
.rgbtBlue
:= CalcColor(p
.rgbtBlue
, b
, d
);
290 if p
.rgbtBlue
< 255 - D
then p
.rgbtBlue
:= p
.rgbtBlue
+ D
else p
.rgbtBlue
:= 255;
291 if p
.rgbtRed
< 255 - D
then p
.rgbtRed
:= p
.rgbtRed
+ D
else p
.rgbtRed
:= 255;
292 if p
.rgbtGreen
< 255 - D
then p
.rgbtGreen
:= p
.rgbtGreen
+ D
else p
.rgbtGreen
:= 255;
294 if p
.rgbtBlue
> D
then p
.rgbtBlue
:= p
.rgbtBlue
- D
else p
.rgbtBlue
:= 000;
295 if p
.rgbtRed
> D
then p
.rgbtRed
:= p
.rgbtRed
- D
else p
.rgbtRed
:= 000;
296 if p
.rgbtGreen
> D
then p
.rgbtGreen
:= p
.rgbtGreen
- D
else p
.rgbtGreen
:= 000;