/// <summary> /// Construct an icon from the raw image data. /// </summary> /// <returns></returns> /// <remarks></remarks> private Icon _constructIcon() { Icon _constructIconRet = default; if (_hIcon != IntPtr.Zero) { User32.DestroyIcon(_hIcon); _hIcon = IntPtr.Zero; } MemPtr mm = (MemPtr)_image; var bmp = mm.ToStruct <BITMAPINFOHEADER>(); IntPtr hBmp; IntPtr ptr; IntPtr ppBits = new IntPtr(); var lpicon = default(ICONINFO); IntPtr hicon; IntPtr hBmpMask = new IntPtr(); bool hasMask; if (bmp.biHeight == bmp.biWidth * 2) { hasMask = true; bmp.biHeight = (int)(bmp.biHeight / 2d); } else { hasMask = false; } bmp.biSizeImage = (int)(bmp.biWidth * bmp.biHeight * (bmp.biBitCount / 8d)); bmp.biXPelsPerMeter = (int)(24.5d * 1000d); bmp.biYPelsPerMeter = (int)(24.5d * 1000d); bmp.biClrUsed = 0; bmp.biClrImportant = 0; bmp.biPlanes = 1; Marshal.StructureToPtr(bmp, mm.Handle, false); ptr = mm.Handle + bmp.biSize; if (bmp.biSize != 40) { return(null); } hBmp = User32.CreateDIBSection(IntPtr.Zero, mm.Handle, 0U, ref ppBits, IntPtr.Zero, 0); Native.MemCpy(ptr, ppBits, bmp.biSizeImage); if (hasMask) { ptr = ptr + bmp.biSizeImage; bmp.biBitCount = 1; bmp.biSizeImage = 0; Marshal.StructureToPtr(bmp, mm.Handle, false); hBmpMask = User32.CreateDIBSection(IntPtr.Zero, mm.Handle, 0U, ref ppBits, IntPtr.Zero, 0); Native.MemCpy(ptr, ppBits, (long)(Math.Max(bmp.biWidth, 32) * bmp.biHeight / 8d)); } lpicon.fIcon = 1; lpicon.hbmColor = hBmp; lpicon.hbmMask = hBmpMask; hicon = User32.CreateIconIndirect(ref lpicon); NativeShell.DeleteObject(hBmp); if (hasMask) { NativeShell.DeleteObject(hBmpMask); } _constructIconRet = Icon.FromHandle(hicon); _hIcon = hicon; mm.Free(); return(_constructIconRet); }