dataobj.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,257 行 · 第 1/3 页
CPP
1,257 行
switch ( pmedium->tymed )
{
case TYMED_GDI:
m_pDataObject->SetData(wxDF_BITMAP, 0, &pmedium->hBitmap);
break;
case TYMED_ENHMF:
m_pDataObject->SetData(wxDF_ENHMETAFILE, 0, &pmedium->hEnhMetaFile);
break;
case TYMED_MFPICT:
// fall through - we pass METAFILEPICT through HGLOBAL
case TYMED_HGLOBAL:
{
wxDataFormat format = pformatetc->cfFormat;
// this is quite weird, but for file drag and drop, explorer
// calls our SetData() with the formats we do *not* support!
//
// as we can't fix this bug in explorer (it's a bug because it
// should only use formats returned by EnumFormatEtc), do the
// check here
if ( !m_pDataObject->IsSupported(format, wxDataObject::Set) ) {
// go away!
return DV_E_FORMATETC;
}
// 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:
{
// we suppose that the size precedes the data
pBuf = m_pDataObject->GetSizeFromBuffer( pBuf, &size, format );
if (! format.IsStandard() ) {
// see GetData for corresponding increment
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 functions
STDMETHODIMP 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& WXUNUSED(format) )
{
return sizeof(size_t);
}
const void* wxDataObject::GetSizeFromBuffer( const void* buffer, size_t* size,
const wxDataFormat& WXUNUSED(format) )
{
size_t* p = (size_t*)buffer;
*size = *p;
return p + 1;
}
void* wxDataObject::SetSizeInBuffer( void* buffer, size_t size,
const wxDataFormat& WXUNUSED(format) )
{
size_t* p = (size_t*)buffer;
*p = size;
return p + 1;
}
#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 well
size_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) )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?