Link to Bob S article gives the correct answer. Since this article contains quite a bit of additional information that you really need, here is the form / unit that I create through it (note that you will need the GraphicEx library from here :
unit Splash2Form; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, GraphicEx; type TSplash2 = class(TForm) private { Private declarations } procedure PreMultiplyBitmap(Bitmap: TBitmap); public constructor Create(Owner: TComponent);override; { Public declarations } procedure CreateParams(var Params: TCreateParams);override; procedure Execute; end; var Splash2: TSplash2; implementation {$R *.dfm} { TSplash2 } constructor TSplash2.Create(Owner: TComponent); begin inherited; Brush.Style := bsClear; end; procedure TSplash2.CreateParams(var Params: TCreateParams); begin inherited; end; procedure TSplash2.Execute; var exStyle: DWORD; BitmapPos: TPoint; BitmapSize: TSize; BlendFunction: TBlendFunction; PNG: TPNGGraphic; Stream: TResourceStream; 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); PNG := TPNGGraphic.Create; try Stream := TResourceStream.Create(HInstance, 'SPLASH', RT_RCDATA); try PNG.LoadFromStream(Stream); finally Stream.Free; end; PreMultiplyBitmap(PNG); ClientWidth := PNG.Width; ClientHeight := PNG.Height; BitmapPos := Point(0, 0); BitmapSize.cx := ClientWidth; BitmapSize.cy := ClientHeight; // Setup alpha blending parameters BlendFunction.BlendOp := AC_SRC_OVER; BlendFunction.BlendFlags := 0; BlendFunction.SourceConstantAlpha := 255; BlendFunction.AlphaFormat := AC_SRC_ALPHA; // ... and action! UpdateLayeredWindow(Handle, 0, nil, @BitmapSize, PNG.Canvas.Handle, @BitmapPos, 0, @BlendFunction, ULW_ALPHA); Show; finally PNG.Free; end; end; procedure TSplash2.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; end.
source share