[英]Fade in an alpha-blended PNG form in Delphi
幾年前,當Vista首次發布時,我問了一個關於這個問題的問題,但從未解決過這個問題,並將其作為后來考慮的問題擱置了。
我有一個閃屏,我努力讓自己看起來很棒。 它是一個32bpp的alpha混合PNG。 我有一些代碼(如果需要我可以挖掘!)在Windows XP或Vista +下關閉桌面組合時效果很好。 然而,在Vista +下,所有透明部分都是黑色的,破壞了一切看起來很棒的東西!
所以,我的問題是這樣的:因為任何人都可以將一個32bpp的alpha混合PNG作為啟動畫面顯示, 無論是否激活桌面合成都可以使用 ? 如果需要,我可以免費或以其他方式使用第三方組件。
理想情況下,這適用於Delphi 7。
更新:除了下面的答案,這些工作非常好,我發現TMS TAdvSmoothSplashScreen組件也能很好地處理這個任務,如果有點復雜的話。
蒂姆,我剛剛在Vista / D2007上嘗試了這個,選擇了'Windows Classic'主題:
德爾福Alpha混合啟動畫面 - 第2部分http://melander.dk/articles/alphasplash2/2/
沒有我能看到的黑色背景......它看起來仍然很棒。
Bob S鏈接的文章給出了正確的答案。 由於那篇文章包含了你真正需要的額外信息,這里是我通過它創建的表單/單元(請注意,你需要從這里獲得GraphicEx庫:
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.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.