]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/ole/dataobj.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: msw/ole/dataobj.cpp
3 // Purpose: implementation of wx[I]DataObject class
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "dataobj.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
27 #if defined(__BORLANDC__)
33 #if defined(__WIN32__) && !defined(__GNUWIN32__)
36 #include "wx/dataobj.h"
46 #include "wx/msw/ole/oleutils.h"
48 // ----------------------------------------------------------------------------
50 // ----------------------------------------------------------------------------
52 static const char *GetTymedName(DWORD tymed
);
54 // ----------------------------------------------------------------------------
55 // wxIEnumFORMATETC interface implementation
56 // ----------------------------------------------------------------------------
57 class wxIEnumFORMATETC
: public IEnumFORMATETC
60 wxIEnumFORMATETC(CLIPFORMAT cf
);
62 DECLARE_IUNKNOWN_METHODS
;
65 STDMETHODIMP
Next(ULONG celt
, FORMATETC
*rgelt
, ULONG
*pceltFetched
);
66 STDMETHODIMP
Skip(ULONG celt
);
68 STDMETHODIMP
Clone(IEnumFORMATETC
**ppenum
);
71 FORMATETC m_format
; // (unique @@@) format we can provide data in
72 ULONG m_nCurrent
; // current enum position (currently either 0 or 1)
75 // ----------------------------------------------------------------------------
76 // wxIDataObject implementation of IDataObject interface
77 // ----------------------------------------------------------------------------
78 class wxIDataObject
: public IDataObject
81 wxIDataObject(wxDataObject
*pDataObject
);
83 DECLARE_IUNKNOWN_METHODS
;
86 STDMETHODIMP
GetData(FORMATETC
*pformatetcIn
, STGMEDIUM
*pmedium
);
87 STDMETHODIMP
GetDataHere(FORMATETC
*pformatetc
, STGMEDIUM
*pmedium
);
88 STDMETHODIMP
QueryGetData(FORMATETC
*pformatetc
);
89 STDMETHODIMP
GetCanonicalFormatEtc(FORMATETC
*In
, FORMATETC
*pOut
);
90 STDMETHODIMP
SetData(FORMATETC
*pfetc
, STGMEDIUM
*pmedium
, BOOL fRelease
);
91 STDMETHODIMP
EnumFormatEtc(DWORD dwDirection
, IEnumFORMATETC
**ppenumFEtc
);
92 STDMETHODIMP
DAdvise(FORMATETC
*pfetc
, DWORD ad
, IAdviseSink
*p
, DWORD
*pdw
);
93 STDMETHODIMP
DUnadvise(DWORD dwConnection
);
94 STDMETHODIMP
EnumDAdvise(IEnumSTATDATA
**ppenumAdvise
);
97 wxDataObject
*m_pDataObject
; // pointer to C++ class we belong to
100 // ============================================================================
102 // ============================================================================
104 // ----------------------------------------------------------------------------
106 // ----------------------------------------------------------------------------
108 void wxDataFormat::SetId(const wxChar
*format
)
110 m_format
= ::RegisterClipboardFormat(format
);
113 wxLogError(_("Couldn't register clipboard format '%s'."), format
);
117 wxString
wxDataFormat::GetId() const
119 static const int max
= 256;
123 wxCHECK_MSG( !IsStandard(), s
,
124 _T("name of predefined format cannot be retrieved") );
126 int len
= ::GetClipboardFormatName(m_format
, s
.GetWriteBuf(max
), max
);
131 wxLogError(_("The clipboard format '%d' doesn't exist."), m_format
);
137 // ----------------------------------------------------------------------------
139 // ----------------------------------------------------------------------------
141 BEGIN_IID_TABLE(wxIEnumFORMATETC
)
143 ADD_IID(EnumFORMATETC
)
146 IMPLEMENT_IUNKNOWN_METHODS(wxIEnumFORMATETC
)
148 wxIEnumFORMATETC::wxIEnumFORMATETC(CLIPFORMAT cf
)
150 m_format
.cfFormat
= cf
;
152 m_format
.dwAspect
= DVASPECT_CONTENT
;
153 m_format
.lindex
= -1;
154 m_format
.tymed
= TYMED_HGLOBAL
;
159 STDMETHODIMP
wxIEnumFORMATETC::Next(ULONG celt
,
163 wxLogTrace(_T("wxIEnumFORMATETC::Next"));
168 if ( m_nCurrent
== 0 ) {
178 STDMETHODIMP
wxIEnumFORMATETC::Skip(ULONG celt
)
180 wxLogTrace(_T("wxIEnumFORMATETC::Skip"));
182 if ( m_nCurrent
== 0 )
188 STDMETHODIMP
wxIEnumFORMATETC::Reset()
190 wxLogTrace(_T("wxIEnumFORMATETC::Reset"));
197 STDMETHODIMP
wxIEnumFORMATETC::Clone(IEnumFORMATETC
**ppenum
)
199 wxLogTrace(_T("wxIEnumFORMATETC::Clone"));
201 wxIEnumFORMATETC
*pNew
= new wxIEnumFORMATETC(m_format
.cfFormat
);
208 // ----------------------------------------------------------------------------
210 // ----------------------------------------------------------------------------
212 BEGIN_IID_TABLE(wxIDataObject
)
217 IMPLEMENT_IUNKNOWN_METHODS(wxIDataObject
)
219 wxIDataObject::wxIDataObject(wxDataObject
*pDataObject
)
222 m_pDataObject
= pDataObject
;
225 // get data functions
226 STDMETHODIMP
wxIDataObject::GetData(FORMATETC
*pformatetcIn
, STGMEDIUM
*pmedium
)
228 wxLogTrace(_T("wxIDataObject::GetData"));
230 // is data is in our format?
231 HRESULT hr
= QueryGetData(pformatetcIn
);
236 HGLOBAL hGlobal
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_SHARE
,
237 m_pDataObject
->GetDataSize());
238 if ( hGlobal
== NULL
) {
239 wxLogLastError("GlobalAlloc");
240 return E_OUTOFMEMORY
;
244 pmedium
->tymed
= TYMED_HGLOBAL
;
245 pmedium
->hGlobal
= hGlobal
;
246 pmedium
->pUnkForRelease
= NULL
;
248 hr
= GetDataHere(pformatetcIn
, pmedium
);
257 STDMETHODIMP
wxIDataObject::GetDataHere(FORMATETC
*pformatetc
,
260 wxLogTrace(_T("wxIDataObject::GetDataHere"));
262 // put data in caller provided medium
263 if ( pmedium
->tymed
!= TYMED_HGLOBAL
)
267 void *pBuf
= GlobalLock(pmedium
->hGlobal
);
268 if ( pBuf
== NULL
) {
269 wxLogLastError(_T("GlobalLock"));
270 return E_OUTOFMEMORY
;
273 m_pDataObject
->GetDataHere(pBuf
);
275 GlobalUnlock(pmedium
->hGlobal
);
280 // set data functions (not implemented)
281 STDMETHODIMP
wxIDataObject::SetData(FORMATETC
*pformatetc
,
285 wxLogTrace(_T("wxIDataObject::SetData"));
289 // information functions
290 STDMETHODIMP
wxIDataObject::QueryGetData(FORMATETC
*pformatetc
)
292 // do we accept data in this format?
293 if ( pformatetc
== NULL
) {
294 wxLogTrace(_T("wxIDataObject::QueryGetData: invalid ptr."));
298 // the only one allowed by current COM implementation
299 if ( pformatetc
->lindex
!= -1 ) {
300 wxLogTrace(_T("wxIDataObject::QueryGetData: bad lindex %d"),
305 // we don't support anything other (THUMBNAIL, ICON, DOCPRINT...)
306 if ( pformatetc
->dwAspect
!= DVASPECT_CONTENT
) {
307 wxLogTrace(_T("wxIDataObject::QueryGetData: bad dwAspect %d"),
308 pformatetc
->dwAspect
);
309 return DV_E_DVASPECT
;
312 // @@ we only transfer data by global memory (bad for large amounts of it!)
313 if ( !(pformatetc
->tymed
& TYMED_HGLOBAL
) ) {
314 wxLogTrace(_T("wxIDataObject::QueryGetData: %s != TYMED_HGLOBAL."),
315 GetTymedName(pformatetc
->tymed
));
319 // and now check the type of data requested
320 if ( m_pDataObject
->IsSupportedFormat((wxDataFormatId
)pformatetc
->cfFormat
) ) {
321 wxLogTrace(_T("wxIDataObject::QueryGetData: %s ok"),
322 wxDataObject::GetFormatName((wxDataFormatId
)pformatetc
->cfFormat
));
326 wxLogTrace(_T("wxIDataObject::QueryGetData: %s unsupported"),
327 wxDataObject::GetFormatName((wxDataFormatId
)pformatetc
->cfFormat
));
328 return DV_E_FORMATETC
;
332 STDMETHODIMP
wxIDataObject::GetCanonicalFormatEtc(FORMATETC
*pFormatetcIn
,
333 FORMATETC
*pFormatetcOut
)
335 wxLogTrace(_T("wxIDataObject::GetCanonicalFormatEtc"));
337 // @@ implementation is trivial, we might want something better here
338 if ( pFormatetcOut
!= NULL
)
339 pFormatetcOut
->ptd
= NULL
;
340 return DATA_S_SAMEFORMATETC
;
343 STDMETHODIMP
wxIDataObject::EnumFormatEtc(DWORD dwDirection
,
344 IEnumFORMATETC
**ppenumFormatEtc
)
346 wxLogTrace(_T("wxIDataObject::EnumFormatEtc"));
348 if ( dwDirection
== DATADIR_SET
) {
349 // we don't allow setting of data anyhow
353 wxIEnumFORMATETC
*pEnum
=
354 new wxIEnumFORMATETC(m_pDataObject
->GetPreferredFormat());
356 *ppenumFormatEtc
= pEnum
;
361 // advise sink functions (not implemented)
362 STDMETHODIMP
wxIDataObject::DAdvise(FORMATETC
*pformatetc
,
364 IAdviseSink
*pAdvSink
,
365 DWORD
*pdwConnection
)
367 return OLE_E_ADVISENOTSUPPORTED
;
370 STDMETHODIMP
wxIDataObject::DUnadvise(DWORD dwConnection
)
372 return OLE_E_ADVISENOTSUPPORTED
;
375 STDMETHODIMP
wxIDataObject::EnumDAdvise(IEnumSTATDATA
**ppenumAdvise
)
377 return OLE_E_ADVISENOTSUPPORTED
;
380 // ----------------------------------------------------------------------------
382 // ----------------------------------------------------------------------------
384 wxDataObject::wxDataObject()
386 m_pIDataObject
= new wxIDataObject(this);
387 m_pIDataObject
->AddRef();
390 wxDataObject::~wxDataObject()
392 m_pIDataObject
->Release();
395 const char *wxDataObject::GetFormatName(wxDataFormat format
)
398 // case 'xxx' is not a valid value for switch of enum 'wxDataFormat'
400 #pragma warning(disable:4063)
403 static char s_szBuf
[128];
405 case CF_TEXT
: return "CF_TEXT";
406 case CF_BITMAP
: return "CF_BITMAP";
407 case CF_METAFILEPICT
: return "CF_METAFILEPICT";
408 case CF_SYLK
: return "CF_SYLK";
409 case CF_DIF
: return "CF_DIF";
410 case CF_TIFF
: return "CF_TIFF";
411 case CF_OEMTEXT
: return "CF_OEMTEXT";
412 case CF_DIB
: return "CF_DIB";
413 case CF_PALETTE
: return "CF_PALETTE";
414 case CF_PENDATA
: return "CF_PENDATA";
415 case CF_RIFF
: return "CF_RIFF";
416 case CF_WAVE
: return "CF_WAVE";
417 case CF_UNICODETEXT
: return "CF_UNICODETEXT";
418 case CF_ENHMETAFILE
: return "CF_ENHMETAFILE";
419 case CF_HDROP
: return "CF_HDROP";
420 case CF_LOCALE
: return "CF_LOCALE";
422 sprintf(s_szBuf
, "clipboard format %d (unknown)", format
);
427 #pragma warning(default:4063)
435 // ----------------------------------------------------------------------------
436 // wxPrivateDataObject
437 // ----------------------------------------------------------------------------
439 wxPrivateDataObject::wxPrivateDataObject()
445 void wxPrivateDataObject::Free()
451 void wxPrivateDataObject::SetData( const void *data
, size_t size
)
456 m_data
= malloc(size
);
458 memcpy( m_data
, data
, size
);
461 void wxPrivateDataObject::WriteData( void *dest
) const
463 WriteData( m_data
, dest
);
466 size_t wxPrivateDataObject::GetSize() const
471 void wxPrivateDataObject::WriteData( const void *data
, void *dest
) const
473 memcpy( dest
, data
, GetSize() );
476 // ----------------------------------------------------------------------------
478 // ----------------------------------------------------------------------------
479 static const char *GetTymedName(DWORD tymed
)
481 static char s_szBuf
[128];
483 case TYMED_HGLOBAL
: return "TYMED_HGLOBAL";
484 case TYMED_FILE
: return "TYMED_FILE";
485 case TYMED_ISTREAM
: return "TYMED_ISTREAM";
486 case TYMED_ISTORAGE
: return "TYMED_ISTORAGE";
487 case TYMED_GDI
: return "TYMED_GDI";
488 case TYMED_MFPICT
: return "TYMED_MFPICT";
489 case TYMED_ENHMF
: return "TYMED_ENHMF";
491 sprintf(s_szBuf
, "type of media format %d (unknown)", tymed
);
496 // TODO: OLE parts of wxBitmap/File/MetafileDataObject