예제 #1
0
        /// <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);
        }