Example #1
0
        /// <summary>
        /// Get the next celt entries from the enumeration
        /// </summary>
        /// <param name="celt">entries to fetch</param>
        /// <param name="rgelt">array to fetch into (allocated by caller)</param>
        /// <param name="pceltFetched">number of entries fetched</param>
        /// <returns>S_OK if celt entries are supplied, otherwise S_FALSE</returns>
        public int Next(uint celt, FORMATETC[] rgelt, IntPtr pceltFetched)
        {
            // see how many of the requested items we can serve
            int itemsRequested = Convert.ToInt32(celt);
            int itemsToReturn  = Math.Min(itemsRequested, oleDataEntries.Count - (currentItem + 1));

            // copy the format structures into the caller's array of structures
            for (int i = 0; i < itemsToReturn; i++)
            {
                OleDataEntry dataEntry = (OleDataEntry)oleDataEntries[++currentItem];
                rgelt[i] = dataEntry.format;
            }

            // update the fetch parameter if requested
            if (pceltFetched != IntPtr.Zero)
            {
                Marshal.WriteInt32(pceltFetched, itemsToReturn);
            }

            // return the correct status code depending upon whether we
            // returned all of the items requested
            if (itemsToReturn == itemsRequested)
            {
                return(HRESULT.S_OK);
            }
            else
            {
                return(HRESULT.S_FALSE);
            }
        }
Example #2
0
        /// <summary>
        /// Provides the source data object with data described by a FORMATETC
        /// structure and an STGMEDIUM structure
        /// </summary>
        /// <param name="pFormatEtc">Pointer to the FORMATETC structure defining the
        /// format used by the data object when interpreting the data contained in the
        /// storage medium</param>
        /// <param name="pMedium">Pointer to the STGMEDIUM structure defining the storage
        /// medium in which the data is being passed</param>
        /// <param name="fRelease">If TRUE, the data object called, which implements
        /// IDataObject::SetData, owns the storage medium after the call returns. This
        /// means it must free the medium after it has been used by calling the
        /// ReleaseStgMedium function. If FALSE, the caller retains ownership of the
        /// storage medium and the data object called uses the storage medium for the
        /// duration of the call only</param>
        public int SetData(ref FORMATETC pFormatEtc, ref STGMEDIUM pMedium, bool fRelease)
        {
            // check and see if we have an existing format of this type
            int dataFormatIndex;
            int result = FindDataFormat(ref pFormatEtc, out dataFormatIndex);

            // if we have an existing format of this type then free it and
            // remove it from the list
            if (result == HRESULT.S_OK)
            {
                OleDataEntry oleDataEntry = (OleDataEntry)oleDataEntries[dataFormatIndex];
                Ole32.ReleaseStgMedium(ref oleDataEntry.stgm);
                oleDataEntries.RemoveAt(dataFormatIndex);
            }

            // create an entry to add to our internal list
            OleDataEntry dataEntry;

            // if the caller is releasing the data that is being set then just
            // copy bit for bit (we are now responsible for freeing the storage)
            if (fRelease)
            {
                dataEntry = new OleDataEntry(pFormatEtc, pMedium);
            }

            // if the caller is not releasing the data object to us then
            // we only get to use it for the duration of the call -- we need
            // to therefore clone the storage so that we have our own
            // copy/reference
            else
            {
                // attempt to clone the storage medium
                STGMEDIUM mediumClone = new STGMEDIUM();
                result = CloneStgMedium(pMedium, ref mediumClone);
                if (result != HRESULT.S_OK)
                {
                    return(result);
                }

                // cloned it, initialize the data entry using the cloned storage
                dataEntry = new OleDataEntry(pFormatEtc, mediumClone);
            }

            // add the entry to our internal list
            oleDataEntries.Add(dataEntry);

            // return OK
            return(HRESULT.S_OK);
        }
Example #3
0
        /// <summary>
        /// Private helper method to find an existing data format
        /// </summary>
        /// <param name="pFormatEtc">format spec</param>
        /// <param name="dataIndex">returned index of data format if we've got it,
        /// -1 if we don't have it</param>
        /// <returns>S_OK if the data format was found, otherwise the appropriate
        /// OLE error code (see QueryGetData for documentation on error codes)</returns>
        private int FindDataFormat(ref FORMATETC pFormatEtc, out int dataIndex)
        {
            // default to data not found
            dataIndex = -1;

            // no support for comparing target devices
            if (pFormatEtc.ptd != IntPtr.Zero)
            {
                return(DV_E.TARGETDEVICE);
            }

            // iterate through our FORMATETC structures to see if one matches
            // this format spec
            for (int i = 0; i < oleDataEntries.Count; i++)
            {
                // get the data entry
                OleDataEntry dataEntry = (OleDataEntry)oleDataEntries[i];

                // check for matching format spec
                if ((dataEntry.format.cfFormat == pFormatEtc.cfFormat) &&
                    (dataEntry.format.dwAspect == pFormatEtc.dwAspect) &&
                    (dataEntry.format.lindex == pFormatEtc.lindex))
                {
                    // check for matching data type
                    if ((dataEntry.format.tymed & pFormatEtc.tymed) > 0)
                    {
                        dataIndex = i;
                        return(HRESULT.S_OK);
                    }
                    else
                    {
                        return(DV_E.TYMED);
                    }
                }
            }

            // no matching format found
            return(DV_E.FORMATETC);
        }
Example #4
0
        /// <summary>
        /// Renders the data described in a FORMATETC structure and transfers it
        /// through the STGMEDIUM structure.
        /// </summary>
        /// <param name="pFormatEtc">Pointer to the FORMATETC structure that defines
        /// the format, medium, and target device to use when passing the data. It is
        /// possible to specify more than one medium by using the Boolean OR operator,
        /// allowing the method to choose the best medium among those specified</param>
        /// <param name="pMedium">Pointer to the STGMEDIUM structure that indicates
        /// the storage medium containing the returned data through its tymed member,
        /// and the responsibility for releasing the medium through the value of its
        /// pUnkForRelease member. If pUnkForRelease is NULL, the receiver of the medium
        /// is responsible for releasing it; otherwise, pUnkForRelease points to the
        /// IUnknown on the appropriate object so its Release method can be called.
        /// The medium must be allocated and filled in by IDataObject::GetData</param>
        public int GetData(ref FORMATETC pFormatEtc, ref STGMEDIUM pMedium)
        {
            // check to see if we have data of the requested type
            int dataFormatIndex;
            int result = FindDataFormat(ref pFormatEtc, out dataFormatIndex);

            // if we do then return a clone of it (returns error code if an
            // error occurs during the clone)
            if (result == HRESULT.S_OK)
            {
                // lookup the entry
                OleDataEntry dataEntry = (OleDataEntry)oleDataEntries[dataFormatIndex];

                // clone the storage and return
                return(CloneStgMedium(dataEntry.stgm, ref pMedium));
            }
            // don't have the data, return the error code passed back to us
            // from FindDataFormat
            else
            {
                return(result);
            }
        }
        /// <summary>
        /// Provides the source data object with data described by a FORMATETC
        /// structure and an STGMEDIUM structure
        /// </summary>
        /// <param name="pFormatEtc">Pointer to the FORMATETC structure defining the
        /// format used by the data object when interpreting the data contained in the
        /// storage medium</param>
        /// <param name="pMedium">Pointer to the STGMEDIUM structure defining the storage
        /// medium in which the data is being passed</param>
        /// <param name="fRelease">If TRUE, the data object called, which implements
        /// IDataObject::SetData, owns the storage medium after the call returns. This
        /// means it must free the medium after it has been used by calling the
        /// ReleaseStgMedium function. If FALSE, the caller retains ownership of the
        /// storage medium and the data object called uses the storage medium for the
        /// duration of the call only</param>
        public int SetData(ref FORMATETC pFormatEtc, ref STGMEDIUM pMedium, bool fRelease)
        {
            // check and see if we have an existing format of this type
            int dataFormatIndex;
            int result = FindDataFormat(ref pFormatEtc, out dataFormatIndex);

            // if we have an existing format of this type then free it and
            // remove it from the list
            if (result == HRESULT.S_OK)
            {
                OleDataEntry oleDataEntry = (OleDataEntry)oleDataEntries[dataFormatIndex];
                Ole32.ReleaseStgMedium(ref oleDataEntry.stgm);
                oleDataEntries.RemoveAt(dataFormatIndex);
            }

            // create an entry to add to our internal list
            OleDataEntry dataEntry;

            // if the caller is releasing the data that is being set then just
            // copy bit for bit (we are now responsible for freeing the storage)
            if (fRelease)
            {
                dataEntry = new OleDataEntry(pFormatEtc, pMedium);
            }

            // if the caller is not releasing the data object to us then
            // we only get to use it for the duration of the call -- we need
            // to therefore clone the storage so that we have our own
            // copy/reference
            else
            {
                // attempt to clone the storage medium
                STGMEDIUM mediumClone = new STGMEDIUM();
                result = CloneStgMedium(pMedium, ref mediumClone);
                if (result != HRESULT.S_OK)
                    return result;

                // cloned it, initialize the data entry using the cloned storage
                dataEntry = new OleDataEntry(pFormatEtc, mediumClone);
            }

            // add the entry to our internal list
            oleDataEntries.Add(dataEntry);

            // return OK
            return HRESULT.S_OK;
        }