Пример #1
0
        /// <summary>
        /// Renders a bitmap to a DIB bitmap in HGLOBAL format. It is neccessary that the provided bitmap has a pixel format of PixelFormat.Format24bppRgb.
        /// </summary>
        /// <param name="bitmap">The provided bitmap. Must have PixelFormat.Format24bppRgb.</param>
        /// <returns>HGLOBAL pointer to the DIB bitmap.</returns>
        public static IntPtr RenderDIBBitmapToHGLOBAL(Bitmap bitmap)
        {
            if (null == bitmap)
            {
                throw new ArgumentNullException("bitmap");
            }
            if (bitmap.PixelFormat != PixelFormat.Format24bppRgb)
            {
                throw new ArgumentException(string.Format("bitmap must have PixelFormat.Format24bppRgb, but it has {0}", bitmap.PixelFormat));
            }

            var bmpStream = new System.IO.MemoryStream();

            // ImageFormat.MemoryBmp work (will save to PNG!).  Therefore use BMP and strip header.
            bitmap.Save(bmpStream, ImageFormat.Bmp);
            byte[] bmpBytes = bmpStream.ToArray();

            int    offset = Marshal.SizeOf(typeof(BITMAPFILEHEADER));
            IntPtr hdib   = Kernel32Func.GlobalAlloc(GlobalAllocFlags.GHND, (int)(bmpStream.Length - offset));

            if (!(hdib != IntPtr.Zero))
            {
                throw new InvalidOperationException("GlobalAlloc operation was not successful");
            }

            IntPtr buf = Kernel32Func.GlobalLock(hdib);

            Marshal.Copy(bmpBytes, offset, buf, (int)bmpStream.Length - offset);
            Kernel32Func.GlobalUnlock(hdib);

            return(hdib);
        }
Пример #2
0
        public static IntPtr RenderLinkedObjectDescriptor(TYMED tymed)
        {
            ComDebug.ReportInfo("GraphDocumentDataObject.RenderLinkedObjectDescriptor");

            // Brockschmidt, Inside Ole 2nd ed. page 991
            if (!(tymed == TYMED.TYMED_HGLOBAL))
            {
                throw new ArgumentException(nameof(tymed) + " is not TYMED_HGLOBAL");
            }
            // Fill in the basic information.
            var od = new OBJECTDESCRIPTOR
            {
                // According to the documentation this is used just to find an icon.
                clsid        = typeof(GraphDocumentLinkedComObject).GUID,
                dwDrawAspect = DVASPECT.DVASPECT_CONTENT,
                sizelcx      = 0, // zero in imitation of Word/Excel, but could be box.Extent.cx;
                sizelcy      = 0, // zero in imitation of Word/Excel, but could be box.Extent.cy;
                pointlx      = 0,
                pointly      = 0
            };

            od.dwStatus = MiscStatus((int)od.dwDrawAspect);

            // Descriptive strings to tack on after the struct.
            string name        = GraphDocumentLinkedComObject.USER_TYPE;
            int    name_size   = (name.Length + 1) * sizeof(char);
            string source      = "Altaxo";
            int    source_size = (source.Length + 1) * sizeof(char);
            int    od_size     = Marshal.SizeOf(typeof(OBJECTDESCRIPTOR));

            od.dwFullUserTypeName = od_size;
            od.dwSrcOfCopy        = od_size + name_size;
            int full_size = od_size + name_size + source_size;

            od.cbSize = full_size;

            // To avoid 'unsafe', we will arrange the strings in a byte array.
            byte[]   strings = new byte[full_size];
            Encoding unicode = Encoding.Unicode;

            Array.Copy(unicode.GetBytes(name), 0, strings, od.dwFullUserTypeName, name.Length * sizeof(char));
            Array.Copy(unicode.GetBytes(source), 0, strings, od.dwSrcOfCopy, source.Length * sizeof(char));

            // Combine the strings and the struct into a single block of mem.
            IntPtr hod = Kernel32Func.GlobalAlloc(GlobalAllocFlags.GHND, full_size);

            if (!(hod != IntPtr.Zero))
            {
                throw new InvalidOperationException("GlobalAlloc operation was not successful");
            }
            IntPtr buf = Kernel32Func.GlobalLock(hod);

            Marshal.Copy(strings, 0, buf, full_size);
            Marshal.StructureToPtr(od, buf, false);

            Kernel32Func.GlobalUnlock(hod);
            return(hod);
        }
Пример #3
0
        /// <summary>
        /// Renders a bitmap to a DIBV5 bitmap in HGLOBAL format. It is neccessary that the provided bitmap has a pixel format of PixelFormat.Format32bppRgb.
        /// </summary>
        /// <param name="bm">The provided bitmap. Must have PixelFormat.Format24bppRgb.</param>
        /// <returns>HGLOBAL pointer to the DIB bitmap.</returns>
        /// <remarks>
        /// See <see href="https://groups.google.com/forum/#!msg/microsoft.public.dotnet.framework.drawing/0sSPCrzf8yE/WNEIU324YtwJ"/> for the original source code and the discussion./>
        /// </remarks>
        public static IntPtr RenderDIBV5BitmapToHGLOBAL(Bitmap bm)
        {
            BitmapData bmData      = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, bm.PixelFormat);
            int        bufferLen   = (Marshal.SizeOf(typeof(BITMAPV5HEADER)) + bmData.Height * bmData.Stride);
            IntPtr     hMem        = Kernel32Func.GlobalAlloc(GlobalAllocFlags.GHND, bufferLen);
            IntPtr     packedDIBV5 = Kernel32Func.GlobalLock(hMem);
            var        bmi         = (BITMAPV5HEADER)Marshal.PtrToStructure(packedDIBV5, typeof(BITMAPV5HEADER));

            bmi.bV5Size     = (uint)Marshal.SizeOf(typeof(BITMAPV5HEADER));
            bmi.bV5Width    = bmData.Width;
            bmi.bV5Height   = -bmData.Height; // Top-down bitmap requires negative height
            bmi.bV5BitCount = 32;
            bmi.bV5Planes   = 1;

            bmi.bV5Compression = (uint)BiCompression.BI_RGB;

            bmi.bV5XPelsPerMeter = (int)(bm.HorizontalResolution * (10000 / 254.0));
            bmi.bV5YPelsPerMeter = (int)(bm.VerticalResolution * (10000 / 254.0));
            bmi.bV5ClrUsed       = 0;
            bmi.bV5ClrImportant  = 0;
            bmi.bV5BlueMask      = 0x000000FF;
            bmi.bV5GreenMask     = 0x0000FF00;
            bmi.bV5RedMask       = 0x00FF0000;
            bmi.bV5AlphaMask     = 0xFF000000;
            bmi.bV5CSType        = (uint)LcsCsType.LCS_WINDOWS_COLOR_SPACE;
            bmi.bV5GammaBlue     = 0;
            bmi.bV5GammaGreen    = 0;
            bmi.bV5GammaRed      = 0;
            bmi.bV5ProfileData   = 0;
            bmi.bV5ProfileSize   = 0;
            bmi.bV5Reserved      = 0;
            bmi.bV5Intent        = (uint)LcsIntent.LCS_GM_IMAGES;
            bmi.bV5SizeImage     = (uint)(bmData.Height * bmData.Stride);
            bmi.bV5Endpoints.ciexyzBlue.ciexyzX  = bmi.bV5Endpoints.ciexyzBlue.ciexyzY = bmi.bV5Endpoints.ciexyzBlue.ciexyzZ = 0;
            bmi.bV5Endpoints.ciexyzGreen.ciexyzX = bmi.bV5Endpoints.ciexyzGreen.ciexyzY = bmi.bV5Endpoints.ciexyzGreen.ciexyzZ = 0;
            bmi.bV5Endpoints.ciexyzRed.ciexyzX   = bmi.bV5Endpoints.ciexyzRed.ciexyzY = bmi.bV5Endpoints.ciexyzRed.ciexyzZ = 0;
            Marshal.StructureToPtr(bmi, packedDIBV5, false);

            int offsetBits = (int)bmi.bV5Size;
            var bits       = IntPtr.Add(packedDIBV5, offsetBits);

            Kernel32Func.CopyMemory(bits, bmData.Scan0, (uint)(bmData.Height * bmData.Stride));

            bm.UnlockBits(bmData);

            Kernel32Func.GlobalUnlock(hMem);

            return(hMem);
        }
Пример #4
0
        /// <summary>
        /// Converts an enhanced metafile to a windows metafile picture (CF_MFPICT). Please note that the provided enhanced metafile should neither contain
        /// transparancies nor splines. Thus it is best if the provided enhanced metafile contains only an embedded bitmap in 24bppRGB format.
        /// </summary>
        /// <param name="hEmf">The handle to the enhanced metafile.</param>
        /// <param name="docSizeX">The document size x in points.</param>
        /// <param name="docSizeY">The document size y in points.</param>
        /// <returns>Handle to a windows meta file picture (CF_MFPICT).</returns>
        public static IntPtr ConvertEnhancedMetafileToWindowsMetafilePict(IntPtr hEmf, double docSizeX, double docSizeY)
        {
            byte[] buffer = ConvertEnhancedMetafileToWindowsMetafileBytes(hEmf);

            // Get a handle to the converted metafile.
            IntPtr hmf = Gdi32Func.SetMetaFileBitsEx((uint)buffer.Length, buffer);

            // Convert the Metafile to a METAFILEPICT.
            IntPtr hMem = Kernel32Func.GlobalAlloc(GlobalAllocFlags.GHND, Marshal.SizeOf(typeof(METAFILEPICT)));
            var    mfp  = new METAFILEPICT()
            {
                mm   = MappingMode.MM_ANISOTROPIC,
                xExt = PointToHimetric(docSizeX),
                yExt = PointToHimetric(docSizeY),
                hMF  = hmf
            };

            Marshal.StructureToPtr(mfp, Kernel32Func.GlobalLock(hMem), false);
            Kernel32Func.GlobalUnlock(hMem);

            return(hMem);
        }