Repository: AvaloniaUI/Avalonia
File: src/Windows/Avalonia.Win32/OleDataObjectHelper.cs (C#)

Code before:

                    IntPtr hdc = IntPtr.Zero, compatDc = IntPtr.Zero, hbitmap = IntPtr.Zero;
                    try
                    {
                        hdc = GetDC(IntPtr.Zero);
                        if (hdc == IntPtr.Zero)
                            return DV_E_FORMATETC;

                        compatDc = CreateCompatibleDC(hdc);
                        if (compatDc == IntPtr.Zero)
                            return DV_E_FORMATETC;

                        hbitmap = CreateCompatibleBitmap(compatDc, pixelSize.Width, pixelSize.Height);
                        if (hbitmap == IntPtr.Zero)
                            return DV_E_FORMATETC;

                        SelectObject(compatDc, hbitmap);

                        var bitmapInfoHeader = new BITMAPINFOHEADER()
                        {
                            biWidth = pixelSize.Width,
                            biHeight = pixelSize.Height,
                            biPlanes = 1,
                            biBitCount = (ushort)(bitmap.Format?.BitsPerPixel ?? 0),
                            biCompression = 0,
                            biSizeImage = (uint)(pixelSize.Width * 4 * Math.Abs(pixelSize.Height))
                        };

                        bitmapInfoHeader.Init();

                        var ret = SetDIBits(compatDc, hbitmap, 0, (uint)pixelSize.Height, (IntPtr)bytes, ref bitmapInfoHeader, 0);

                        SelectObject(compatDc, IntPtr.Zero);

                        hGlobalBitmap = hbitmap;

                        return (uint)HRESULT.S_OK;

                    }
                    finally
                    {
                        if (compatDc != IntPtr.Zero)
                            ReleaseDC(IntPtr.Zero, compatDc);

                        if (hdc != IntPtr.Zero)
                            ReleaseDC(IntPtr.Zero, hdc);
                    }
                }
            }
        }


Review comment (suggestion):
You are assuming pixel is 4 bytes here but use any BitsPerPixel value you get from the bitmap. These should be made to match (and match the reality). Some of the formats, and especially the ones with transparency cannot be supported using BITMAPINFOHEADER, you need V5 header. The main benefit of using HBITMAP is that it can support more pixel formats than CF_DIB.

Code after:
            return DV_E_FORMATETC;
        }

        if (format is DataFormat<string> stringFormat)
        {
            return dataTransfer.TryGetValue(stringFormat) is { } stringValue ?
                WriteStringToHGlobal(ref hGlobal, stringValue) :
                DV_E_FORMATETC;
        }

        if (format is DataFormat<byte[]> bytesFormat)
        {
            return dataTransfer.TryGetValue(bytesFormat) is { } bytes ?
                WriteBytesToHGlobal(ref hGlobal, bytes.AsSpan()) :
                DV_E_FORMATETC;
        }

        Logger.TryGet(LogEventLevel.Warning, LogArea.Win32Platform)
            ?.Log(null, "Unsupported data format {Format}", format);

        return DV_E_FORMATETC;
    }

    private static uint GetAlphaMask(Bitmap? bitmap)
    {
        return bitmap?.Format?.FormatEnum switch
        {
            PixelFormatEnum.Rgba8888 => 0xff000000,
            PixelFormatEnum.Bgra8888 => 0xff000000,
            PixelFormatEnum.Rgb565 => 0,
            _ => throw new NotSupportedException()
        };
    }

    private static uint GetGreenMask(Bitmap? bitmap)
    {
        return bitmap?.Format?.FormatEnum switch
        {
            PixelFormatEnum.Rgba8888 => 0x0000ff00,
            PixelFormatEnum.Bgra8888 => 0x0000ff00,
            PixelFormatEnum.Rgb565 => 0b0000011111100000,
            _ => throw new NotSupportedException()
        };
    }

    private static uint GetBlueMask(Bitmap? bitmap)
    {
        return bitmap?.Format?.FormatEnum switch
        {
            PixelFormatEnum.Rgba8888 => 0x00ff0000,
            PixelFormatEnum.Bgra8888 => 0x000000ff,