-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUTransition.pas
184 lines (166 loc) · 4.65 KB
/
UTransition.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
unit UTransition;
{
(c)2017 Execute SARL
Transition effet for two TWinControl on the same parent (Align = alClient)
}
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;
type
TTransition = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FadeOut(Sender: TObject);
private
const
SPEED = 20; // ms
SLIDE = 10; // px
var
{ Déclarations privées }
FForm : TForm;
FControl1: TWinControl;
FControl2: TWinControl;
FImage : TBitmap;
FPanel : TBitmap;
FRect : TRect;
FOpacity : Byte;
FPosition: Integer;
procedure WMEraseBkGnd(var Msg: TMessage); message WM_ERASEBKGND;
procedure FadeIn(Sender: TObject);
public
{ Déclarations publiques }
procedure Execute(Form: TForm; Control1, Control2: TWinControl);
end;
var
Transition: TTransition;
implementation
{$R *.dfm}
// take a picture of a Control
procedure Capture(Control: TWinControl; Bitmap: TBitmap);
var
DC: HDC;
begin
Bitmap.SetSize(Control.Width, Control.Height);
DC := GetWindowDC(Control.Handle);
try
BitBlt(Bitmap.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, DC, 0, 0, SRCCOPY);
finally
ReleaseDC(Control.Handle, DC);
end;
end;
{ TTransition }
procedure TTransition.FormCreate(Sender: TObject);
begin
FImage := TBitmap.Create; // Picture of the parent Form
FPanel := TBitmap.Create; // Picture of the controls
end;
procedure TTransition.FormDestroy(Sender: TObject);
begin
FImage.Free;
FPanel.Free;
end;
procedure TTransition.Execute(Form: TForm; Control1, Control2: TWinControl);
begin
FForm := Form;
FControl1 := Control1;
FControl2 := Control2;
// take a picture of the actual form
Capture(FForm, FImage);
// place this Transition form on top of it
SetWindowPos(Handle, HWND_TOPMOST, FForm.Left, FForm.Top, FForm.Width, FForm.Height, SWP_NOACTIVATE or SWP_SHOWWINDOW);
Visible := True;
// get Control1 position in the form
FRect := FControl1.ClientRect;
FRect.TopLeft := ScreenToClient(FControl1.ClientToScreen(FRect.TopLeft));
FRect.BottomRight := ScreenToClient(FControl1.ClientToScreen(FRect.BottomRight));
// copy it's picture
FPanel.SetSize(FRect.Width, FRect.Height);
FPanel.Canvas.CopyRect(TRect.Create(0, 0, FRect.Width, FRect.Height), FImage.Canvas, FRect);
// start fade out
FOpacity := 255;
FPosition := 0;
Timer1.OnTimer := FadeOut;
Timer1.Enabled := True;
end;
procedure TTransition.WMEraseBkGnd(var Msg: TMessage);
begin
Msg.Result := 1;
end;
procedure TTransition.FormPaint(Sender: TObject);
var
BF: TBlendFunction;
x1: Integer;
x2: Integer;
w : Integer;
begin
// offline Form picture
with FImage.Canvas do
begin
// clear the control rectangle
Brush.Color := clBtnFace;
FillRect(FRect);
// redraw the control at a new position
// Draw(FRect.Left + FPosition, FRect.Top, FPanel, FOpacity);
BF.BlendOp := AC_SRC_OVER;
BF.BlendFlags := 0;
BF.SourceConstantAlpha := FOpacity;
BF.AlphaFormat := 0;
if FPosition >= 0 then
begin
x1 := FRect.Left + FPosition;
x2 := 0;
w := FRect.Width - FPosition;
end else begin
x1 := 0;
x2 := - FPosition;
w := FRect.Width + FPosition;
end;
Winapi.Windows.AlphaBlend(Handle, x1, FRect.Top, w, FRect.Height,
FPanel.Canvas.Handle, x2, 0, w, FRect.Height, BF);
end;
// draw the updated picture on the screen
Canvas.Draw(0, 0, FImage);
end;
procedure TTransition.FadeOut(Sender: TObject);
begin
// first time, swap the two controls
if FPosition = 0 then
begin
FControl1.Hide;
FControl2.Show;
end;
// need to fade out
if FOpacity > SPEED then
begin
Inc(FPosition, SLIDE);
Dec(FOpacity, SPEED);
Paint;
end else begin
// it's time to show the new control (it is now visibile)
Capture(FForm, FImage);
// get the picture of the new control
FPanel.Canvas.CopyRect(TRect.Create(0, 0, FRect.Width, FRect.Height), FImage.Canvas, FRect);
// it's time to fade in
//FPosition := - FPosition;
Timer1.OnTimer := FadeIn;
end;
end;
procedure TTransition.FadeIn(Sender: TObject);
begin
// not done
if FOpacity < 255 - SPEED then
begin
Dec(FPosition, SLIDE);
Inc(FOpacity, SPEED);
Paint;
end else begin
// transition done
Timer1.Enabled := False;
Hide;
end;
end;
end.