I want to use partially transparent images in drag/drop operations. This is all set up and works fine, but the actual transformation to transparency has a weird side effect.
GDI+ has a number of problems related to alpha blending when doing interop with GDI (and Win32). In this case, the call to bmp.GetHbitmap() will blend your image with a black background. An article on CodeProject gives more detail on the problem, and a solution that was used for adding images to an image list.
You should be able to use similar code to get the HBITMAP to use for the mask:
[DllImport("kernel32.dll")]
public static extern bool RtlMoveMemory(IntPtr dest, IntPtr source, int dwcount);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateDIBSection(IntPtr hdc, [In, MarshalAs(UnmanagedType.LPStruct)]BITMAPINFO pbmi, uint iUsage, out IntPtr ppvBits, IntPtr hSection, uint dwOffset);
public static IntPtr GetBlendedHBitmap(Bitmap bitmap)
{
BITMAPINFO bitmapInfo = new BITMAPINFO();
bitmapInfo.biSize = 40;
bitmapInfo.biBitCount = 32;
bitmapInfo.biPlanes = 1;
bitmapInfo.biWidth = bitmap.Width;
bitmapInfo.biHeight = -bitmap.Height;
IntPtr pixelData;
IntPtr hBitmap = CreateDIBSection(
IntPtr.Zero, bitmapInfo, 0, out pixelData, IntPtr.Zero, 0);
Rectangle bounds = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData bitmapData = bitmap.LockBits(
bounds, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb );
RtlMoveMemory(
pixelData, bitmapData.Scan0, bitmap.Height * bitmapData.Stride);
bitmap.UnlockBits(bitmapData);
return hBitmap;
}