⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dataobj.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:

        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:
                        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 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& 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 )
{
    size_t realsz = ::HeapSize(::GetProcessHeap(), 0, 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 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -