]>
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__) 
  35 #if defined(__WIN32__) && !defined(__GNUWIN32__) || defined(wxUSE_NORLANDER_HEADERS) 
  38 #include "wx/dataobj.h" 
  41 #ifdef wxUSE_NORLANDER_HEADERS 
  51 #include  "wx/msw/ole/oleutils.h" 
  53 // ---------------------------------------------------------------------------- 
  55 // ---------------------------------------------------------------------------- 
  57 static const char *GetTymedName(DWORD tymed
); 
  59 // ---------------------------------------------------------------------------- 
  60 // wxIEnumFORMATETC interface implementation 
  61 // ---------------------------------------------------------------------------- 
  62 class wxIEnumFORMATETC 
: public IEnumFORMATETC
 
  65   wxIEnumFORMATETC(CLIPFORMAT cf
); 
  67   DECLARE_IUNKNOWN_METHODS
; 
  70   STDMETHODIMP 
Next(ULONG celt
, FORMATETC 
*rgelt
, ULONG 
*pceltFetched
); 
  71   STDMETHODIMP 
Skip(ULONG celt
); 
  73   STDMETHODIMP 
Clone(IEnumFORMATETC 
**ppenum
); 
  76   FORMATETC   m_format
;   // (unique @@@) format we can provide data in 
  77   ULONG       m_nCurrent
; // current enum position (currently either 0 or 1) 
  80 // ---------------------------------------------------------------------------- 
  81 // wxIDataObject implementation of IDataObject interface 
  82 // ---------------------------------------------------------------------------- 
  83 class wxIDataObject 
: public IDataObject
 
  86   wxIDataObject(wxDataObject 
*pDataObject
); 
  88   DECLARE_IUNKNOWN_METHODS
; 
  91   STDMETHODIMP 
GetData(FORMATETC 
*pformatetcIn
, STGMEDIUM 
*pmedium
); 
  92   STDMETHODIMP 
GetDataHere(FORMATETC 
*pformatetc
, STGMEDIUM 
*pmedium
); 
  93   STDMETHODIMP 
QueryGetData(FORMATETC 
*pformatetc
); 
  94   STDMETHODIMP 
GetCanonicalFormatEtc(FORMATETC 
*In
, FORMATETC 
*pOut
); 
  95   STDMETHODIMP 
SetData(FORMATETC 
*pfetc
, STGMEDIUM 
*pmedium
, BOOL fRelease
); 
  96   STDMETHODIMP 
EnumFormatEtc(DWORD dwDirection
, IEnumFORMATETC 
**ppenumFEtc
); 
  97   STDMETHODIMP 
DAdvise(FORMATETC 
*pfetc
, DWORD ad
, IAdviseSink 
*p
, DWORD 
*pdw
); 
  98   STDMETHODIMP 
DUnadvise(DWORD dwConnection
); 
  99   STDMETHODIMP 
EnumDAdvise(IEnumSTATDATA 
**ppenumAdvise
); 
 102   wxDataObject 
*m_pDataObject
;      // pointer to C++ class we belong to 
 105 // ============================================================================ 
 107 // ============================================================================ 
 109 // ---------------------------------------------------------------------------- 
 111 // ---------------------------------------------------------------------------- 
 113 void wxDataFormat::SetId(const wxChar 
*format
) 
 115     m_format 
= ::RegisterClipboardFormat(format
); 
 118         wxLogError(_("Couldn't register clipboard format '%s'."), format
); 
 122 wxString 
wxDataFormat::GetId() const 
 124     static const int max 
= 256; 
 128     wxCHECK_MSG( !IsStandard(), s
, 
 129                  _T("name of predefined format cannot be retrieved") ); 
 131     int len 
= ::GetClipboardFormatName(m_format
, s
.GetWriteBuf(max
), max
); 
 136         wxLogError(_("The clipboard format '%d' doesn't exist."), m_format
); 
 142 // ---------------------------------------------------------------------------- 
 144 // ---------------------------------------------------------------------------- 
 146 BEGIN_IID_TABLE(wxIEnumFORMATETC
) 
 148   ADD_IID(EnumFORMATETC
) 
 151 IMPLEMENT_IUNKNOWN_METHODS(wxIEnumFORMATETC
) 
 153 wxIEnumFORMATETC::wxIEnumFORMATETC(CLIPFORMAT cf
) 
 155   m_format
.cfFormat 
= cf
; 
 157   m_format
.dwAspect 
= DVASPECT_CONTENT
; 
 158   m_format
.lindex   
= -1; 
 159   m_format
.tymed    
= TYMED_HGLOBAL
; 
 164 STDMETHODIMP 
wxIEnumFORMATETC::Next(ULONG      celt
, 
 168   wxLogTrace(_T("wxIEnumFORMATETC::Next")); 
 173   if ( m_nCurrent 
== 0 ) { 
 183 STDMETHODIMP 
wxIEnumFORMATETC::Skip(ULONG celt
) 
 185   wxLogTrace(_T("wxIEnumFORMATETC::Skip")); 
 187   if ( m_nCurrent 
== 0 ) 
 193 STDMETHODIMP 
wxIEnumFORMATETC::Reset() 
 195   wxLogTrace(_T("wxIEnumFORMATETC::Reset")); 
 202 STDMETHODIMP 
wxIEnumFORMATETC::Clone(IEnumFORMATETC 
**ppenum
) 
 204   wxLogTrace(_T("wxIEnumFORMATETC::Clone")); 
 206   wxIEnumFORMATETC 
*pNew 
= new wxIEnumFORMATETC(m_format
.cfFormat
); 
 213 // ---------------------------------------------------------------------------- 
 215 // ---------------------------------------------------------------------------- 
 217 BEGIN_IID_TABLE(wxIDataObject
) 
 222 IMPLEMENT_IUNKNOWN_METHODS(wxIDataObject
) 
 224 wxIDataObject::wxIDataObject(wxDataObject 
*pDataObject
) 
 227   m_pDataObject 
= pDataObject
; 
 230 // get data functions 
 231 STDMETHODIMP 
wxIDataObject::GetData(FORMATETC 
*pformatetcIn
, STGMEDIUM 
*pmedium
) 
 233   wxLogTrace(_T("wxIDataObject::GetData")); 
 235   // is data is in our format? 
 236   HRESULT hr 
= QueryGetData(pformatetcIn
); 
 241   HGLOBAL hGlobal 
= GlobalAlloc(GMEM_MOVEABLE 
| GMEM_SHARE
, 
 242                                 m_pDataObject
->GetDataSize()); 
 243   if ( hGlobal 
== NULL 
) { 
 244     wxLogLastError("GlobalAlloc"); 
 245     return E_OUTOFMEMORY
; 
 249   pmedium
->tymed          
= TYMED_HGLOBAL
; 
 250   pmedium
->hGlobal        
= hGlobal
; 
 251   pmedium
->pUnkForRelease 
= NULL
; 
 253   hr 
= GetDataHere(pformatetcIn
, pmedium
); 
 262 STDMETHODIMP 
wxIDataObject::GetDataHere(FORMATETC 
*pformatetc
, 
 265   wxLogTrace(_T("wxIDataObject::GetDataHere")); 
 267   // put data in caller provided medium 
 268   if ( pmedium
->tymed 
!= TYMED_HGLOBAL 
) 
 272   void *pBuf 
= GlobalLock(pmedium
->hGlobal
); 
 273   if ( pBuf 
== NULL 
) { 
 274     wxLogLastError(_T("GlobalLock")); 
 275     return E_OUTOFMEMORY
; 
 278   m_pDataObject
->GetDataHere(pBuf
); 
 280   GlobalUnlock(pmedium
->hGlobal
); 
 285 // set data functions (not implemented) 
 286 STDMETHODIMP 
wxIDataObject::SetData(FORMATETC 
*pformatetc
, 
 290   wxLogTrace(_T("wxIDataObject::SetData")); 
 294 // information functions 
 295 STDMETHODIMP 
wxIDataObject::QueryGetData(FORMATETC 
*pformatetc
) 
 297   // do we accept data in this format? 
 298   if ( pformatetc 
== NULL 
) { 
 299     wxLogTrace(_T("wxIDataObject::QueryGetData: invalid ptr.")); 
 303   // the only one allowed by current COM implementation 
 304   if ( pformatetc
->lindex 
!= -1 ) { 
 305     wxLogTrace(_T("wxIDataObject::QueryGetData: bad lindex %d"), 
 310   // we don't support anything other (THUMBNAIL, ICON, DOCPRINT...) 
 311   if ( pformatetc
->dwAspect 
!= DVASPECT_CONTENT 
) { 
 312     wxLogTrace(_T("wxIDataObject::QueryGetData: bad dwAspect %d"), 
 313                pformatetc
->dwAspect
); 
 314     return DV_E_DVASPECT
; 
 317   // @@ we only transfer data by global memory (bad for large amounts of it!) 
 318   if ( !(pformatetc
->tymed 
& TYMED_HGLOBAL
) ) { 
 319     wxLogTrace(_T("wxIDataObject::QueryGetData: %s != TYMED_HGLOBAL."), 
 320                GetTymedName(pformatetc
->tymed
)); 
 324   // and now check the type of data requested 
 325   if ( m_pDataObject
->IsSupportedFormat((wxDataFormatId
)pformatetc
->cfFormat
) ) { 
 326     wxLogTrace(_T("wxIDataObject::QueryGetData: %s ok"), 
 327                wxDataObject::GetFormatName((wxDataFormatId
)pformatetc
->cfFormat
)); 
 331     wxLogTrace(_T("wxIDataObject::QueryGetData: %s unsupported"), 
 332                wxDataObject::GetFormatName((wxDataFormatId
)pformatetc
->cfFormat
)); 
 333     return DV_E_FORMATETC
; 
 337 STDMETHODIMP 
wxIDataObject::GetCanonicalFormatEtc(FORMATETC 
*pFormatetcIn
, 
 338                                                   FORMATETC 
*pFormatetcOut
) 
 340   wxLogTrace(_T("wxIDataObject::GetCanonicalFormatEtc")); 
 342   // @@ implementation is trivial, we might want something better here 
 343   if ( pFormatetcOut 
!= NULL 
) 
 344     pFormatetcOut
->ptd 
= NULL
; 
 345   return DATA_S_SAMEFORMATETC
; 
 348 STDMETHODIMP 
wxIDataObject::EnumFormatEtc(DWORD dwDirection
, 
 349                                           IEnumFORMATETC 
**ppenumFormatEtc
) 
 351   wxLogTrace(_T("wxIDataObject::EnumFormatEtc")); 
 353   if ( dwDirection 
== DATADIR_SET 
) { 
 354     // we don't allow setting of data anyhow 
 358   wxIEnumFORMATETC 
*pEnum 
= 
 359     new wxIEnumFORMATETC(m_pDataObject
->GetPreferredFormat()); 
 361   *ppenumFormatEtc 
= pEnum
; 
 366 // advise sink functions (not implemented) 
 367 STDMETHODIMP 
wxIDataObject::DAdvise(FORMATETC   
*pformatetc
, 
 369                                     IAdviseSink 
*pAdvSink
, 
 370                                     DWORD       
*pdwConnection
) 
 372   return OLE_E_ADVISENOTSUPPORTED
; 
 375 STDMETHODIMP 
wxIDataObject::DUnadvise(DWORD dwConnection
) 
 377   return OLE_E_ADVISENOTSUPPORTED
; 
 380 STDMETHODIMP 
wxIDataObject::EnumDAdvise(IEnumSTATDATA 
**ppenumAdvise
) 
 382   return OLE_E_ADVISENOTSUPPORTED
; 
 385 // ---------------------------------------------------------------------------- 
 387 // ---------------------------------------------------------------------------- 
 389 wxDataObject::wxDataObject() 
 391   m_pIDataObject 
= new wxIDataObject(this); 
 392   m_pIDataObject
->AddRef(); 
 395 wxDataObject::~wxDataObject() 
 397   m_pIDataObject
->Release(); 
 400 const char *wxDataObject::GetFormatName(wxDataFormat format
) 
 403   // case 'xxx' is not a valid value for switch of enum 'wxDataFormat' 
 405     #pragma warning(disable:4063) 
 408   static char s_szBuf
[128]; 
 410     case CF_TEXT
:         return "CF_TEXT"; 
 411     case CF_BITMAP
:       return "CF_BITMAP"; 
 412     case CF_METAFILEPICT
: return "CF_METAFILEPICT"; 
 413     case CF_SYLK
:         return "CF_SYLK"; 
 414     case CF_DIF
:          return "CF_DIF"; 
 415     case CF_TIFF
:         return "CF_TIFF"; 
 416     case CF_OEMTEXT
:      return "CF_OEMTEXT"; 
 417     case CF_DIB
:          return "CF_DIB"; 
 418     case CF_PALETTE
:      return "CF_PALETTE"; 
 419     case CF_PENDATA
:      return "CF_PENDATA"; 
 420     case CF_RIFF
:         return "CF_RIFF"; 
 421     case CF_WAVE
:         return "CF_WAVE"; 
 422     case CF_UNICODETEXT
:  return "CF_UNICODETEXT"; 
 423     case CF_ENHMETAFILE
:  return "CF_ENHMETAFILE"; 
 424     case CF_HDROP
:        return "CF_HDROP"; 
 425     case CF_LOCALE
:       return "CF_LOCALE"; 
 427       sprintf(s_szBuf
, "clipboard format %d (unknown)", format
); 
 432     #pragma warning(default:4063) 
 440 // ---------------------------------------------------------------------------- 
 441 // wxPrivateDataObject 
 442 // ---------------------------------------------------------------------------- 
 444 wxPrivateDataObject::wxPrivateDataObject() 
 450 void wxPrivateDataObject::Free() 
 456 void wxPrivateDataObject::SetData( const void *data
, size_t size 
) 
 461     m_data 
= malloc(size
); 
 463     memcpy( m_data
, data
, size 
); 
 466 void wxPrivateDataObject::WriteData( void *dest 
) const 
 468     WriteData( m_data
, dest 
); 
 471 size_t wxPrivateDataObject::GetSize() const 
 476 void wxPrivateDataObject::WriteData( const void *data
, void *dest 
) const 
 478     memcpy( dest
, data
, GetSize() ); 
 481 // ---------------------------------------------------------------------------- 
 483 // ---------------------------------------------------------------------------- 
 484 static const char *GetTymedName(DWORD tymed
) 
 486   static char s_szBuf
[128]; 
 488     case TYMED_HGLOBAL
:   return "TYMED_HGLOBAL"; 
 489     case TYMED_FILE
:      return "TYMED_FILE"; 
 490     case TYMED_ISTREAM
:   return "TYMED_ISTREAM"; 
 491     case TYMED_ISTORAGE
:  return "TYMED_ISTORAGE"; 
 492     case TYMED_GDI
:       return "TYMED_GDI"; 
 493     case TYMED_MFPICT
:    return "TYMED_MFPICT"; 
 494     case TYMED_ENHMF
:     return "TYMED_ENHMF"; 
 496       sprintf(s_szBuf
, "type of media format %d (unknown)", tymed
); 
 501 // TODO: OLE parts of wxBitmap/File/MetafileDataObject