📄 dataobj.cpp
字号:
} // copy data const void *pBuf = GlobalLock(pmedium->hGlobal); if ( pBuf == NULL ) { wxLogLastError(wxT("GlobalLock")); return E_OUTOFMEMORY; } // we've got a problem with SetData() here because the base // class version requires the size parameter which we don't // have anywhere in OLE data transfer - so we need to // synthetise it for known formats and we suppose that all data // in custom formats starts with a DWORD containing the size size_t size; switch ( format ) { case CF_TEXT: case CF_OEMTEXT: size = strlen((const char *)pBuf); break;#if !(defined(__BORLANDC__) && (__BORLANDC__ < 0x500)) case CF_UNICODETEXT:#if ( defined(__BORLANDC__) && (__BORLANDC__ > 0x530) ) \ || ( defined(__MWERKS__) && defined(__WXMSW__) ) size = std::wcslen((const wchar_t *)pBuf) * sizeof(wchar_t);#else size = wxWcslen((const wchar_t *)pBuf) * sizeof(wchar_t);#endif break;#endif case CF_BITMAP:#ifndef __WXWINCE__ case CF_HDROP: // these formats don't use size at all, anyhow (but // pass data by handle, which is always a single DWORD) size = 0; break;#endif case CF_DIB: // the handler will calculate size itself (it's too // complicated to do it here) size = 0; break;#ifndef __WXWINCE__ case CF_METAFILEPICT: size = sizeof(METAFILEPICT); break;#endif default: pBuf = m_pDataObject-> GetSizeFromBuffer(pBuf, &size, format); size -= m_pDataObject->GetBufferOffset(format); } bool ok = m_pDataObject->SetData(format, size, pBuf); GlobalUnlock(pmedium->hGlobal); if ( !ok ) { return E_UNEXPECTED; } } break; default: return DV_E_TYMED; } if ( fRelease ) { // we own the medium, so we must release it - but do *not* free any // data we pass by handle because we have copied it elsewhere switch ( pmedium->tymed ) { case TYMED_GDI: pmedium->hBitmap = 0; break; case TYMED_MFPICT: pmedium->hMetaFilePict = 0; break; case TYMED_ENHMF: pmedium->hEnhMetaFile = 0; break; } ReleaseStgMedium(pmedium); } return S_OK;}// information functionsSTDMETHODIMP wxIDataObject::QueryGetData(FORMATETC *pformatetc){ // do we accept data in this format? if ( pformatetc == NULL ) { wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: invalid ptr.")); return E_INVALIDARG; } // the only one allowed by current COM implementation if ( pformatetc->lindex != -1 ) { wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: bad lindex %ld"), pformatetc->lindex); return DV_E_LINDEX; } // we don't support anything other (THUMBNAIL, ICON, DOCPRINT...) if ( pformatetc->dwAspect != DVASPECT_CONTENT ) { wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: bad dwAspect %ld"), pformatetc->dwAspect); return DV_E_DVASPECT; } // and now check the type of data requested wxDataFormat format = pformatetc->cfFormat; if ( m_pDataObject->IsSupportedFormat(format) ) { wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: %s ok"), wxGetFormatName(format)); } else { wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: %s unsupported"), wxGetFormatName(format)); return DV_E_FORMATETC; } // we only transfer data by global memory, except for some particular cases DWORD tymed = pformatetc->tymed; if ( (format == wxDF_BITMAP && !(tymed & TYMED_GDI)) && !(tymed & TYMED_HGLOBAL) ) { // it's not what we're waiting for wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: %s != %s"), GetTymedName(tymed), GetTymedName(format == wxDF_BITMAP ? TYMED_GDI : TYMED_HGLOBAL)); return DV_E_TYMED; } return S_OK;}STDMETHODIMP wxIDataObject::GetCanonicalFormatEtc(FORMATETC *WXUNUSED(pFormatetcIn), FORMATETC *pFormatetcOut){ wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::GetCanonicalFormatEtc")); // TODO we might want something better than this trivial implementation here if ( pFormatetcOut != NULL ) pFormatetcOut->ptd = NULL; return DATA_S_SAMEFORMATETC;}STDMETHODIMP wxIDataObject::EnumFormatEtc(DWORD dwDir, IEnumFORMATETC **ppenumFormatEtc){ wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::EnumFormatEtc")); wxDataObject::Direction dir = dwDir == DATADIR_GET ? wxDataObject::Get : wxDataObject::Set; ULONG nFormatCount = wx_truncate_cast(ULONG, m_pDataObject->GetFormatCount(dir)); wxDataFormat format; wxDataFormat *formats; formats = nFormatCount == 1 ? &format : new wxDataFormat[nFormatCount]; m_pDataObject->GetAllFormats(formats, dir); wxIEnumFORMATETC *pEnum = new wxIEnumFORMATETC(formats, nFormatCount); pEnum->AddRef(); *ppenumFormatEtc = pEnum; if ( formats != &format ) { delete [] formats; } return S_OK;}// ----------------------------------------------------------------------------// advise sink functions (not implemented)// ----------------------------------------------------------------------------STDMETHODIMP wxIDataObject::DAdvise(FORMATETC *WXUNUSED(pformatetc), DWORD WXUNUSED(advf), IAdviseSink *WXUNUSED(pAdvSink), DWORD *WXUNUSED(pdwConnection)){ return OLE_E_ADVISENOTSUPPORTED;}STDMETHODIMP wxIDataObject::DUnadvise(DWORD WXUNUSED(dwConnection)){ return OLE_E_ADVISENOTSUPPORTED;}STDMETHODIMP wxIDataObject::EnumDAdvise(IEnumSTATDATA **WXUNUSED(ppenumAdvise)){ return OLE_E_ADVISENOTSUPPORTED;}// ----------------------------------------------------------------------------// wxDataObject// ----------------------------------------------------------------------------wxDataObject::wxDataObject(){ m_pIDataObject = new wxIDataObject(this); m_pIDataObject->AddRef();}wxDataObject::~wxDataObject(){ ReleaseInterface(m_pIDataObject);}void wxDataObject::SetAutoDelete(){ ((wxIDataObject *)m_pIDataObject)->SetDeleteFlag(); m_pIDataObject->Release(); // so that the dtor doesnt' crash m_pIDataObject = NULL;}size_t wxDataObject::GetBufferOffset(const wxDataFormat& format ){ // if we prepend the size of the data to the buffer itself, account for it return NeedsVerbatimData(format) ? 0 : sizeof(size_t);}const void* wxDataObject::GetSizeFromBuffer( const void* buffer, size_t* size, const wxDataFormat& format ){ // hack: the third parameter is declared non-const in Wine's headers so // cast away the const size_t realsz = ::HeapSize(::GetProcessHeap(), 0, wx_const_cast(void*, buffer)); if ( realsz == (size_t)-1 ) { // note that HeapSize() does not set last error wxLogApiError(wxT("HeapSize"), 0); return NULL; } *size = realsz; // check if this data has its size prepended (as it was by default for wx // programs prior 2.6.3): size_t *p = (size_t *)buffer; if ( *p == realsz ) { if ( NeedsVerbatimData(format) ) wxLogDebug(wxT("Apparent data format mismatch: size not needed")); p++; // this data has its size prepended; skip first DWORD } return p;}void* wxDataObject::SetSizeInBuffer( void* buffer, size_t size, const wxDataFormat& format ){ size_t* p = (size_t *)buffer; if ( !NeedsVerbatimData(format) ) { // prepend the size to the data and skip it *p++ = size; } return p;}#ifdef __WXDEBUG__const wxChar *wxDataObject::GetFormatName(wxDataFormat format){ // case 'xxx' is not a valid value for switch of enum 'wxDataFormat' #ifdef __VISUALC__ #pragma warning(disable:4063) #endif // VC++ static wxChar s_szBuf[256]; switch ( format ) { case CF_TEXT: return wxT("CF_TEXT"); case CF_BITMAP: return wxT("CF_BITMAP"); case CF_SYLK: return wxT("CF_SYLK"); case CF_DIF: return wxT("CF_DIF"); case CF_TIFF: return wxT("CF_TIFF"); case CF_OEMTEXT: return wxT("CF_OEMTEXT"); case CF_DIB: return wxT("CF_DIB"); case CF_PALETTE: return wxT("CF_PALETTE"); case CF_PENDATA: return wxT("CF_PENDATA"); case CF_RIFF: return wxT("CF_RIFF"); case CF_WAVE: return wxT("CF_WAVE"); case CF_UNICODETEXT: return wxT("CF_UNICODETEXT");#ifndef __WXWINCE__ case CF_METAFILEPICT: return wxT("CF_METAFILEPICT"); case CF_ENHMETAFILE: return wxT("CF_ENHMETAFILE"); case CF_LOCALE: return wxT("CF_LOCALE"); case CF_HDROP: return wxT("CF_HDROP");#endif default: if ( !::GetClipboardFormatName(format, s_szBuf, WXSIZEOF(s_szBuf)) ) { // it must be a new predefined format we don't know the name of wxSprintf(s_szBuf, wxT("unknown CF (0x%04x)"), format.GetFormatId()); } return s_szBuf; } #ifdef __VISUALC__ #pragma warning(default:4063) #endif // VC++}#endif // Debug// ----------------------------------------------------------------------------// wxBitmapDataObject supports CF_DIB format// ----------------------------------------------------------------------------// TODO: support CF_DIB under Windows CE as wellsize_t wxBitmapDataObject::GetDataSize() const{#if wxUSE_WXDIB && !defined(__WXWINCE__) return wxDIB::ConvertFromBitmap(NULL, GetHbitmapOf(GetBitmap()));#else return 0;#endif}bool wxBitmapDataObject::GetDataHere(void *buf) const{#if wxUSE_WXDIB && !defined(__WXWINCE__) BITMAPINFO * const pbi = (BITMAPINFO *)buf; return wxDIB::ConvertFromBitmap(pbi, GetHbitmapOf(GetBitmap())) != 0;#else wxUnusedVar(buf); return false;#endif}bool wxBitmapDataObject::SetData(size_t WXUNUSED(len), const void *buf){#if wxUSE_WXDIB && !defined(__WXWINCE__) const BITMAPINFO * const pbmi = (const BITMAPINFO *)buf; HBITMAP hbmp = wxDIB::ConvertToBitmap(pbmi); wxCHECK_MSG( hbmp, FALSE, wxT("pasting/dropping invalid bitmap") ); const BITMAPINFOHEADER * const pbmih = &pbmi->bmiHeader; wxBitmap bitmap(pbmih->biWidth, pbmih->biHeight, pbmih->biBitCount); bitmap.SetHBITMAP((WXHBITMAP)hbmp); // TODO: create wxPalette if the bitmap has any SetBitmap(bitmap); return true;#else wxUnusedVar(buf); return false;#endif}// ----------------------------------------------------------------------------// wxBitmapDataObject2 supports CF_BITMAP format// ----------------------------------------------------------------------------// the bitmaps aren't passed by value as other types of data (i.e. by copying// the data into a global memory chunk and passing it to the clipboard or// another application or whatever), but by handle, so these generic functions// don't make much sense to them.size_t wxBitmapDataObject2::GetDataSize() const{ return 0;}bool wxBitmapDataObject2::GetDataHere(void *pBuf) const{ // we put a bitmap handle into pBuf *(WXHBITMAP *)pBuf = GetBitmap().GetHBITMAP(); return true;}bool wxBitmapDataObject2::SetData(size_t WXUNUSED(len), const void *pBuf){ HBITMAP hbmp = *(HBITMAP *)pBuf; BITMAP bmp; if ( !GetObject(hbmp, sizeof(BITMAP), &bmp) ) { wxLogLastError(wxT("GetObject(HBITMAP)")); } wxBitmap bitmap(bmp.bmWidth, bmp.bmHeight, bmp.bmPlanes); bitmap.SetHBITMAP((WXHBITMAP)hbmp); if ( !bitmap.Ok() ) { wxFAIL_MSG(wxT("pasting/dropping invalid bitmap")); return false; } SetBitmap(bitmap); return true;}#if 0size_t wxBitmapDataObject::GetDataSize(const wxDataFormat& format) const{ if ( format.GetFormatId() == CF_DIB ) { // create the DIB ScreenHDC hdc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -