Skip to content

Commit bcf0a6e

Browse files
committed
Add about form
1 parent 6c64f91 commit bcf0a6e

File tree

2 files changed

+213
-0
lines changed

2 files changed

+213
-0
lines changed

Splash.dfm

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
object FormSplash: TFormSplash
2+
Left = 192
3+
Top = 124
4+
BorderStyle = bsNone
5+
Caption = 'FormSplash'
6+
ClientHeight = 442
7+
ClientWidth = 912
8+
Color = clBtnFace
9+
Font.Charset = DEFAULT_CHARSET
10+
Font.Color = clWindowText
11+
Font.Height = -11
12+
Font.Name = 'Tahoma'
13+
Font.Style = []
14+
FormStyle = fsStayOnTop
15+
Position = poScreenCenter
16+
OnClick = FormClick
17+
OnClose = FormClose
18+
OnKeyPress = FormKeyPress
19+
TextHeight = 13
20+
object TimerSplash: TTimer
21+
Interval = 4096
22+
OnTimer = TimerSplashTimer
23+
Left = 208
24+
Top = 112
25+
end
26+
end

Splash.pas

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
unit Splash;
2+
3+
interface
4+
5+
uses
6+
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7+
Dialogs, ExtCtrls, GDIPAPI, GDIpOBJ, Activex;
8+
9+
type
10+
TFormSplash = class(TForm)
11+
TimerSplash: TTimer;
12+
procedure FormClose(Sender: TObject; var Action: TCloseAction);
13+
procedure TimerSplashTimer(Sender: TObject);
14+
procedure FormKeyPress(Sender: TObject; var Key: Char);
15+
procedure FormClick(Sender: TObject);
16+
17+
private
18+
{ Private declarations }
19+
protected
20+
procedure WMNCHitTest(var message: TWMNCHitTest); message WM_NCHITTEST;
21+
public
22+
{ Public declarations }
23+
procedure Execute;
24+
end;
25+
26+
var
27+
FormSplash: TFormSplash;
28+
29+
implementation
30+
31+
{$R *.dfm}
32+
33+
procedure TFormSplash.FormClose(Sender: TObject; var Action: TCloseAction);
34+
begin
35+
TimerSplash.Destroy;
36+
Action := caFree;
37+
end;
38+
39+
procedure TFormSplash.TimerSplashTimer(Sender: TObject);
40+
begin
41+
Close;
42+
end;
43+
44+
procedure TFormSplash.FormKeyPress(Sender: TObject; var Key: Char);
45+
begin
46+
Close;
47+
end;
48+
49+
procedure TFormSplash.WMNCHitTest(var message: TWMNCHitTest);
50+
begin
51+
Message.Result := HTCAPTION;
52+
end;
53+
54+
procedure PremultiplyBitmap(Bitmap: TBitmap);
55+
var
56+
Row, Col: integer;
57+
p: PRGBQuad;
58+
PreMult: array [byte, byte] of byte;
59+
begin
60+
// precalculate all possible values of a*b
61+
for Row := 0 to 255 do
62+
for Col := Row to 255 do
63+
begin
64+
PreMult[Row, Col] := Row * Col div 255;
65+
if (Row <> Col) then
66+
PreMult[Col, Row] := PreMult[Row, Col]; // a*b = b*a
67+
end;
68+
69+
for Row := 0 to Bitmap.Height - 1 do
70+
begin
71+
Col := Bitmap.Width;
72+
p := Bitmap.ScanLine[Row];
73+
while (Col > 0) do
74+
begin
75+
p.rgbBlue := PreMult[p.rgbReserved, p.rgbBlue];
76+
p.rgbGreen := PreMult[p.rgbReserved, p.rgbGreen];
77+
p.rgbRed := PreMult[p.rgbReserved, p.rgbRed];
78+
inc(p);
79+
dec(Col);
80+
end;
81+
end;
82+
end;
83+
84+
type
85+
TFixedStreamAdapter = class(TStreamAdapter)
86+
public
87+
function Stat(out statstg: TStatStg; grfStatFlag: DWORD): HResult;
88+
override; stdcall;
89+
end;
90+
91+
function TFixedStreamAdapter.Stat(out statstg: TStatStg;
92+
grfStatFlag: DWORD): HResult;
93+
begin
94+
Result := inherited Stat(statstg, grfStatFlag);
95+
statstg.pwcsName := nil;
96+
end;
97+
98+
procedure TFormSplash.Execute;
99+
var
100+
Ticks: DWORD;
101+
BlendFunction: TBlendFunction;
102+
BitmapPos: TPoint;
103+
BitmapSize: TSize;
104+
exStyle: DWORD;
105+
Bitmap: TBitmap;
106+
PNGBitmap: TGPBitmap;
107+
BitmapHandle: HBITMAP;
108+
Stream: TStream;
109+
StreamAdapter: IStream;
110+
begin
111+
// Enable window layering
112+
exStyle := GetWindowLongA(Handle, GWL_EXSTYLE);
113+
if (exStyle and WS_EX_LAYERED = 0) then
114+
SetWindowLong(Handle, GWL_EXSTYLE, exStyle or WS_EX_LAYERED);
115+
116+
Bitmap := TBitmap.Create;
117+
try
118+
// Load the PNG from a resource
119+
Stream := TResourceStream.Create(HInstance, 'SPLASH', RT_RCDATA);
120+
try
121+
// Wrap the VCL stream in a COM IStream
122+
StreamAdapter := TFixedStreamAdapter.Create(Stream);
123+
try
124+
// Create and load a GDI+ bitmap from the stream
125+
PNGBitmap := TGPBitmap.Create(StreamAdapter);
126+
try
127+
// Convert the PNG to a 32 bit bitmap
128+
PNGBitmap.GetHBITMAP(MakeColor(0, 0, 0, 0), BitmapHandle);
129+
// Wrap the bitmap in a VCL TBitmap
130+
Bitmap.Handle := BitmapHandle;
131+
finally
132+
PNGBitmap.Free;
133+
end;
134+
finally
135+
StreamAdapter := nil;
136+
end;
137+
finally
138+
Stream.Free;
139+
end;
140+
141+
ASSERT(Bitmap.PixelFormat = pf32bit,
142+
'Wrong bitmap format - must be 32 bits/pixel');
143+
144+
// Perform run-time premultiplication
145+
PremultiplyBitmap(Bitmap);
146+
147+
// Resize form to fit bitmap
148+
ClientWidth := Bitmap.Width;
149+
ClientHeight := Bitmap.Height;
150+
151+
// Position bitmap on form
152+
BitmapPos := Point(0, 0);
153+
BitmapSize.cx := Bitmap.Width;
154+
BitmapSize.cy := Bitmap.Height;
155+
156+
// Setup alpha blending parameters
157+
BlendFunction.BlendOp := AC_SRC_OVER;
158+
BlendFunction.BlendFlags := 0;
159+
BlendFunction.SourceConstantAlpha := 0; // Start completely transparent
160+
BlendFunction.AlphaFormat := AC_SRC_ALPHA;
161+
162+
Show;
163+
// ... and action!
164+
Ticks := 0;
165+
while (BlendFunction.SourceConstantAlpha < 255) do
166+
begin
167+
while (Ticks = GetTickCount) do
168+
Sleep(10); // Don't fade too fast
169+
Ticks := GetTickCount;
170+
inc(BlendFunction.SourceConstantAlpha,
171+
(255 - BlendFunction.SourceConstantAlpha) div 32 + 1); // Fade in
172+
UpdateLayeredWindow(Handle, 0, nil, @BitmapSize, Bitmap.Canvas.Handle,
173+
@BitmapPos, 0, @BlendFunction, ULW_ALPHA);
174+
end;
175+
finally
176+
Bitmap.Free;
177+
end;
178+
// Start timer to hide form after a short while
179+
TimerSplash.Enabled := True;
180+
end;
181+
182+
procedure TFormSplash.FormClick(Sender: TObject);
183+
begin
184+
Close;
185+
end;
186+
187+
end.

0 commit comments

Comments
 (0)