Delphi 如何使窗体在没有边框的情况下透明?
我想知道是否有可能使表单透明(AlphaBlend),而边界(最小化按钮所在的位置以及所有这些)也不透明?如果是,我怎么做Delphi 如何使窗体在没有边框的情况下透明?,delphi,delphi-xe2,Delphi,Delphi Xe2,我想知道是否有可能使表单透明(AlphaBlend),而边界(最小化按钮所在的位置以及所有这些)也不透明?如果是,我怎么做 这是可能的,但您在此类表单上放置的任何控件都将不可见 这里有一些基本代码可以帮助您入门,但我从未在带有边框的表单上使用过它,因此边框功能可能会出现问题。最可能的情况是,您必须创建包含窗口边框的位图,并将该部分的alpha设置为255 procedure PremultiplyBitmap(Bitmap: TBitmap); var Row, Col: Integer;
这是可能的,但您在此类表单上放置的任何控件都将不可见 这里有一些基本代码可以帮助您入门,但我从未在带有边框的表单上使用过它,因此边框功能可能会出现问题。最可能的情况是,您必须创建包含窗口边框的位图,并将该部分的alpha设置为255
procedure PremultiplyBitmap(Bitmap: TBitmap);
var
Row, Col: Integer;
p: PRGBQuad;
begin
Bitmap.AlphaFormat := afPremultiplied;
for Row := 0 to Bitmap.Height - 1 do
begin
Col := Bitmap.Width;
p := Bitmap.ScanLine[Row];
while (Col > 0) do
begin
p.rgbBlue := p.rgbReserved * p.rgbBlue div 255;
p.rgbGreen := p.rgbReserved * p.rgbGreen div 255;
p.rgbRed := p.rgbReserved * p.rgbRed div 255;
inc(p);
dec(Col);
end;
end;
end;
procedure PremultiplyBitmapAlpha(Bitmap: TBitmap; Alpha: byte);
var
Row, Col: Integer;
p: PRGBQuad;
begin
Bitmap.AlphaFormat := afPremultiplied;
for Row := 0 to Bitmap.Height - 1 do
begin
Col := Bitmap.Width;
p := Bitmap.ScanLine[Row];
while (Col > 0) do
begin
p.rgbReserved := Alpha;
p.rgbBlue := p.rgbReserved * p.rgbBlue div 255;
p.rgbGreen := p.rgbReserved * p.rgbGreen div 255;
p.rgbRed := p.rgbReserved * p.rgbRed div 255;
inc(p);
dec(Col);
end;
end;
end;
procedure BlendForm(Form: TCustomForm; Bmp: TBitmap);
var
BitmapPos: TPoint;
BitmapSize: TSize;
BlendFunction: TBlendFunction;
begin
BitmapPos := Point(0, 0);
BitmapSize.cx := Bmp.Width;
BitmapSize.cy := Bmp.Height;
BlendFunction.BlendOp := AC_SRC_OVER;
BlendFunction.BlendFlags := 0;
BlendFunction.SourceConstantAlpha := 255;
BlendFunction.AlphaFormat := AC_SRC_ALPHA;
UpdateLayeredWindow(Form.Handle, 0, nil, @BitmapSize, Bmp.Canvas.Handle, @BitmapPos, 0, @BlendFunction, ULW_ALPHA);
end;
procedure TForm1.CreateWnd;
var
ExStyle: DWORD;
begin
inherited;
ExStyle := GetWindowLong(Handle, GWL_EXSTYLE);
if (ExStyle and WS_EX_LAYERED = 0) then
SetWindowLong(Handle, GWL_EXSTYLE, ExStyle or WS_EX_LAYERED);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
Bmp: TBitmap;
begin
Bmp := TBitmap.Create;
try
Bmp.PixelFormat := pf32bit;
Bmp.Width := ClientWidth;
Bmp.Height := ClientHeight;
PremultiplyBitmapAlpha(Bmp, 200);
BlendForm(Form1, Bmp);
finally
Bmp.Free;
end;
end;
使用的位图必须是32位位图。如果要将整个位图与某个alpha值混合,可以使用PremultiplyBitmapAlpha
过程,如果位图具有alpha通道,则可以使用PremultiplyBitmap
过程
为了提高速度,您可以使用如下预乘字节表:
var
PreMult: array[byte, byte] of byte;
procedure InitializePreMult;
var
Row, Col: Integer;
begin
// precalculate all possible values of a*b
for Row := 0 to 255 do
for Col := Row to 255 do
PreMult[Row, Col] := Row*Col div 255;
end;
然后,PremultiplyBitmap
过程将使用该查找表:
procedure PremultiplyBitmap(Bitmap: TBitmap);
var
Row, Col: integer;
p: PRGBQuad;
begin
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;
@SirRufo我怎么做?很复杂。您希望表单部分透明-即标题栏为实心,其余为半透明。要做到这一点,请使用UpdateLayeredWindow(并使用WS_EX_LAYERED样式创建表单-谷歌获取所有这些信息)。@NGLN这张图片是从您的代码中创建的吗?它是由两个单独的屏幕截图创建的。@NGLN您是指两个单独的表单吗?