IDataObjectUtils.h

Go to the documentation of this file.
00001 #include <shlobj.h>
00002 
00003 namespace IDataObjectUtils {
00004 
00005         class ReleaseStgMediumScope {
00006         public:
00007                 ReleaseStgMediumScope(STGMEDIUM * medium) : m_medium(medium) {}
00008                 ~ReleaseStgMediumScope() {if (m_medium != NULL) ReleaseStgMedium(m_medium);}
00009         private:
00010                 STGMEDIUM * m_medium;
00011 
00012                 PFC_CLASS_NOT_COPYABLE_EX(ReleaseStgMediumScope)
00013         };
00014 
00015         static const DWORD DataBlockToSTGMEDIUM_SupportedTymeds = TYMED_ISTREAM | TYMED_HGLOBAL;
00016         static const DWORD ExtractDataObjectContent_SupportedTymeds = TYMED_ISTREAM | TYMED_HGLOBAL;
00017 
00018         HRESULT DataBlockToSTGMEDIUM(const void * blockPtr, t_size blockSize, STGMEDIUM * medium, DWORD tymed, bool bHere) throw();
00019 
00020         HGLOBAL HGlobalFromMemblock(const void * ptr,t_size size);
00021 
00022         HRESULT ExtractDataObjectContent(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD aspect, LONG index, pfc::array_t<t_uint8> & out);
00023         HRESULT ExtractDataObjectContent(pfc::com_ptr_t<IDataObject> obj, UINT format, pfc::array_t<t_uint8> & out);
00024 
00025         HRESULT ExtractDataObjectContentTest(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD aspect, LONG index);
00026         HRESULT ExtractDataObjectContentTest(pfc::com_ptr_t<IDataObject> obj, UINT format);
00027 
00028         HRESULT ExtractDataObjectString(pfc::com_ptr_t<IDataObject> obj, pfc::string_base & out);
00029         HRESULT SetDataObjectString(pfc::com_ptr_t<IDataObject> obj, const char * str);
00030 
00031         HRESULT SetDataObjectContent(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD aspect, LONG index, const void * data, t_size dataSize);
00032 
00033         HRESULT STGMEDIUMToDataBlock(const STGMEDIUM & med, pfc::array_t<t_uint8> & out);
00034 
00035         HRESULT ExtractDataObjectDWORD(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD & val);
00036         HRESULT SetDataObjectDWORD(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD val);
00037 
00038         HRESULT PasteSucceeded(pfc::com_ptr_t<IDataObject> obj, DWORD effect);
00039 
00040         class comparator_FORMATETC {
00041         public:
00042                 static int compare(const FORMATETC & v1, const FORMATETC & v2) {
00043                         int val;
00044                         val = pfc::compare_t(v1.cfFormat,v2.cfFormat); if (val != 0) return val;
00045                         val = pfc::compare_t(v1.dwAspect,v2.dwAspect); if (val != 0) return val;
00046                         val = pfc::compare_t(v1.lindex,  v2.lindex  ); if (val != 0) return val;
00047                         return 0;
00048                 }
00049         };
00050 
00051         class CDataObjectBase : public IDataObject {
00052         public:
00053                 COM_QI_BEGIN()
00054                         COM_QI_ENTRY(IUnknown)
00055                         COM_QI_ENTRY(IDataObject)
00056                 COM_QI_END()
00057 
00058                 HRESULT STDMETHODCALLTYPE GetData(FORMATETC * formatetc, STGMEDIUM * medium) {
00059                         return GetData_internal(formatetc,medium,false);
00060                 }
00061                 
00062                 HRESULT STDMETHODCALLTYPE GetDataHere(FORMATETC * formatetc, STGMEDIUM * medium) {
00063                         return GetData_internal(formatetc,medium,true);
00064                 }
00065 
00066                 HRESULT STDMETHODCALLTYPE QueryGetData(FORMATETC * formatetc) {
00067                         if (formatetc == NULL) return E_INVALIDARG;
00068                         
00069                         if ((DataBlockToSTGMEDIUM_SupportedTymeds & formatetc->tymed) == 0) return DV_E_TYMED;
00070 
00071                         try {
00072                                 return RenderDataTest(formatetc->cfFormat,formatetc->dwAspect,formatetc->lindex);
00073                         } FB2K_COM_CATCH;
00074                 }
00075 
00076 
00077                 HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc(FORMATETC * in, FORMATETC * out) {
00078                         //check this again
00079                         if (in == NULL || out == NULL)
00080                                 return E_INVALIDARG;
00081                         *out = *in;
00082                         return DATA_S_SAMEFORMATETC;
00083                 }
00084 
00085                 HRESULT STDMETHODCALLTYPE EnumFormatEtc(DWORD dwDirection,IEnumFORMATETC ** ppenumFormatetc) {
00086                         if (dwDirection == DATADIR_GET) {
00087                                 if (ppenumFormatetc == NULL) return E_INVALIDARG;
00088                                 return CreateIEnumFORMATETC(ppenumFormatetc);
00089                         } else if (dwDirection == DATADIR_SET) {
00090                                 return E_NOTIMPL;
00091                         } else {
00092                                 return E_INVALIDARG;
00093                         }
00094                 }
00095 
00096                 HRESULT STDMETHODCALLTYPE SetData(FORMATETC * pFormatetc, STGMEDIUM * pmedium, BOOL fRelease) {
00097                         try {
00098                                 ReleaseStgMediumScope relScope(fRelease ? pmedium : NULL);
00099                                 if (pFormatetc == NULL || pmedium == NULL) return E_INVALIDARG;
00100 
00101                                 /*TCHAR buf[256];
00102                                 if (GetClipboardFormatName(pFormatetc->cfFormat,buf,tabsize(buf)) > 0) {
00103                                         buf[tabsize(buf)-1] = 0;
00104                                         OutputDebugString(TEXT("SetData: ")); OutputDebugString(buf); OutputDebugString(TEXT("\n"));
00105                                 } else {
00106                                         OutputDebugString(TEXT("SetData: unknown clipboard format.\n"));
00107                                 }*/
00108 
00109                                 pfc::array_t<t_uint8> temp;
00110                                 HRESULT state = STGMEDIUMToDataBlock(*pmedium,temp);
00111                                 if (FAILED(state)) return state;
00112                                 m_entries.set(*pFormatetc,temp);
00113                                 return S_OK;
00114                         } FB2K_COM_CATCH;
00115                 }
00116                 HRESULT STDMETHODCALLTYPE DAdvise(FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection) {return OLE_E_ADVISENOTSUPPORTED;}
00117                 HRESULT STDMETHODCALLTYPE DUnadvise(DWORD dwConnection) {return OLE_E_ADVISENOTSUPPORTED;}
00118                 HRESULT STDMETHODCALLTYPE EnumDAdvise(IEnumSTATDATA ** ppenumAdvise) {return OLE_E_ADVISENOTSUPPORTED;}
00119         protected:
00120                 virtual HRESULT RenderData(UINT format,DWORD aspect,LONG dataIndex,stream_writer_formatter<> & out) const {
00121                         FORMATETC fmt = {};
00122                         fmt.cfFormat = format; fmt.dwAspect = aspect; fmt.lindex = dataIndex;
00123                         const pfc::array_t<t_uint8> * entry = m_entries.query_ptr(fmt);
00124                         if (entry != NULL) {
00125                                 out.write_raw(entry->get_ptr(), entry->get_size());
00126                                 return S_OK;
00127                         }
00128                         return DV_E_FORMATETC;
00129                 }
00130                 virtual HRESULT RenderDataTest(UINT format,DWORD aspect, LONG dataIndex) const {
00131                         FORMATETC fmt = {};
00132                         fmt.cfFormat = format; fmt.dwAspect = aspect; fmt.lindex = dataIndex;
00133                         if (m_entries.have_item(fmt)) return S_OK;
00134                         return DV_E_FORMATETC;
00135                 }
00136                 typedef pfc::list_base_t<FORMATETC> TFormatList;
00137 
00138                 static void AddFormat(TFormatList & out,UINT code) {
00139                         FORMATETC fmt = {};
00140                         fmt.dwAspect = DVASPECT_CONTENT;
00141                         fmt.lindex = -1;
00142                         fmt.cfFormat = code;
00143                         for(t_size medWalk = 0; medWalk < 32; ++medWalk) {
00144                                 const DWORD med = 1 << medWalk;
00145                                 if ((DataBlockToSTGMEDIUM_SupportedTymeds & med) != 0) {
00146                                         fmt.tymed = med;
00147                                         out.add_item(fmt);
00148                                 }
00149                         }
00150                 }
00151 
00152                 virtual void EnumFormats(TFormatList & out) const {
00153                         pfc::avltree_t<UINT> formats;
00154                         for(t_entries::const_iterator walk = m_entries.first(); walk.is_valid(); ++walk) {
00155                                 formats.add_item( walk->m_key.cfFormat );
00156                         }
00157                         for(pfc::const_iterator<UINT> walk = formats.first(); walk.is_valid(); ++walk) {
00158                                 AddFormat(out, *walk);
00159                         }
00160                 }
00161                 HRESULT CreateIEnumFORMATETC(IEnumFORMATETC ** outptr) const throw() {
00162                         try {
00163                                 pfc::list_t<FORMATETC> out;
00164                                 EnumFormats(out);
00165                                 return SHCreateStdEnumFmtEtc((UINT)out.get_count(), out.get_ptr(), outptr);
00166                         } FB2K_COM_CATCH;
00167                 }
00168         private:
00169                 HRESULT GetData_internal(FORMATETC * formatetc, STGMEDIUM * medium,bool bHere) {
00170                         if (formatetc == NULL || medium == NULL) return E_INVALIDARG;
00171                         
00172                         try {
00173                                 stream_writer_formatter_simple<> out;
00174                                 HRESULT hr = RenderData(formatetc->cfFormat,formatetc->dwAspect,formatetc->lindex,out);
00175                                 if (FAILED(hr)) return hr;
00176                                 return DataBlockToSTGMEDIUM(out.m_buffer.get_ptr(),out.m_buffer.get_size(),medium,formatetc->tymed,bHere);
00177                         } FB2K_COM_CATCH;
00178                 }
00179 
00180                 typedef pfc::map_t<FORMATETC, pfc::array_t<t_uint8>, comparator_FORMATETC> t_entries;
00181                 t_entries m_entries;
00182         };
00183 }

Generated on Thu Aug 28 21:15:31 2008 for foobar2000 SDK by  doxygen 1.5.5