foobar2000 SDK  2015-08-03
IDataObjectUtils.h
Go to the documentation of this file.
1 #ifdef _WIN32
2 #include <shlobj.h>
3 
4 namespace IDataObjectUtils {
5 
7  public:
8  ReleaseStgMediumScope(STGMEDIUM * medium) : m_medium(medium) {}
9  ~ReleaseStgMediumScope() {if (m_medium != NULL) ReleaseStgMedium(m_medium);}
10  private:
11  STGMEDIUM * m_medium;
12 
13  PFC_CLASS_NOT_COPYABLE_EX(ReleaseStgMediumScope)
14  };
15 
16  static const DWORD DataBlockToSTGMEDIUM_SupportedTymeds = TYMED_ISTREAM | TYMED_HGLOBAL;
17  static const DWORD ExtractDataObjectContent_SupportedTymeds = TYMED_ISTREAM | TYMED_HGLOBAL;
18 
19  HRESULT DataBlockToSTGMEDIUM(const void * blockPtr, t_size blockSize, STGMEDIUM * medium, DWORD tymed, bool bHere) throw();
20 
21  HGLOBAL HGlobalFromMemblock(const void * ptr,t_size size);
22 
23  HRESULT ExtractDataObjectContent(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD aspect, LONG index, pfc::array_t<t_uint8> & out);
25 
26  HRESULT ExtractDataObjectContentTest(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD aspect, LONG index);
28 
30  HRESULT SetDataObjectString(pfc::com_ptr_t<IDataObject> obj, const char * str);
31 
32  HRESULT SetDataObjectContent(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD aspect, LONG index, const void * data, t_size dataSize);
33 
34  HRESULT STGMEDIUMToDataBlock(const STGMEDIUM & med, pfc::array_t<t_uint8> & out);
35 
36  HRESULT ExtractDataObjectDWORD(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD & val);
37  HRESULT SetDataObjectDWORD(pfc::com_ptr_t<IDataObject> obj, UINT format, DWORD val);
38 
39  HRESULT PasteSucceeded(pfc::com_ptr_t<IDataObject> obj, DWORD effect);
40 
42  public:
43  static int compare(const FORMATETC & v1, const FORMATETC & v2) {
44  int val;
45  val = pfc::compare_t(v1.cfFormat,v2.cfFormat); if (val != 0) return val;
46  val = pfc::compare_t(v1.dwAspect,v2.dwAspect); if (val != 0) return val;
47  val = pfc::compare_t(v1.lindex, v2.lindex ); if (val != 0) return val;
48  return 0;
49  }
50  };
51 
52  class CDataObjectBase : public IDataObject {
53  public:
54  COM_QI_SIMPLE(IDataObject)
55 
56  HRESULT STDMETHODCALLTYPE GetData(FORMATETC * formatetc, STGMEDIUM * medium) {
57  return GetData_internal(formatetc,medium,false);
58  }
59 
60  HRESULT STDMETHODCALLTYPE GetDataHere(FORMATETC * formatetc, STGMEDIUM * medium) {
61  return GetData_internal(formatetc,medium,true);
62  }
63 
64  HRESULT STDMETHODCALLTYPE QueryGetData(FORMATETC * formatetc) {
65  if (formatetc == NULL) return E_INVALIDARG;
66 
67  if ((DataBlockToSTGMEDIUM_SupportedTymeds & formatetc->tymed) == 0) return DV_E_TYMED;
68 
69  try {
70  return RenderDataTest(formatetc->cfFormat,formatetc->dwAspect,formatetc->lindex);
71  } FB2K_COM_CATCH;
72  }
73 
74 
75  HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc(FORMATETC * in, FORMATETC * out) {
76  //check this again
77  if (in == NULL || out == NULL)
78  return E_INVALIDARG;
79  *out = *in;
80  return DATA_S_SAMEFORMATETC;
81  }
82 
83  HRESULT STDMETHODCALLTYPE EnumFormatEtc(DWORD dwDirection,IEnumFORMATETC ** ppenumFormatetc) {
84  if (dwDirection == DATADIR_GET) {
85  if (ppenumFormatetc == NULL) return E_INVALIDARG;
86  return CreateIEnumFORMATETC(ppenumFormatetc);
87  } else if (dwDirection == DATADIR_SET) {
88  return E_NOTIMPL;
89  } else {
90  return E_INVALIDARG;
91  }
92  }
93 
94  HRESULT STDMETHODCALLTYPE SetData(FORMATETC * pFormatetc, STGMEDIUM * pmedium, BOOL fRelease) {
95  try {
96  ReleaseStgMediumScope relScope(fRelease ? pmedium : NULL);
97  if (pFormatetc == NULL || pmedium == NULL) return E_INVALIDARG;
98 
99  /*TCHAR buf[256];
100  if (GetClipboardFormatName(pFormatetc->cfFormat,buf,PFC_TABSIZE(buf)) > 0) {
101  buf[PFC_TABSIZE(buf)-1] = 0;
102  OutputDebugString(TEXT("SetData: ")); OutputDebugString(buf); OutputDebugString(TEXT("\n"));
103  } else {
104  OutputDebugString(TEXT("SetData: unknown clipboard format.\n"));
105  }*/
106 
108  HRESULT state = STGMEDIUMToDataBlock(*pmedium,temp);
109  if (FAILED(state)) return state;
110  m_entries.set(*pFormatetc,temp);
111  return S_OK;
112  } FB2K_COM_CATCH;
113  }
114  HRESULT STDMETHODCALLTYPE DAdvise(FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection) {return OLE_E_ADVISENOTSUPPORTED;}
115  HRESULT STDMETHODCALLTYPE DUnadvise(DWORD dwConnection) {return OLE_E_ADVISENOTSUPPORTED;}
116  HRESULT STDMETHODCALLTYPE EnumDAdvise(IEnumSTATDATA ** ppenumAdvise) {return OLE_E_ADVISENOTSUPPORTED;}
117  protected:
118  virtual HRESULT RenderData(UINT format,DWORD aspect,LONG dataIndex,stream_writer_formatter<> & out) const {
119  FORMATETC fmt = {};
120  fmt.cfFormat = format; fmt.dwAspect = aspect; fmt.lindex = dataIndex;
121  const pfc::array_t<t_uint8> * entry = m_entries.query_ptr(fmt);
122  if (entry != NULL) {
123  out.write_raw(entry->get_ptr(), entry->get_size());
124  return S_OK;
125  }
126  return DV_E_FORMATETC;
127  }
128  virtual HRESULT RenderDataTest(UINT format,DWORD aspect, LONG dataIndex) const {
129  FORMATETC fmt = {};
130  fmt.cfFormat = format; fmt.dwAspect = aspect; fmt.lindex = dataIndex;
131  if (m_entries.have_item(fmt)) return S_OK;
132  return DV_E_FORMATETC;
133  }
135 
136  static void AddFormat(TFormatList & out,UINT code) {
137  FORMATETC fmt = {};
138  fmt.dwAspect = DVASPECT_CONTENT;
139  fmt.lindex = -1;
140  fmt.cfFormat = code;
141  for(t_size medWalk = 0; medWalk < 32; ++medWalk) {
142  const DWORD med = 1 << medWalk;
143  if ((DataBlockToSTGMEDIUM_SupportedTymeds & med) != 0) {
144  fmt.tymed = med;
145  out.add_item(fmt);
146  }
147  }
148  }
149 
150  virtual void EnumFormats(TFormatList & out) const {
151  pfc::avltree_t<UINT> formats;
152  for(t_entries::const_iterator walk = m_entries.first(); walk.is_valid(); ++walk) {
153  formats.add_item( walk->m_key.cfFormat );
154  }
155  for(pfc::const_iterator<UINT> walk = formats.first(); walk.is_valid(); ++walk) {
156  AddFormat(out, *walk);
157  }
158  }
159  HRESULT CreateIEnumFORMATETC(IEnumFORMATETC ** outptr) const throw() {
160  try {
162  EnumFormats(out);
163  return SHCreateStdEnumFmtEtc((UINT)out.get_count(), out.get_ptr(), outptr);
164  } FB2K_COM_CATCH;
165  }
166  private:
167  HRESULT GetData_internal(FORMATETC * formatetc, STGMEDIUM * medium,bool bHere) {
168  if (formatetc == NULL || medium == NULL) return E_INVALIDARG;
169 
170  try {
172  HRESULT hr = RenderData(formatetc->cfFormat,formatetc->dwAspect,formatetc->lindex,out);
173  if (FAILED(hr)) return hr;
174  return DataBlockToSTGMEDIUM(out.m_buffer.get_ptr(),out.m_buffer.get_size(),medium,formatetc->tymed,bHere);
175  } FB2K_COM_CATCH;
176  }
177 
179  t_entries m_entries;
180  };
181 }
182 
183 #endif // _WIN32
HRESULT STDMETHODCALLTYPE DUnadvise(DWORD dwConnection)
Definition: map.h:16
HRESULT STDMETHODCALLTYPE SetData(FORMATETC *pFormatetc, STGMEDIUM *pmedium, BOOL fRelease)
const t_item * get_ptr() const
Definition: array.h:213
HRESULT DataBlockToSTGMEDIUM(const void *blockPtr, t_size blockSize, STGMEDIUM *medium, DWORD tymed, bool bHere)
HRESULT SetDataObjectString(pfc::com_ptr_t< IDataObject > obj, const char *str)
HRESULT STDMETHODCALLTYPE EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatetc)
HRESULT GetData_internal(FORMATETC *formatetc, STGMEDIUM *medium, bool bHere)
t_size add_item(const T &item)
Definition: list.h:210
static int compare(const FORMATETC &v1, const FORMATETC &v2)
HRESULT STDMETHODCALLTYPE EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
HRESULT ExtractDataObjectString(pfc::com_ptr_t< IDataObject > obj, pfc::string_base &out)
static const DWORD DataBlockToSTGMEDIUM_SupportedTymeds
typedef BOOL(WINAPI *pPowerSetRequest_t)(__in HANDLE PowerRequest
HRESULT STDMETHODCALLTYPE DAdvise(FORMATETC *pFormatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
pfc::list_base_t< FORMATETC > TFormatList
pfc::map_t< FORMATETC, pfc::array_t< t_uint8 >, comparator_FORMATETC > t_entries
bool is_valid() const
Definition: iterators.h:24
HRESULT ExtractDataObjectContentTest(pfc::com_ptr_t< IDataObject > obj, UINT format, DWORD aspect, LONG index)
static void AddFormat(TFormatList &out, UINT code)
const_iterator first() const
Definition: avltree.h:485
HRESULT ExtractDataObjectContent(pfc::com_ptr_t< IDataObject > obj, UINT format, DWORD aspect, LONG index, pfc::array_t< t_uint8 > &out)
size_t t_size
Definition: int_types.h:48
HRESULT PasteSucceeded(pfc::com_ptr_t< IDataObject > obj, DWORD effect)
virtual void EnumFormats(TFormatList &out) const
HRESULT ExtractDataObjectDWORD(pfc::com_ptr_t< IDataObject > obj, UINT format, DWORD &val)
int compare_t(const hasher_md5_result &p_item1, const hasher_md5_result &p_item2)
Definition: hasher_md5.h:20
HRESULT STDMETHODCALLTYPE QueryGetData(FORMATETC *formatetc)
HRESULT STGMEDIUMToDataBlock(const STGMEDIUM &med, pfc::array_t< t_uint8 > &out)
HRESULT SetDataObjectContent(pfc::com_ptr_t< IDataObject > obj, UINT format, DWORD aspect, LONG index, const void *data, t_size dataSize)
HRESULT CreateIEnumFORMATETC(IEnumFORMATETC **outptr) const
HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc(FORMATETC *in, FORMATETC *out)
t_storage & add_item(t_param const &p_item)
Definition: avltree.h:380
virtual HRESULT RenderDataTest(UINT format, DWORD aspect, LONG dataIndex) const
HGLOBAL HGlobalFromMemblock(const void *ptr, t_size size)
HRESULT SetDataObjectDWORD(pfc::com_ptr_t< IDataObject > obj, UINT format, DWORD val)
HRESULT STDMETHODCALLTYPE GetDataHere(FORMATETC *formatetc, STGMEDIUM *medium)
static const DWORD ExtractDataObjectContent_SupportedTymeds
virtual HRESULT RenderData(UINT format, DWORD aspect, LONG dataIndex, stream_writer_formatter<> &out) const
void write_raw(const void *p_buffer, t_size p_bytes)
t_size get_size() const
Definition: array.h:130