예제 #1
0
            private void CreateStorage()
            {
                Debug.Assert(storage == null, "but we already have a storage!!!");
                IntPtr hglobal = IntPtr.Zero;

                if (buffer != null)
                {
                    hglobal = Kernel32.GlobalAlloc(Kernel32.GMEM.MOVEABLE, (uint)length);
                    IntPtr pointer = Kernel32.GlobalLock(hglobal);
                    try
                    {
                        if (pointer != IntPtr.Zero)
                        {
                            Marshal.Copy(buffer, 0, pointer, length);
                        }
                    }
                    finally
                    {
                        Kernel32.GlobalUnlock(hglobal);
                    }
                }

                try
                {
                    iLockBytes = Ole32.CreateILockBytesOnHGlobal(hglobal, BOOL.TRUE);
                    if (buffer == null)
                    {
                        storage = Ole32.StgCreateDocfileOnILockBytes(
                            iLockBytes,
                            Ole32.STGM.CREATE | Ole32.STGM.READWRITE | Ole32.STGM.SHARE_EXCLUSIVE,
                            0);
                    }
                    else
                    {
                        storage = Ole32.StgOpenStorageOnILockBytes(
                            iLockBytes,
                            null,
                            Ole32.STGM.READWRITE | Ole32.STGM.SHARE_EXCLUSIVE,
                            IntPtr.Zero,
                            0);
                    }
                }
                catch (Exception)
                {
                    if (iLockBytes == null && hglobal != IntPtr.Zero)
                    {
                        Kernel32.GlobalFree(hglobal);
                    }
                    else
                    {
                        iLockBytes = null;
                    }

                    storage = null;
                }
            }
예제 #2
0
            public HRESULT GetNewStorage(out Ole32.IStorage storage)
            {
                Debug.WriteLineIf(RichTextDebug.TraceVerbose, "IRichTextBoxOleCallback::GetNewStorage");

                WinFormsComWrappers.LockBytesWrapper pLockBytes = Ole32.CreateILockBytesOnHGlobal(IntPtr.Zero, BOOL.TRUE);

                storage = Ole32.StgCreateDocfileOnILockBytes(
                    pLockBytes,
                    Ole32.STGM.SHARE_EXCLUSIVE | Ole32.STGM.CREATE | Ole32.STGM.READWRITE);

                Debug.Assert(storage is not null, "storage is NULL!");

                return(HRESULT.S_OK);
            }
            public HRESULT GetNewStorage(out Ole32.IStorage storage)
            {
                Debug.WriteLineIf(RichTextDbg.TraceVerbose, "IRichTextBoxOleCallback::GetNewStorage");

                Ole32.ILockBytes pLockBytes = Ole32.CreateILockBytesOnHGlobal(IntPtr.Zero, true);
                Debug.Assert(pLockBytes != null, "pLockBytes is NULL!");

                storage = Ole32.StgCreateDocfileOnILockBytes(
                    pLockBytes,
                    Ole32.STGM.STGM_SHARE_EXCLUSIVE | Ole32.STGM.STGM_CREATE | Ole32.STGM.STGM_READWRITE,
                    0);
                Debug.Assert(storage != null, "storage is NULL!");

                return(HRESULT.S_OK);
            }
예제 #4
0
            public HRESULT GetNewStorage(out Ole32.IStorage storage)
            {
                Debug.WriteLineIf(RichTextDbg.TraceVerbose, "IRichEditOleCallback::GetNewStorage");
                if (!owner.AllowOleObjects)
                {
                    storage = null;
                    return(HRESULT.E_FAIL);
                }

                Ole32.ILockBytes pLockBytes = Ole32.CreateILockBytesOnHGlobal(IntPtr.Zero, BOOL.TRUE);
                Debug.Assert(pLockBytes is not null, "pLockBytes is NULL!");

                storage = Ole32.StgCreateDocfileOnILockBytes(
                    pLockBytes,
                    Ole32.STGM.SHARE_EXCLUSIVE | Ole32.STGM.CREATE | Ole32.STGM.READWRITE,
                    0);
                Debug.Assert(storage is not null, "storage is NULL!");

                return(HRESULT.S_OK);
            }
예제 #5
0
        /// <summary>
        /// Retrieves the data associated with the specified data format at the specified index.
        /// </summary>
        /// <param name="Format">The format of the data to retrieve. See <see cref="T:System.Windows.DataFormats"></see> for predefined formats.</param>
        /// <param name="Index">The index of the data to retrieve.</param>
        /// <returns>
        /// A <see cref="MemoryStream"/> containing the raw data for the specified data format at the specified index.
        /// </returns>
        private MemoryStream GetContentData(string Format, int Index)
        {
            //create a FORMATETC struct to request the data with
            FORMATETC Formatetc = new FORMATETC
            {
                cfFormat = (short)DataFormats.GetFormat(Format).Id,
                dwAspect = DVASPECT.DVASPECT_CONTENT,
                lindex   = Index,
                ptd      = new IntPtr(0),
                tymed    = TYMED.TYMED_ISTREAM | TYMED.TYMED_ISTORAGE | TYMED.TYMED_HGLOBAL
            };

            //using the Com IDataObject interface get the data using the defined FORMATETC
            comUnderlyingDataObject.GetData(ref Formatetc, out STGMEDIUM Medium);

            //retrieve the data depending on the returned store type
            switch (Medium.tymed)
            {
            case TYMED.TYMED_ISTORAGE:
            {
                //to handle a IStorage it needs to be written into a second unmanaged
                //memory mapped storage and then the data can be read from memory into
                //a managed byte and returned as a MemoryStream

                try
                {
                    //marshal the returned pointer to a IStorage object
                    Ole32.IStorage IStorageObject = (Ole32.IStorage)Marshal.GetObjectForIUnknown(Medium.unionmember);

                    try
                    {
                        //create a ILockBytes (unmanaged byte array) and then create a IStorage using the byte array as a backing store
                        Ole32.CreateILockBytesOnHGlobal(IntPtr.Zero, true, out Ole32.ILockBytes LockBytes);
                        Ole32.StgCreateDocfileOnILockBytes(LockBytes, STGM.STGM_READWRITE | STGM.STGM_SHARE_EXCLUSIVE | STGM.STGM_CREATE, ppstgOpen: out Ole32.IStorage IStorageObjectCopy);

                        try
                        {
                            //copy the returned IStorage into the new IStorage
                            IStorageObject.CopyTo(snbExclude: IntPtr.Zero, pstgDest: IStorageObjectCopy);
                            LockBytes.Flush();
                            IStorageObjectCopy.Commit(Ole32.STGC.STGC_DEFAULT);

                            //get the STATSTG of the LockBytes to determine how many bytes were written to it
                            LockBytes.Stat(out STATSTG LockBytesStat, Ole32.STATFLAG.STATFLAG_NONAME);

                            int CbSize = Convert.ToInt32(LockBytesStat.cbSize);

                            IntPtr LockBytesContentPtr = Marshal.AllocHGlobal(CbSize);

                            try
                            {
                                LockBytes.ReadAt(0, LockBytesContentPtr, Convert.ToUInt32(LockBytesStat.cbSize), out _);

                                byte[] LockBytesContent = new byte[CbSize];

                                Marshal.Copy(LockBytesContentPtr, LockBytesContent, 0, LockBytesContent.Length);

                                return(new MemoryStream(LockBytesContent));
                            }
                            finally
                            {
                                Marshal.FreeHGlobal(LockBytesContentPtr);
                            }
                        }
                        finally
                        {
                            Marshal.ReleaseComObject(IStorageObjectCopy);
                            Marshal.ReleaseComObject(LockBytes);
                        }
                    }
                    finally
                    {
                        Marshal.ReleaseComObject(IStorageObject);
                    }
                }
                finally
                {
                    Marshal.Release(Medium.unionmember);
                }
            }

            case TYMED.TYMED_ISTREAM:
            {
                //to handle a IStream it needs to be read into a managed byte and
                //returned as a MemoryStream

                IStream IStreamObject = (IStream)Marshal.GetObjectForIUnknown(Medium.unionmember);

                try
                {
                    //get the STATSTG of the IStream to determine how many bytes are in it
                    IStreamObject.Stat(out STATSTG iStreamStat, 0);

                    byte[] IStreamContent = new byte[(Convert.ToInt32(iStreamStat.cbSize))];

                    IStreamObject.Read(IStreamContent, IStreamContent.Length, IntPtr.Zero);

                    return(new MemoryStream(IStreamContent));
                }
                finally
                {
                    Marshal.Release(Medium.unionmember);
                    Marshal.ReleaseComObject(IStreamObject);
                }
            }

            case TYMED.TYMED_HGLOBAL:
            {
                //to handle a HGlobal the exisitng "GetDataFromHGLOBAL" method is invoked via
                //reflection

                try
                {
                    return((MemoryStream)getDataFromHGLOBALMethod.Invoke(oleUnderlyingDataObject, new object[] { DataFormats.GetFormat(Formatetc.cfFormat).Name, Medium.unionmember }));
                }
                finally
                {
                    Marshal.Release(Medium.unionmember);
                }
            }

            default:
            {
                return(null);
            }
            }
        }