+}
+
+bool wxFileDataObject::GetDataHere(void *WXUNUSED_IN_WINCE(pData)) const
+{
+#ifndef __WXWINCE__
+ // pData points to an externally allocated memory block
+ // created using the size returned by GetDataSize()
+
+ // if pData is NULL, or there are no files, return
+ if ( !pData || m_filenames.GetCount() == 0 )
+ return false;
+
+ // convert data pointer to a DROPFILES struct pointer
+ LPDROPFILES pDrop = (LPDROPFILES) pData;
+
+ // initialize DROPFILES struct
+ pDrop->pFiles = sizeof(DROPFILES);
+ pDrop->fNC = FALSE; // not non-client coords
+#if wxUSE_UNICODE
+ pDrop->fWide = TRUE;
+#else // ANSI
+ pDrop->fWide = FALSE;
+#endif // Unicode/Ansi
+
+ // set start of filenames list (null separated)
+ wxChar *pbuf = (wxChar*) ((BYTE *)pDrop + sizeof(DROPFILES));
+
+ size_t count = m_filenames.GetCount();
+ for (size_t i = 0; i < count; i++ )
+ {
+ // copy filename to pbuf and add null terminator
+ size_t len = m_filenames[i].Len();
+ memcpy(pbuf, m_filenames[i], len*sizeof(wxChar));
+ pbuf += len;
+ *pbuf++ = wxT('\0');
+ }
+
+ // add final null terminator
+ *pbuf = wxT('\0');
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+// ----------------------------------------------------------------------------
+// wxURLDataObject
+// ----------------------------------------------------------------------------
+
+class CFSTR_SHELLURLDataObject : public wxCustomDataObject
+{
+public:
+ CFSTR_SHELLURLDataObject() : wxCustomDataObject(CFSTR_SHELLURL) {}
+
+ virtual size_t GetBufferOffset( const wxDataFormat& WXUNUSED(format) )
+ {
+ return 0;
+ }
+
+ virtual const void* GetSizeFromBuffer( const void* buffer, size_t* size,
+ const wxDataFormat& WXUNUSED(format) )
+ {
+ // CFSTR_SHELLURL is _always_ ANSI text
+ *size = strlen( (const char*)buffer );
+
+ return buffer;
+ }
+
+ virtual void* SetSizeInBuffer( void* buffer, size_t WXUNUSED(size),
+ const wxDataFormat& WXUNUSED(format) )
+ {
+ return buffer;
+ }
+
+#if wxUSE_UNICODE
+ virtual bool GetDataHere( void* buffer ) const
+ {
+ // CFSTR_SHELLURL is _always_ ANSI!
+ wxCharBuffer char_buffer( GetDataSize() );
+ wxCustomDataObject::GetDataHere( (void*)char_buffer.data() );
+ wxString unicode_buffer( char_buffer, wxConvLibc );
+ memcpy( buffer, unicode_buffer.c_str(),
+ ( unicode_buffer.length() + 1 ) * sizeof(wxChar) );
+
+ return true;
+ }
+ virtual bool GetDataHere(const wxDataFormat& WXUNUSED(format),
+ void *buf) const
+ { return GetDataHere(buf); }
+#endif
+
+ DECLARE_NO_COPY_CLASS(CFSTR_SHELLURLDataObject)
+};
+
+
+
+wxURLDataObject::wxURLDataObject()
+{
+ // we support CF_TEXT and CFSTR_SHELLURL formats which are basicly the same
+ // but it seems that some browsers only provide one of them so we have to
+ // support both
+ Add(new wxTextDataObject);
+ Add(new CFSTR_SHELLURLDataObject());
+
+ // we don't have any data yet
+ m_dataObjectLast = NULL;
+}
+
+bool wxURLDataObject::SetData(const wxDataFormat& format,
+ size_t len,
+ const void *buf)
+{
+ m_dataObjectLast = GetObject(format);
+
+ wxCHECK_MSG( m_dataObjectLast, FALSE,
+ wxT("unsupported format in wxURLDataObject"));
+
+ return m_dataObjectLast->SetData(len, buf);
+}
+
+wxString wxURLDataObject::GetURL() const
+{
+ wxString url;
+ wxCHECK_MSG( m_dataObjectLast, url, _T("no data in wxURLDataObject") );
+
+ size_t len = m_dataObjectLast->GetDataSize();
+
+ m_dataObjectLast->GetDataHere(wxStringBuffer(url, len));
+
+ return url;
+}
+
+void wxURLDataObject::SetURL(const wxString& url)
+{
+ SetData(wxDataFormat(wxUSE_UNICODE ? wxDF_UNICODETEXT : wxDF_TEXT),
+ url.Length()+1, url.c_str());
+
+ // CFSTR_SHELLURL is always supposed to be ANSI...
+ wxWX2MBbuf urlA = (wxWX2MBbuf)url.mbc_str();
+ size_t len = strlen(urlA);
+ SetData(wxDataFormat(CFSTR_SHELLURL), len+1, (const char*)urlA);
+}
+
+// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
+
+#ifdef __WXDEBUG__
+
+static const wxChar *GetTymedName(DWORD tymed)
+{
+ static wxChar s_szBuf[128];
+ switch ( tymed ) {
+ case TYMED_HGLOBAL: return wxT("TYMED_HGLOBAL");
+ case TYMED_FILE: return wxT("TYMED_FILE");
+ case TYMED_ISTREAM: return wxT("TYMED_ISTREAM");
+ case TYMED_ISTORAGE: return wxT("TYMED_ISTORAGE");
+ case TYMED_GDI: return wxT("TYMED_GDI");
+ case TYMED_MFPICT: return wxT("TYMED_MFPICT");
+ case TYMED_ENHMF: return wxT("TYMED_ENHMF");
+ default:
+ wxSprintf(s_szBuf, wxT("type of media format %ld (unknown)"), tymed);
+ return s_szBuf;
+ }
+}
+
+#endif // Debug
+
+#else // not using OLE at all
+
+// ----------------------------------------------------------------------------
+// wxDataObject
+// ----------------------------------------------------------------------------
+
+#if wxUSE_DATAOBJ
+
+wxDataObject::wxDataObject()
+{
+}
+
+wxDataObject::~wxDataObject()
+{
+}
+
+void wxDataObject::SetAutoDelete()
+{
+}
+
+#ifdef __WXDEBUG__
+const wxChar *wxDataObject::GetFormatName(wxDataFormat WXUNUSED(format))
+{
+ return NULL;
+}
+#endif // __WXDEBUG__
+
+#endif // wxUSE_DATAOBJ
+
+#endif // wxUSE_OLE/!wxUSE_OLE
+