meneerroux
asked on
Show controls on PNG Alpha Blended Form
Hi there,
Please see my code attached below - this allows me to show a PNG graphic as a alphablended splash screen. This only shows my bitmap, I need to see other controls on my form and be able to click on them, but still retain the alphablended effect. I think the problem lies in that the form style is set to WS_EX_LAYERED.
uses
GraphicEx;
...
procedure PremultiplyBitmap(Bitmap: TBitmap);
var
Row, Col: integer;
p: PRGBQuad;
PreMult: array[byte, byte] of byte;
begin
// Precalculate all possible values of a*b
for Row := 0 to 255 do
for Col := Row to 255 do
begin
PreMult[Row, Col] := Row * Col div 255;
if (Row <> Col) then
PreMult[Col, Row] := PreMult[Row, Col]; // a*b = b*a
end;
for Row := 0 to Bitmap.Height-1 do
begin
Col := Bitmap.Width;
p := Bitmap.ScanLine[Row];
while (Col > 0) do
begin
p.rgbBlue := PreMult[p.rgbReserved, p.rgbBlue];
p.rgbGreen := PreMult[p.rgbReserved, p.rgbGreen];
p.rgbRed := PreMult[p.rgbReserved, p.rgbRed];
inc(p);
dec(Col);
end;
end;
end;
procedure TFormSplash.Execute;
var
Ticks: DWORD;
BlendFunction: TBlendFunction;
BitmapPos: TPoint;
BitmapSize: TSize;
exStyle: DWORD;
Bitmap: TBitmap;
Stream: TStream;
begin
// Enable window layering
exStyle := GetWindowLongA(Handle, GWL_EXSTYLE);
if (exStyle and WS_EX_LAYERED = 0) then
SetWindowLong(Handle, GWL_EXSTYLE, exStyle or WS_EX_LAYERED);
// Bitmap := TBitmap.Create;
Bitmap := TPNGGraphic.Create;
try
//Bitmap.LoadFromFile('DLL SplashForm \splash.pn g');
Stream := TResourceStream.Create(HIn stance, 'SPLASH', RT_RCDATA);
try
Bitmap.LoadFromStream(Stre am);
finally
Stream.Free;
end;
ASSERT(Bitmap.PixelFormat = pf32bit, 'Wrong bitmap format - must be 32 bits/pixel');
// Perform run-time premultiplication
PremultiplyBitmap(Bitmap);
// Resize form to fit bitmap
ClientWidth := Bitmap.Width;
ClientHeight := Bitmap.Height;
// Position bitmap on form
BitmapPos := Point(0, 0);
BitmapSize.cx := Bitmap.Width;
BitmapSize.cy := Bitmap.Height;
// Setup alpha blending parameters
BlendFunction.BlendOp := AC_SRC_OVER;
BlendFunction.BlendFlags := 0;
BlendFunction.SourceConsta ntAlpha := 0; // Start completely transparent
BlendFunction.AlphaFormat := AC_SRC_ALPHA;
Show;
Width := 0;
Height := 0;
// ... and action!
Ticks := 0;
while (BlendFunction.SourceConst antAlpha < 255) do
begin
while (Ticks = GetTickCount) do
Sleep(25); // Don't fade too fast
Ticks := GetTickCount;
inc(BlendFunction.SourceCo nstantAlph a,
(255-BlendFunction.SourceC onstantAlp ha) div 32+1); // Fade in
UpdateLayeredWindow(Handle , 0, nil, @BitmapSize, Bitmap.Canvas.Handle,
@BitmapPos, 0, @BlendFunction, ULW_ALPHA);
end;
finally
Bitmap.Free;
end;
end;
Please see my code attached below - this allows me to show a PNG graphic as a alphablended splash screen. This only shows my bitmap, I need to see other controls on my form and be able to click on them, but still retain the alphablended effect. I think the problem lies in that the form style is set to WS_EX_LAYERED.
uses
GraphicEx;
...
procedure PremultiplyBitmap(Bitmap: TBitmap);
var
Row, Col: integer;
p: PRGBQuad;
PreMult: array[byte, byte] of byte;
begin
// Precalculate all possible values of a*b
for Row := 0 to 255 do
for Col := Row to 255 do
begin
PreMult[Row, Col] := Row * Col div 255;
if (Row <> Col) then
PreMult[Col, Row] := PreMult[Row, Col]; // a*b = b*a
end;
for Row := 0 to Bitmap.Height-1 do
begin
Col := Bitmap.Width;
p := Bitmap.ScanLine[Row];
while (Col > 0) do
begin
p.rgbBlue := PreMult[p.rgbReserved, p.rgbBlue];
p.rgbGreen := PreMult[p.rgbReserved, p.rgbGreen];
p.rgbRed := PreMult[p.rgbReserved, p.rgbRed];
inc(p);
dec(Col);
end;
end;
end;
procedure TFormSplash.Execute;
var
Ticks: DWORD;
BlendFunction: TBlendFunction;
BitmapPos: TPoint;
BitmapSize: TSize;
exStyle: DWORD;
Bitmap: TBitmap;
Stream: TStream;
begin
// Enable window layering
exStyle := GetWindowLongA(Handle, GWL_EXSTYLE);
if (exStyle and WS_EX_LAYERED = 0) then
SetWindowLong(Handle, GWL_EXSTYLE, exStyle or WS_EX_LAYERED);
// Bitmap := TBitmap.Create;
Bitmap := TPNGGraphic.Create;
try
//Bitmap.LoadFromFile('DLL
Stream := TResourceStream.Create(HIn
try
Bitmap.LoadFromStream(Stre
finally
Stream.Free;
end;
ASSERT(Bitmap.PixelFormat = pf32bit, 'Wrong bitmap format - must be 32 bits/pixel');
// Perform run-time premultiplication
PremultiplyBitmap(Bitmap);
// Resize form to fit bitmap
ClientWidth := Bitmap.Width;
ClientHeight := Bitmap.Height;
// Position bitmap on form
BitmapPos := Point(0, 0);
BitmapSize.cx := Bitmap.Width;
BitmapSize.cy := Bitmap.Height;
// Setup alpha blending parameters
BlendFunction.BlendOp := AC_SRC_OVER;
BlendFunction.BlendFlags := 0;
BlendFunction.SourceConsta
BlendFunction.AlphaFormat := AC_SRC_ALPHA;
Show;
Width := 0;
Height := 0;
// ... and action!
Ticks := 0;
while (BlendFunction.SourceConst
begin
while (Ticks = GetTickCount) do
Sleep(25); // Don't fade too fast
Ticks := GetTickCount;
inc(BlendFunction.SourceCo
(255-BlendFunction.SourceC
UpdateLayeredWindow(Handle
@BitmapPos, 0, @BlendFunction, ULW_ALPHA);
end;
finally
Bitmap.Free;
end;
end;
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Did you try the alpha controls?
You could try to make an extra window on top of your layered window, make it fully transparent and place normal controls on there.
You could try to make an extra window on top of your layered window, make it fully transparent and place normal controls on there.
ASKER
Yes, thats exactly what I did... thanks for your help.
ASKER