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

📄 dataobj.cpp

📁 很牛的GUI源码wxWidgets-2.8.0.zip 可在多种平台下运行.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
///////////////////////////////////////////////////////////////////////////////// Name:        msw/ole/dataobj.cpp// Purpose:     implementation of wx[I]DataObject class// Author:      Vadim Zeitlin// Modified by:// Created:     10.05.98// RCS-ID:      $Id: dataobj.cpp,v 1.98 2006/11/12 15:54:06 JS Exp $// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>// Licence:     wxWindows licence///////////////////////////////////////////////////////////////////////////////// ============================================================================// declarations// ============================================================================// ----------------------------------------------------------------------------// headers// ----------------------------------------------------------------------------// For compilers that support precompilation, includes "wx.h".#include "wx/wxprec.h"#if defined(__BORLANDC__)    #pragma hdrstop#endif#ifndef WX_PRECOMP    #include "wx/intl.h"    #include "wx/log.h"    #include "wx/utils.h"#endif#include "wx/dataobj.h"#if wxUSE_OLE && defined(__WIN32__) && !defined(__GNUWIN32_OLD__)#include "wx/msw/private.h"         // includes <windows.h>#ifdef __WXWINCE__#include <winreg.h>#endif// for some compilers, the entire ole2.h must be included, not only oleauto.h#if wxUSE_NORLANDER_HEADERS || defined(__WATCOMC__) || defined(__WXWINCE__)  #include <ole2.h>#endif#include <oleauto.h>#include <shlobj.h>#include "wx/msw/ole/oleutils.h"#include "wx/msw/dib.h"#ifndef CFSTR_SHELLURL#define CFSTR_SHELLURL _T("UniformResourceLocator")#endif// ----------------------------------------------------------------------------// functions// ----------------------------------------------------------------------------#ifdef __WXDEBUG__    static const wxChar *GetTymedName(DWORD tymed);#else // !Debug    #define GetTymedName(tymed) wxEmptyString#endif // Debug/!Debug// ----------------------------------------------------------------------------// wxIEnumFORMATETC interface implementation// ----------------------------------------------------------------------------class wxIEnumFORMATETC : public IEnumFORMATETC{public:    wxIEnumFORMATETC(const wxDataFormat* formats, ULONG nCount);    virtual ~wxIEnumFORMATETC() { delete [] m_formats; }    // IEnumFORMATETC    STDMETHODIMP Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched);    STDMETHODIMP Skip(ULONG celt);    STDMETHODIMP Reset();    STDMETHODIMP Clone(IEnumFORMATETC **ppenum);    DECLARE_IUNKNOWN_METHODS;private:    CLIPFORMAT *m_formats;  // formats we can provide data in    ULONG       m_nCount,   // number of formats we support                m_nCurrent; // current enum position    DECLARE_NO_COPY_CLASS(wxIEnumFORMATETC)};// ----------------------------------------------------------------------------// wxIDataObject implementation of IDataObject interface// ----------------------------------------------------------------------------class wxIDataObject : public IDataObject{public:    wxIDataObject(wxDataObject *pDataObject);    virtual ~wxIDataObject();    // normally, wxDataObject controls our lifetime (i.e. we're deleted when it    // is), but in some cases, the situation is reversed, that is we delete it    // when this object is deleted - setting this flag enables such logic    void SetDeleteFlag() { m_mustDelete = true; }    // IDataObject    STDMETHODIMP GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium);    STDMETHODIMP GetDataHere(FORMATETC *pformatetc, STGMEDIUM *pmedium);    STDMETHODIMP QueryGetData(FORMATETC *pformatetc);    STDMETHODIMP GetCanonicalFormatEtc(FORMATETC *In, FORMATETC *pOut);    STDMETHODIMP SetData(FORMATETC *pfetc, STGMEDIUM *pmedium, BOOL fRelease);    STDMETHODIMP EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFEtc);    STDMETHODIMP DAdvise(FORMATETC *pfetc, DWORD ad, IAdviseSink *p, DWORD *pdw);    STDMETHODIMP DUnadvise(DWORD dwConnection);    STDMETHODIMP EnumDAdvise(IEnumSTATDATA **ppenumAdvise);    DECLARE_IUNKNOWN_METHODS;private:    wxDataObject *m_pDataObject;      // pointer to C++ class we belong to    bool m_mustDelete;    DECLARE_NO_COPY_CLASS(wxIDataObject)};// ============================================================================// implementation// ============================================================================// ----------------------------------------------------------------------------// wxDataFormat// ----------------------------------------------------------------------------void wxDataFormat::SetId(const wxChar *format){    m_format = (wxDataFormat::NativeFormat)::RegisterClipboardFormat(format);    if ( !m_format )    {        wxLogError(_("Couldn't register clipboard format '%s'."), format);    }}wxString wxDataFormat::GetId() const{    static const int max = 256;    wxString s;    wxCHECK_MSG( !IsStandard(), s,                 wxT("name of predefined format cannot be retrieved") );    int len = ::GetClipboardFormatName(m_format, wxStringBuffer(s, max), max);    if ( !len )    {        wxLogError(_("The clipboard format '%d' doesn't exist."), m_format);    }    return s;}// ----------------------------------------------------------------------------// wxIEnumFORMATETC// ----------------------------------------------------------------------------BEGIN_IID_TABLE(wxIEnumFORMATETC)    ADD_IID(Unknown)    ADD_IID(EnumFORMATETC)END_IID_TABLE;IMPLEMENT_IUNKNOWN_METHODS(wxIEnumFORMATETC)wxIEnumFORMATETC::wxIEnumFORMATETC(const wxDataFormat *formats, ULONG nCount){    m_nCurrent = 0;    m_nCount = nCount;    m_formats = new CLIPFORMAT[nCount];    for ( ULONG n = 0; n < nCount; n++ ) {        m_formats[n] = formats[n].GetFormatId();    }}STDMETHODIMP wxIEnumFORMATETC::Next(ULONG      celt,                                    FORMATETC *rgelt,                                    ULONG     *pceltFetched){    wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumFORMATETC::Next"));    ULONG numFetched = 0;    while (m_nCurrent < m_nCount && numFetched < celt) {        FORMATETC format;        format.cfFormat = m_formats[m_nCurrent++];        format.ptd      = NULL;        format.dwAspect = DVASPECT_CONTENT;        format.lindex   = -1;        format.tymed    = TYMED_HGLOBAL;        *rgelt++ = format;        numFetched++;    }    if (pceltFetched)        *pceltFetched = numFetched;    return numFetched == celt ? S_OK : S_FALSE;}STDMETHODIMP wxIEnumFORMATETC::Skip(ULONG celt){    wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumFORMATETC::Skip"));    m_nCurrent += celt;    if ( m_nCurrent < m_nCount )        return S_OK;    // no, can't skip this many elements    m_nCurrent -= celt;    return S_FALSE;}STDMETHODIMP wxIEnumFORMATETC::Reset(){    wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumFORMATETC::Reset"));    m_nCurrent = 0;    return S_OK;}STDMETHODIMP wxIEnumFORMATETC::Clone(IEnumFORMATETC **ppenum){    wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumFORMATETC::Clone"));    // unfortunately, we can't reuse the code in ctor - types are different    wxIEnumFORMATETC *pNew = new wxIEnumFORMATETC(NULL, 0);    pNew->m_nCount = m_nCount;    pNew->m_formats = new CLIPFORMAT[m_nCount];    for ( ULONG n = 0; n < m_nCount; n++ ) {        pNew->m_formats[n] = m_formats[n];    }    pNew->AddRef();    *ppenum = pNew;    return S_OK;}// ----------------------------------------------------------------------------// wxIDataObject// ----------------------------------------------------------------------------BEGIN_IID_TABLE(wxIDataObject)    ADD_IID(Unknown)    ADD_IID(DataObject)END_IID_TABLE;IMPLEMENT_IUNKNOWN_METHODS(wxIDataObject)wxIDataObject::wxIDataObject(wxDataObject *pDataObject){    m_pDataObject = pDataObject;    m_mustDelete = false;}wxIDataObject::~wxIDataObject(){    if ( m_mustDelete )    {        delete m_pDataObject;    }}// get data functionsSTDMETHODIMP 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;    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;}STDMETHODIMP wxIDataObject::GetDataHere(FORMATETC *pformatetc,                                        STGMEDIUM *pmedium){    wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::GetDataHere"));    // put data in caller provided medium    switch ( pmedium->tymed )    {        case TYMED_GDI:            if ( !m_pDataObject->GetDataHere(wxDF_BITMAP, &pmedium->hBitmap) )                return E_UNEXPECTED;            break;        case TYMED_ENHMF:            if ( !m_pDataObject->GetDataHere(wxDF_ENHMETAFILE,                                             &pmedium->hEnhMetaFile) )                return E_UNEXPECTED;            break;        case TYMED_MFPICT:            // fall through - we pass METAFILEPICT through HGLOBAL        case TYMED_HGLOBAL:            {                // copy data                HGLOBAL hGlobal = pmedium->hGlobal;                void *pBuf = GlobalLock(hGlobal);                if ( pBuf == NULL ) {                    wxLogLastError(wxT("GlobalLock"));                    return E_OUTOFMEMORY;                }                wxDataFormat format = pformatetc->cfFormat;                // possibly put the size in the beginning of the buffer                pBuf = m_pDataObject->SetSizeInBuffer                                      (                                        pBuf,                                        ::GlobalSize(hGlobal),                                        format                                      );                if ( !m_pDataObject->GetDataHere(format, pBuf) )                    return E_UNEXPECTED;                GlobalUnlock(hGlobal);            }            break;        default:            return DV_E_TYMED;    }    return S_OK;}// set data functionsSTDMETHODIMP 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_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;

⌨️ 快捷键说明

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