dataobject.cpp 7.93 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*****************************************************************************
 * viewobject.cpp: ActiveX control for VLC
 *****************************************************************************
 * Copyright (C) 2005 VideoLAN
 *
 * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
18 19 20
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 22 23 24 25 26 27 28 29
 *****************************************************************************/

#include "plugin.h"
#include "dataobject.h"

#include "utils.h"

using namespace std;

30
//////////////////////////////////////////////////////////////////////////////
31 32

static const FORMATETC _metaFileFormatEtc =
33 34 35 36 37 38 39
{
    CF_METAFILEPICT,
    NULL,
    DVASPECT_CONTENT,
    -1,
    TYMED_MFPICT,
};
40
static const FORMATETC _enhMetaFileFormatEtc =
41 42 43 44 45 46 47
{
    CF_ENHMETAFILE,
    NULL,
    DVASPECT_CONTENT,
    -1,
    TYMED_ENHMF,
};
48

49 50 51 52 53 54 55 56 57 58 59 60 61 62
class VLCEnumFORMATETC : public VLCEnumIterator<IID_IEnumFORMATETC,
    IEnumFORMATETC,
    FORMATETC,
    vector<FORMATETC>::iterator>
{
public:
    VLCEnumFORMATETC(vector<FORMATETC> v) :
        VLCEnumIterator<IID_IEnumFORMATETC,
        IEnumFORMATETC,
        FORMATETC,
        vector<FORMATETC>::iterator>(v.begin(), v.end())
    {};
};

63
//////////////////////////////////////////////////////////////////////////////
64

65 66 67 68 69 70 71 72 73 74 75 76
VLCDataObject::VLCDataObject(VLCPlugin *p_instance) : _p_instance(p_instance)
{
    _v_formatEtc.push_back(_enhMetaFileFormatEtc);
    _v_formatEtc.push_back(_metaFileFormatEtc);
    CreateDataAdviseHolder(&_p_adviseHolder);
};

VLCDataObject::~VLCDataObject()
{
    _p_adviseHolder->Release();
};

77
//////////////////////////////////////////////////////////////////////////////
78

79 80
STDMETHODIMP VLCDataObject::DAdvise(LPFORMATETC pFormatEtc, DWORD padvf,
                              LPADVISESINK pAdviseSink, LPDWORD pdwConnection)
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
{
    return _p_adviseHolder->Advise(this,
            pFormatEtc, padvf,pAdviseSink, pdwConnection);
};

STDMETHODIMP VLCDataObject::DUnadvise(DWORD dwConnection)
{
    return _p_adviseHolder->Unadvise(dwConnection);
};

STDMETHODIMP VLCDataObject::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
{
    return _p_adviseHolder->EnumAdvise(ppenumAdvise);
};

96 97
STDMETHODIMP VLCDataObject::EnumFormatEtc(DWORD dwDirection,
                                          IEnumFORMATETC **ppEnum)
98
{
99
    if( NULL == ppEnum )
100 101
        return E_POINTER;

102
    *ppEnum = new VLCEnumFORMATETC(_v_formatEtc);
103 104

    return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
105 106
};

107 108
STDMETHODIMP VLCDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatEtcIn,
                                                  LPFORMATETC pFormatEtcOut)
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
{
    HRESULT result = QueryGetData(pFormatEtcIn);
    if( FAILED(result) )
        return result;

    if( NULL == pFormatEtcOut )
        return E_POINTER;

    *pFormatEtcOut = *pFormatEtcIn;
    pFormatEtcOut->ptd = NULL;

    return DATA_S_SAMEFORMATETC;
};

STDMETHODIMP VLCDataObject::GetData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
{
    if( NULL == pMedium )
        return E_POINTER;

    HRESULT result = QueryGetData(pFormatEtc);
    if( SUCCEEDED(result) )
    {
        switch( pFormatEtc->cfFormat )
        {
            case CF_METAFILEPICT:
                pMedium->tymed = TYMED_MFPICT;
                pMedium->hMetaFilePict = NULL;
                pMedium->pUnkForRelease = NULL;
                result = getMetaFileData(pFormatEtc, pMedium);
                break;
            case CF_ENHMETAFILE:
                pMedium->tymed = TYMED_ENHMF;
                pMedium->hEnhMetaFile = NULL;
                pMedium->pUnkForRelease = NULL;
                result = getEnhMetaFileData(pFormatEtc, pMedium);
                break;
            default:
                result = DV_E_FORMATETC;
        }
    }
    return result;
};

152 153
STDMETHODIMP VLCDataObject::GetDataHere(LPFORMATETC pFormatEtc,
                                        LPSTGMEDIUM pMedium)
154 155 156 157 158 159 160
{
    if( NULL == pMedium )
        return E_POINTER;

    return E_NOTIMPL;
}

161
//////////////////////////////////////////////////////////////////////////////
162

163 164
HRESULT VLCDataObject::getMetaFileData(LPFORMATETC pFormatEtc,
                                       LPSTGMEDIUM pMedium)
165 166 167 168 169
{
    HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
    if( NULL == hicTargetDev )
        return E_FAIL;

170
    HDC hdcMeta = CreateMetaFile(NULL);
171 172
    if( NULL != hdcMeta )
    {
173 174
        LPMETAFILEPICT pMetaFilePict =
                         (LPMETAFILEPICT)CoTaskMemAlloc(sizeof(METAFILEPICT));
175 176 177 178 179 180 181 182 183
        if( NULL != pMetaFilePict )
        {
            SIZEL size = _p_instance->getExtent();
            RECTL wBounds = { 0L, 0L, size.cx, size.cy };

            pMetaFilePict->mm   = MM_ANISOTROPIC;
            pMetaFilePict->xExt = size.cx;
            pMetaFilePict->yExt = size.cy;

184 185
            DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);

186
            SetMapMode(hdcMeta, MM_ANISOTROPIC);
187
            SetWindowExtEx(hdcMeta, size.cx, size.cy, NULL);
188

189
            RECTL bounds = { 0L, 0L, size.cx, size.cy };
190

191 192
            _p_instance->onDraw(pFormatEtc->ptd, hicTargetDev, hdcMeta,
                                &bounds, &wBounds);
193 194 195 196 197 198 199 200 201 202 203
            pMetaFilePict->hMF = CloseMetaFile(hdcMeta);
            if( NULL != pMetaFilePict->hMF )
                pMedium->hMetaFilePict = pMetaFilePict;
            else
                CoTaskMemFree(pMetaFilePict);
        }
    }
    DeleteDC(hicTargetDev);
    return (NULL != pMedium->hMetaFilePict) ? S_OK : E_FAIL;
};

204 205
HRESULT VLCDataObject::getEnhMetaFileData(LPFORMATETC pFormatEtc,
                                          LPSTGMEDIUM pMedium)
206 207 208 209 210 211 212
{
    HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
    if( NULL == hicTargetDev )
        return E_FAIL;

    SIZEL size = _p_instance->getExtent();

213
    HDC hdcMeta = CreateEnhMetaFile(hicTargetDev, NULL, NULL, NULL);
214 215 216 217
    if( NULL != hdcMeta )
    {
        RECTL wBounds = { 0L, 0L, size.cx, size.cy };

218
        DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);
219

220
        RECTL bounds = { 0L, 0L, size.cx, size.cy };
221

222 223
        _p_instance->onDraw(pFormatEtc->ptd, hicTargetDev,
                            hdcMeta, &bounds, &wBounds);
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
        pMedium->hEnhMetaFile = CloseEnhMetaFile(hdcMeta);
    }
    DeleteDC(hicTargetDev);

    return (NULL != pMedium->hEnhMetaFile) ? S_OK : E_FAIL;
};

STDMETHODIMP VLCDataObject::QueryGetData(LPFORMATETC pFormatEtc)
{
    if( NULL == pFormatEtc )
        return E_POINTER;

    const FORMATETC *formatEtc;

    switch( pFormatEtc->cfFormat )
    {
        case CF_METAFILEPICT:
            formatEtc = &_metaFileFormatEtc;
            break;
        case CF_ENHMETAFILE:
            formatEtc = &_enhMetaFileFormatEtc;
            break;
        default:
            return DV_E_FORMATETC;
    }
249
 
250 251 252 253 254 255 256 257 258 259 260 261
    if( pFormatEtc->dwAspect != formatEtc->dwAspect )
        return DV_E_DVASPECT;

    if( pFormatEtc->lindex != formatEtc->lindex )
        return DV_E_LINDEX;

    if( pFormatEtc->tymed != formatEtc->tymed )
        return DV_E_TYMED;

    return S_OK;
};

262 263
STDMETHODIMP VLCDataObject::SetData(LPFORMATETC pFormatEtc,
                                    LPSTGMEDIUM pMedium, BOOL fRelease)
264 265 266 267
{
    return E_NOTIMPL;
};

268 269 270 271 272
/*void VLCDataObject::onDataChange(void)
{
    _p_adviseHolder->SendOnDataChange(this, 0, 0);
};*/

273 274 275 276 277 278 279
void VLCDataObject::onClose(void)
{
    _p_adviseHolder->SendOnDataChange(this, 0, ADVF_DATAONSTOP);
    if( S_OK == OleIsCurrentClipboard(dynamic_cast<LPDATAOBJECT>(this)) )
        OleFlushClipboard();
};