1 | unit TrayAnimation;
|
---|
2 |
|
---|
3 | { D5 and down don't support alpha-blending (transparent forms). }
|
---|
4 | {$IFDEF VER140} {$DEFINE DELPHI_6} {$ENDIF}
|
---|
5 | {$IFDEF VER150} {$DEFINE DELPHI_7} {$ENDIF}
|
---|
6 | {$IFDEF DELPHI_6} {$DEFINE DELPHI_6_UP} {$ENDIF}
|
---|
7 | {$IFDEF DELPHI_7} {$DEFINE DELPHI_6_UP} {$ENDIF}
|
---|
8 |
|
---|
9 | interface
|
---|
10 |
|
---|
11 | uses
|
---|
12 | Windows, Classes, Graphics, Forms;
|
---|
13 |
|
---|
14 | type
|
---|
15 | TWindowFader = class(TThread)
|
---|
16 | private
|
---|
17 | BlendValue: Integer;
|
---|
18 | procedure Fade;
|
---|
19 | public
|
---|
20 | FadeOut: Boolean;
|
---|
21 | procedure Execute; override;
|
---|
22 | end;
|
---|
23 |
|
---|
24 | TWindowImploder = class(TThread)
|
---|
25 | private
|
---|
26 | X, Y, W, H: Integer;
|
---|
27 | procedure Implode;
|
---|
28 | public
|
---|
29 | Imploding: Boolean;
|
---|
30 | procedure Execute; override;
|
---|
31 | end;
|
---|
32 |
|
---|
33 | TWindowOutlineImploder = class(TThread)
|
---|
34 | private
|
---|
35 | X, Y, W, H: Integer;
|
---|
36 | DesktopCanvas: TCanvas;
|
---|
37 | procedure Implode;
|
---|
38 | public
|
---|
39 | Imploding: Boolean;
|
---|
40 | constructor Create;
|
---|
41 | destructor Destroy; override;
|
---|
42 | procedure Execute; override;
|
---|
43 | end;
|
---|
44 |
|
---|
45 |
|
---|
46 | procedure FloatingRectangles(Minimizing, OverrideUserSettings: Boolean);
|
---|
47 |
|
---|
48 | implementation
|
---|
49 |
|
---|
50 | uses
|
---|
51 | Math, ShellApi, Messages, Main;
|
---|
52 |
|
---|
53 | {----------------- Stand-alone methods ----------------}
|
---|
54 |
|
---|
55 | procedure FloatingRectangles(Minimizing, OverrideUserSettings: Boolean);
|
---|
56 | var
|
---|
57 | RectFrom, RectTo: TRect;
|
---|
58 | GotRectTo: Boolean;
|
---|
59 | abd: TAppBarData;
|
---|
60 | HTaskbar, HTrayWnd: HWND;
|
---|
61 | ResetRegistry: Boolean;
|
---|
62 | ai: TAnimationInfo;
|
---|
63 |
|
---|
64 | procedure SetAnimation(Animation: Boolean);
|
---|
65 | begin
|
---|
66 | FillChar(ai, SizeOf(ai), 0);
|
---|
67 | ai.cbSize := SizeOf(ai);
|
---|
68 | if Animation then
|
---|
69 | ai.iMinAnimate := 1
|
---|
70 | else
|
---|
71 | ai.iMinAnimate := 0;
|
---|
72 | SystemParametersInfo(SPI_SETANIMATION, 0, @ai, SPIF_SENDCHANGE);
|
---|
73 | end;
|
---|
74 |
|
---|
75 | begin
|
---|
76 | // Check if user wants window animation
|
---|
77 | ResetRegistry := False;
|
---|
78 | if OverrideUserSettings then
|
---|
79 | begin
|
---|
80 | FillChar(ai, SizeOf(ai), 0);
|
---|
81 | ai.cbSize := SizeOf(ai);
|
---|
82 | SystemParametersInfo(SPI_GETANIMATION, 0, @ai, SPIF_SENDCHANGE);
|
---|
83 | if ai.iMinAnimate = 0 then
|
---|
84 | begin
|
---|
85 | // Temporarily enable window animation
|
---|
86 | ResetRegistry := True;
|
---|
87 | SetAnimation(True);
|
---|
88 | end;
|
---|
89 | end;
|
---|
90 |
|
---|
91 | RectFrom := MainForm.BoundsRect;
|
---|
92 | GotRectTo := False;
|
---|
93 |
|
---|
94 | // Get the traybar's bounding rectangle
|
---|
95 | HTaskbar := FindWindow('Shell_TrayWnd', nil);
|
---|
96 | if HTaskbar <> 0 then
|
---|
97 | begin
|
---|
98 | HTrayWnd := FindWindowEx(HTaskbar, 0, 'TrayNotifyWnd', nil);
|
---|
99 | if HTrayWnd <> 0 then
|
---|
100 | if GetWindowRect(HTrayWnd, RectTo) then
|
---|
101 | GotRectTo := True;
|
---|
102 | end;
|
---|
103 |
|
---|
104 | // If that fails, invent a rectangle in the corner where the traybar is
|
---|
105 | if not GotRectTo then
|
---|
106 | begin
|
---|
107 | FillChar(abd, SizeOf(abd), 0);
|
---|
108 | abd.cbSize := SizeOf(abd);
|
---|
109 | if SHAppBarMessage(ABM_GETTASKBARPOS, abd) = 0 then Exit;
|
---|
110 | with Screen, abd.rc do
|
---|
111 | if (Top > 0) or (Left > 0) then
|
---|
112 | RectTo := Rect(Width-32, Height-32, Width, Height)
|
---|
113 | else if (Bottom < Height) then
|
---|
114 | RectTo := Rect(Width-32, 0, Width, 32)
|
---|
115 | else if (Right < Width) then
|
---|
116 | RectTo := Rect(0, Height-32, 32, Height);
|
---|
117 | end;
|
---|
118 |
|
---|
119 | if Minimizing then
|
---|
120 | DrawAnimatedRects(MainForm.Handle, IDANI_CAPTION, RectFrom, RectTo)
|
---|
121 | else
|
---|
122 | DrawAnimatedRects(MainForm.Handle, IDANI_CAPTION, RectTo, RectFrom);
|
---|
123 |
|
---|
124 | if ResetRegistry then
|
---|
125 | SetAnimation(False); // Disable window animation
|
---|
126 | end;
|
---|
127 |
|
---|
128 | {-------------------- TWindowFader --------------------}
|
---|
129 |
|
---|
130 | procedure TWindowFader.Execute;
|
---|
131 | begin
|
---|
132 | {$IFDEF DELPHI_6_UP}
|
---|
133 | BlendValue := MainForm.AlphaBlendValue;
|
---|
134 | {$ENDIF}
|
---|
135 | while not Terminated do
|
---|
136 | begin
|
---|
137 | if FadeOut then
|
---|
138 | Dec(BlendValue, 25)
|
---|
139 | else
|
---|
140 | Inc(BlendValue, 25);
|
---|
141 | Sleep(10);
|
---|
142 | // Application.ProcessMessages;
|
---|
143 | Synchronize(Fade);
|
---|
144 | if (BlendValue <= 0) or (BlendValue >= 255) then
|
---|
145 | Terminate;
|
---|
146 | end;
|
---|
147 | end;
|
---|
148 |
|
---|
149 |
|
---|
150 | procedure TWindowFader.Fade;
|
---|
151 | begin
|
---|
152 | {$IFDEF DELPHI_6_UP}
|
---|
153 | if (BlendValue >= 0) and (BlendValue <= 255) then
|
---|
154 | MainForm.AlphaBlendValue := BlendValue;
|
---|
155 | {$ENDIF}
|
---|
156 | end;
|
---|
157 |
|
---|
158 | {------------------ TWindowImploder -------------------}
|
---|
159 |
|
---|
160 | procedure TWindowImploder.Execute;
|
---|
161 | const
|
---|
162 | minW = 120;
|
---|
163 | minH = 25;
|
---|
164 | deltaGrowth = 0.2;
|
---|
165 | var
|
---|
166 | maxW, maxH: Integer;
|
---|
167 | deltaW, deltaH: Integer;
|
---|
168 | begin
|
---|
169 | with MainForm do
|
---|
170 | begin
|
---|
171 | X := Left;
|
---|
172 | Y := Top;
|
---|
173 | W := Width;
|
---|
174 | H := Height;
|
---|
175 | if Imploding then
|
---|
176 | begin
|
---|
177 | // Store current form size
|
---|
178 | StartX := Left;
|
---|
179 | StartY := Top;
|
---|
180 | StartW := Width;
|
---|
181 | StartH := Height;
|
---|
182 | end;
|
---|
183 | // Remember previous form size
|
---|
184 | maxW := StartW;
|
---|
185 | maxH := StartH;
|
---|
186 | end;
|
---|
187 |
|
---|
188 | while not Terminated do
|
---|
189 | begin
|
---|
190 | deltaW := Round((W-minW) * deltaGrowth);
|
---|
191 | deltaH := Round((H-minH) * deltaGrowth);
|
---|
192 | if deltaW = 0 then
|
---|
193 | Inc(deltaW);
|
---|
194 | if Odd(deltaW) then
|
---|
195 | Inc(deltaW);
|
---|
196 | if deltaH = 0 then
|
---|
197 | Inc(deltaH);
|
---|
198 | if Odd(deltaH) then
|
---|
199 | Inc(deltaH);
|
---|
200 | if Imploding then
|
---|
201 | begin
|
---|
202 | W := W - deltaW;
|
---|
203 | H := H - deltaH;
|
---|
204 | X := X + (deltaW div 2);
|
---|
205 | Y := Y + (deltaH div 2);
|
---|
206 | end
|
---|
207 | else
|
---|
208 | begin
|
---|
209 | W := W + deltaW;
|
---|
210 | H := H + deltaH;
|
---|
211 | X := X - (deltaW div 2);
|
---|
212 | Y := Y - (deltaH div 2);
|
---|
213 | end;
|
---|
214 | Sleep(10);
|
---|
215 |
|
---|
216 | if (Imploding and ((W <= minW) or (H <= minH) or (deltaW = 0))) or
|
---|
217 | (not Imploding and ((W >= maxW) or (H >= maxH) or (deltaH = 0))) then
|
---|
218 | Terminate;
|
---|
219 |
|
---|
220 | if not Terminated then
|
---|
221 | Synchronize(Implode);
|
---|
222 | Application.ProcessMessages;
|
---|
223 | end;
|
---|
224 |
|
---|
225 | if not Imploding then
|
---|
226 | begin
|
---|
227 | with MainForm do
|
---|
228 | SetWindowPos(Handle, 0, StartX, StartY, StartW, StartH, SWP_NOZORDER);
|
---|
229 | Application.ProcessMessages;
|
---|
230 | end;
|
---|
231 | end;
|
---|
232 |
|
---|
233 |
|
---|
234 | procedure TWindowImploder.Implode;
|
---|
235 | begin
|
---|
236 | SetWindowPos(MainForm.Handle, 0, X, Y, W, H, SWP_NOZORDER);
|
---|
237 | end;
|
---|
238 |
|
---|
239 | {--------------- TWindowOutlineImploder ---------------}
|
---|
240 |
|
---|
241 | constructor TWindowOutlineImploder.Create;
|
---|
242 | begin
|
---|
243 | inherited Create(False);
|
---|
244 | DesktopCanvas := TCanvas.Create;
|
---|
245 | with DesktopCanvas do
|
---|
246 | begin
|
---|
247 | Handle := GetDC(0); // HDC of desktop
|
---|
248 | // Handle := GetWindowDC(GetDesktopWindow);
|
---|
249 | Pen.Mode := pmNotXor;
|
---|
250 | Pen.Style := psDot;
|
---|
251 | Pen.Width := 2;
|
---|
252 | Pen.Color := clGray;
|
---|
253 | // Brush.Color := clGray;
|
---|
254 | // Brush.Style := bsDiagCross;
|
---|
255 | Brush.Style := bsClear;
|
---|
256 | end;
|
---|
257 | end;
|
---|
258 |
|
---|
259 |
|
---|
260 | destructor TWindowOutlineImploder.Destroy;
|
---|
261 | begin
|
---|
262 | // ReleaseDC(GetDesktopWindow, DesktopCanvas.Handle);
|
---|
263 | ReleaseDC(0, DesktopCanvas.Handle);
|
---|
264 | DesktopCanvas.Handle := 0;
|
---|
265 | DesktopCanvas.Free;
|
---|
266 | DesktopCanvas := nil;
|
---|
267 | inherited Destroy;
|
---|
268 | end;
|
---|
269 |
|
---|
270 |
|
---|
271 | procedure TWindowOutlineImploder.Execute;
|
---|
272 | const
|
---|
273 | minW = 25;
|
---|
274 | minH = 25;
|
---|
275 | deltaGrowth = 0.25;
|
---|
276 | var
|
---|
277 | maxW, maxH: Integer;
|
---|
278 | deltaW, deltaH: Integer;
|
---|
279 | begin
|
---|
280 | with MainForm do
|
---|
281 | begin
|
---|
282 | if Imploding then
|
---|
283 | begin
|
---|
284 | X := Left;
|
---|
285 | Y := Top;
|
---|
286 | W := Width;
|
---|
287 | H := Height;
|
---|
288 | // Store current form size
|
---|
289 | StartX := Left;
|
---|
290 | StartY := Top;
|
---|
291 | StartW := Width;
|
---|
292 | StartH := Height;
|
---|
293 | CoolTrayIcon1.HideMainForm;
|
---|
294 | end
|
---|
295 | else
|
---|
296 | begin
|
---|
297 | X := StartX + ((StartW-minW) div 2);
|
---|
298 | Y := StartY + ((StartH-minH) div 2);
|
---|
299 | W := minW;
|
---|
300 | H := minH;
|
---|
301 | end;
|
---|
302 | // Remember previous form size
|
---|
303 | maxW := StartW;
|
---|
304 | maxH := StartH;
|
---|
305 | end;
|
---|
306 |
|
---|
307 | while not Terminated do
|
---|
308 | begin
|
---|
309 | deltaW := Round((W-minW) * deltaGrowth);
|
---|
310 | deltaH := Round((H-minH) * deltaGrowth);
|
---|
311 | if deltaW = 0 then
|
---|
312 | Inc(deltaW);
|
---|
313 | if Odd(deltaW) then
|
---|
314 | Inc(deltaW);
|
---|
315 | if deltaH = 0 then
|
---|
316 | Inc(deltaH);
|
---|
317 | if Odd(deltaH) then
|
---|
318 | Inc(deltaH);
|
---|
319 | if Imploding then
|
---|
320 | begin
|
---|
321 | W := W - deltaW;
|
---|
322 | H := H - deltaH;
|
---|
323 | X := X + (deltaW div 2);
|
---|
324 | Y := Y + (deltaH div 2);
|
---|
325 | end
|
---|
326 | else
|
---|
327 | begin
|
---|
328 | W := W + deltaW;
|
---|
329 | H := H + deltaH;
|
---|
330 | X := X - (deltaW div 2);
|
---|
331 | Y := Y - (deltaH div 2);
|
---|
332 | end;
|
---|
333 | Synchronize(Implode);
|
---|
334 |
|
---|
335 | if (Imploding and ((W <= minW) or (H <= minH) or (deltaW = 0))) or
|
---|
336 | (not Imploding and ((W >= maxW) or (H >= maxH) or (deltaH = 0))) then
|
---|
337 | Terminate;
|
---|
338 | end;
|
---|
339 | end;
|
---|
340 |
|
---|
341 |
|
---|
342 | procedure TWindowOutlineImploder.Implode;
|
---|
343 | {var
|
---|
344 | R: TRect;}
|
---|
345 | begin
|
---|
346 | if not Terminated then
|
---|
347 | if (DesktopCanvas <> nil) and (DesktopCanvas.Handle <> 0) then
|
---|
348 | begin
|
---|
349 | // R := Rect(X, Y, X+W, Y+H);
|
---|
350 | // InvalidateRect(DesktopCanvas.Handle, @R, True);
|
---|
351 | // PostMessage(DesktopCanvas.Handle, WM_SETREDRAW, 1, 0);
|
---|
352 | // RedrawWindow(DesktopCanvas.Handle, 0, 0, RDW_ERASE or RDW_INVALIDATE or RDW_ERASENOW);
|
---|
353 | // UpdateWindow(DesktopCanvas.Handle);
|
---|
354 | DesktopCanvas.Rectangle(X, Y, X+W, Y+H);
|
---|
355 | Sleep(10);
|
---|
356 | DesktopCanvas.Rectangle(X, Y, X+W, Y+H);
|
---|
357 | end;
|
---|
358 | end;
|
---|
359 |
|
---|
360 | end.
|
---|
361 |
|
---|