示例#1
0
// set data functions
STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
                                    STGMEDIUM *pmedium,
                                    BOOL       fRelease)
{
    wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::SetData"));

    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_ISTREAM:
            // check if this format is supported
            if ( !m_pDataObject->IsSupported(pformatetc->cfFormat,
                                             wxDataObject::Set) )
            {
                // As this is not a supported format (content data), assume it
                // is system data and save it.
                return SaveSystemData(pformatetc, pmedium, fRelease);
            }
            break;

        case TYMED_MFPICT:
            // fall through - we pass METAFILEPICT through HGLOBAL
        case TYMED_HGLOBAL:
            {
                wxDataFormat format = pformatetc->cfFormat;

                format = HtmlFormatFixup(format);

                // check if this format is supported
                if ( !m_pDataObject->IsSupported(format, wxDataObject::Set) ) {
                    // As above, assume that unsupported format must be system
                    // data and just save it.
                    return SaveSystemData(pformatetc, pmedium, fRelease);
                }

                // 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 wxDF_HTML:
                    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) )
                        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;
}
示例#2
0
// get data functions
STDMETHODIMP wxIDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
{
    wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::GetData"));

    // is data is in our format?
    HRESULT hr = QueryGetData(pformatetcIn);
    if ( FAILED(hr) )
        return hr;

    // for the bitmaps and metafiles we use the handles instead of global memory
    // to pass the data
    wxDataFormat format = (wxDataFormat::NativeFormat)pformatetcIn->cfFormat;
    format = HtmlFormatFixup(format);

    // is this system data?
    if ( GetSystemData(format, pmedium) )
    {
        // pmedium is already filled with corresponding data, so we're ready.
        return S_OK;
    }

    switch ( format )
    {
        case wxDF_BITMAP:
            pmedium->tymed = TYMED_GDI;
            break;

        case wxDF_ENHMETAFILE:
            pmedium->tymed = TYMED_ENHMF;
            break;

#ifndef __WXWINCE__
        case wxDF_METAFILE:
            pmedium->hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
                                           sizeof(METAFILEPICT));
            if ( !pmedium->hGlobal ) {
                wxLogLastError(wxT("GlobalAlloc"));
                return E_OUTOFMEMORY;
            }
            pmedium->tymed = TYMED_MFPICT;
            break;
#endif
        default:
            // alloc memory
            size_t size = m_pDataObject->GetDataSize(format);
            if ( !size ) {
                // it probably means that the method is just not implemented
                wxLogDebug(wxT("Invalid data size - can't be 0"));

                return DV_E_FORMATETC;
            }

            // we may need extra space for the buffer size
            size += m_pDataObject->GetBufferOffset( format );

            HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, size);
            if ( hGlobal == NULL ) {
                wxLogLastError(wxT("GlobalAlloc"));
                return E_OUTOFMEMORY;
            }

            // copy data
            pmedium->tymed   = TYMED_HGLOBAL;
            pmedium->hGlobal = hGlobal;
    }

    pmedium->pUnkForRelease = NULL;

    // do copy the data
    hr = GetDataHere(pformatetcIn, pmedium);
    if ( FAILED(hr) ) {
        // free resources we allocated
        if ( pmedium->tymed & (TYMED_HGLOBAL | TYMED_MFPICT) ) {
            GlobalFree(pmedium->hGlobal);
        }

        return hr;
    }

    return S_OK;
}