+#if wxUSE_OLE_CLIPBOARD
+ IDataObject *pDataObject = NULL;
+ HRESULT hr = OleGetClipboard(&pDataObject);
+ if ( FAILED(hr) || !pDataObject )
+ {
+ wxLogSysError(hr, _("Failed to get data from the clipboard"));
+
+ return FALSE;
+ }
+
+ // build the list of supported formats
+ size_t nFormats = data.GetFormatCount(wxDataObject::Set);
+ wxDataFormat format, *formats;
+ if ( nFormats == 1 )
+ {
+ // the most common case
+ formats = &format;
+ }
+ else
+ {
+ // bad luck, need to alloc mem
+ formats = new wxDataFormat[nFormats];
+ }
+
+ data.GetAllFormats(formats, wxDataObject::Set);
+
+ // get the format enumerator
+ bool result = FALSE;
+ wxArrayInt supportedFormats;
+ IEnumFORMATETC *pEnumFormatEtc = NULL;
+ hr = pDataObject->EnumFormatEtc(DATADIR_GET, &pEnumFormatEtc);
+ if ( FAILED(hr) || !pEnumFormatEtc )
+ {
+ wxLogSysError(hr,
+ _("Failed to retrieve the supported clipboard formats"));
+ }
+ else
+ {
+ // ask for the supported formats and see if there are any we support
+ FORMATETC formatEtc;
+ for ( ;; )
+ {
+ ULONG nCount;
+ hr = pEnumFormatEtc->Next(1, &formatEtc, &nCount);
+
+ // don't use FAILED() because S_FALSE would pass it
+ if ( hr != S_OK )
+ {
+ // no more formats
+ break;
+ }
+
+ CLIPFORMAT cf = formatEtc.cfFormat;
+
+#ifdef __WXDEBUG__
+ wxLogTrace(wxTRACE_OleCalls,
+ wxT("Object on the clipboard supports format %s."),
+ wxDataObject::GetFormatName(cf));
+#endif // Debug
+
+ // is supported?
+ for ( size_t n = 0; n < nFormats; n++ )
+ {
+ if ( formats[n].GetFormatId() == cf )
+ {
+ if ( supportedFormats.Index(cf) == wxNOT_FOUND )
+ {
+ supportedFormats.Add(cf);
+ }
+ }
+ }
+ }
+
+ pEnumFormatEtc->Release();
+ }
+
+ if ( formats != &format )
+ {
+ delete [] formats;
+ }
+ //else: we didn't allocate any memory
+
+ if ( !supportedFormats.IsEmpty() )
+ {
+ FORMATETC formatEtc;
+ formatEtc.ptd = NULL;
+ formatEtc.dwAspect = DVASPECT_CONTENT;
+ formatEtc.lindex = -1;
+
+ size_t nSupportedFormats = supportedFormats.GetCount();
+ for ( size_t n = 0; !result && (n < nSupportedFormats); n++ )
+ {
+ STGMEDIUM medium;
+ formatEtc.cfFormat = supportedFormats[n];
+
+ // use the appropriate tymed
+ switch ( formatEtc.cfFormat )
+ {
+ case CF_BITMAP:
+ formatEtc.tymed = TYMED_GDI;
+ break;
+
+ case CF_METAFILEPICT:
+ formatEtc.tymed = TYMED_MFPICT;
+ break;
+
+ case CF_ENHMETAFILE:
+ formatEtc.tymed = TYMED_ENHMF;
+ break;
+
+ default:
+ formatEtc.tymed = TYMED_HGLOBAL;
+ }
+
+ // try to get data
+ hr = pDataObject->GetData(&formatEtc, &medium);
+ if ( FAILED(hr) )
+ {
+ // try other tymed for GDI objects
+ if ( formatEtc.cfFormat == CF_BITMAP )
+ {
+ formatEtc.tymed = TYMED_HGLOBAL;
+ hr = pDataObject->GetData(&formatEtc, &medium);
+ }
+ }
+
+ if ( SUCCEEDED(hr) )
+ {
+ // pass the data to the data object
+ hr = data.GetInterface()->SetData(&formatEtc, &medium, TRUE);
+ if ( FAILED(hr) )
+ {
+ wxLogDebug(wxT("Failed to set data in wxIDataObject"));
+
+ // IDataObject only takes the ownership of data if it
+ // successfully got it - which is not the case here
+ ReleaseStgMedium(&medium);
+ }
+ else
+ {
+ result = TRUE;
+ }
+ }
+ //else: unsupported tymed?
+ }
+ }
+ //else: unsupported format
+
+ // clean up and return
+ pDataObject->Release();
+
+ return result;
+#elif wxUSE_DATAOBJ