Windows Forms: Making a cursor bitmap partially transparent

前端 未结 5 1997
一向
一向 2020-12-16 23:10

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.

5条回答
  •  一向
    一向 (楼主)
    2020-12-16 23:37

    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;
    }
    

提交回复
热议问题