internal static NativeMethods.IconHandle CreateIconCursor(byte[] colorArray, int width, int height, int xHotspot, int yHotspot, bool isIcon) { NativeMethods.BitmapHandle bitmapHandle = null; NativeMethods.BitmapHandle bitmapHandle2 = null; NativeMethods.IconHandle result; try { NativeMethods.BITMAPINFO bitmapinfo = new NativeMethods.BITMAPINFO(width, -height, 32); bitmapinfo.bmiHeader_biCompression = 0; IntPtr zero = IntPtr.Zero; bitmapHandle = UnsafeNativeMethods.CreateDIBSection(new HandleRef(null, IntPtr.Zero), ref bitmapinfo, 0, ref zero, null, 0); if (bitmapHandle.IsInvalid || zero == IntPtr.Zero) { result = NativeMethods.IconHandle.GetInvalidIcon(); } else { Marshal.Copy(colorArray, 0, zero, colorArray.Length); byte[] array = IconHelper.GenerateMaskArray(width, height, colorArray); Invariant.Assert(array != null); bitmapHandle2 = UnsafeNativeMethods.CreateBitmap(width, height, 1, 1, array); if (bitmapHandle2.IsInvalid) { result = NativeMethods.IconHandle.GetInvalidIcon(); } else { result = UnsafeNativeMethods.CreateIconIndirect(new NativeMethods.ICONINFO { fIcon = isIcon, xHotspot = xHotspot, yHotspot = yHotspot, hbmMask = bitmapHandle2, hbmColor = bitmapHandle }); } } } finally { if (bitmapHandle != null) { bitmapHandle.Dispose(); bitmapHandle = null; } if (bitmapHandle2 != null) { bitmapHandle2.Dispose(); bitmapHandle2 = null; } } return(result); }
// Also used by PenCursorManager // Creates a 32 bit per pixel Icon or cursor. This code is moved from framework\ms\internal\ink\pencursormanager.cs internal static NativeMethods.IconHandle CreateIconCursor( byte[] colorArray, int width, int height, int xHotspot, int yHotspot, bool isIcon) { // 1. We are going to generate a WIN32 color bitmap which represents the color cursor. // 2. Then we need to create a monochrome bitmap which is used as the cursor mask. // 3. At last we create a WIN32 HICON from the above two bitmaps NativeMethods.BitmapHandle colorBitmap = null; NativeMethods.BitmapHandle maskBitmap = null; try { // 1) Create the color bitmap using colorArray // Fill in the header information NativeMethods.BITMAPINFO bi = new NativeMethods.BITMAPINFO( width, // width -height, // A negative value indicates the bitmap is top-down DIB 32 // biBitCount ); bi.bmiHeader_biCompression = NativeMethods.BI_RGB; IntPtr bits = IntPtr.Zero; colorBitmap = MS.Win32.UnsafeNativeMethods.CreateDIBSection( new HandleRef(null, IntPtr.Zero), // A device context. Pass null in if no DIB_PAL_COLORS is used. ref bi, // A BITMAPINFO structure which specifies the dimensions and colors. NativeMethods.DIB_RGB_COLORS, // Specifies the type of data contained in the bmiColors array member of the BITMAPINFO structure ref bits, // An out Pointer to a variable that receives a pointer to the location of the DIB bit values null, // Handle to a file-mapping object that the function will use to create the DIB. This parameter can be null. 0 // dwOffset. This value is ignored if hSection is NULL ); if (colorBitmap.IsInvalid || bits == IntPtr.Zero) { // Note we will release the GDI resources in the finally block. return(NativeMethods.IconHandle.GetInvalidIcon()); } // Copy the color bits to the win32 bitmap Marshal.Copy(colorArray, 0, bits, colorArray.Length); // 2) Now create the mask bitmap which is monochrome byte[] maskArray = GenerateMaskArray(width, height, colorArray); Invariant.Assert(maskArray != null); maskBitmap = UnsafeNativeMethods.CreateBitmap(width, height, 1, 1, maskArray); if (maskBitmap.IsInvalid) { // Note we will release the GDI resources in the finally block. return(NativeMethods.IconHandle.GetInvalidIcon()); } // Now create HICON from two bitmaps. NativeMethods.ICONINFO iconInfo = new NativeMethods.ICONINFO(); iconInfo.fIcon = isIcon; // fIcon == ture means creating an Icon, otherwise Cursor iconInfo.xHotspot = xHotspot; iconInfo.yHotspot = yHotspot; iconInfo.hbmMask = maskBitmap; iconInfo.hbmColor = colorBitmap; return(UnsafeNativeMethods.CreateIconIndirect(iconInfo)); } finally { if (colorBitmap != null) { colorBitmap.Dispose(); colorBitmap = null; } if (maskBitmap != null) { maskBitmap.Dispose(); maskBitmap = null; } } }