问题
According to MS KB entry, there is a quirk in CreateIconIndirect
which recognizes HBITMAP
s been created with BITMAPV5HEADER
passed to CreateDIBSection
(and BGRA channel layout).
However, TBitmap
instances with (PixelFormat = pf32bit) and (AlphaFormat = afDefined)
(behaving as alpha blended for the other purposes) when referred by its Handle
s are not being recognized as valid alpha blended bitmaps for creation of icons or cursors.
Currently, I have to create a full copy of TBitmap using described API calls (see) to make CreateIconIndirect
accept a bitmap handle as alpha blended. How do I overcome this clumsiness?
回答1:
Here is an example:
procedure TForm1.Button1Click(Sender: TObject);
const
crAlpha = TCursor(-25);
var
Bmp: TBitmap;
Px: PRGBQuad;
X, Y: Integer;
BmpMask: TBitmap;
II: TIconInfo;
AlphaCursor: HCURSOR;
begin
Bmp := TBitmap.Create;
Bmp.PixelFormat := pf32bit;
Bmp.Canvas.Brush.Color := clWhite;
Bmp.SetSize(32, 32);
Bmp.Canvas.Font.Style := [fsBold];
Bmp.Canvas.Font.Color := clRed;
Bmp.Canvas.TextOut(1, 10, 'alpha');
for Y := 0 to (Bmp.Height - 1) do
begin
Px := Bmp.ScanLine[Y];
for X := 0 to (Bmp.Width - 1) do begin
if DWORD(Px^) = DWORD(clWhite) then
Px.rgbReserved := $00
else
Px.rgbReserved := $FF;
Inc(Px);
end;
end;
BmpMask := TBitmap.Create;
BmpMask.SetSize(Bmp.Width, Bmp.Height);
II.fIcon := False;
II.xHotspot := 32;
II.yHotspot := 32;
II.hbmMask := BmpMask.Handle;
II.hbmColor := Bmp.Handle;
AlphaCursor := CreateIconIndirect(II);
Win32Check(AlphaCursor <> 0);
BmpMask.Free;
Bmp.AlphaFormat := afDefined; // AlphaBlend below, premultiply channels
Canvas.Draw(0, 0, Bmp); // test draw
Bmp.Free;
Screen.Cursors[crAlpha] := AlphaCursor;
Cursor := crAlpha;
end;
来源:https://stackoverflow.com/questions/13109267/how-can-i-create-alpha-blended-icon-cursor-indirect-from-the-tbitmap-instance