dataobject.cpp 7.78 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
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

27 28 29 30 31 32 33
#include "plugin.h"
#include "dataobject.h"

#include "utils.h"

using namespace std;

34
//////////////////////////////////////////////////////////////////////////////
35 36

static const FORMATETC _metaFileFormatEtc =
37 38 39 40 41 42 43
{
    CF_METAFILEPICT,
    NULL,
    DVASPECT_CONTENT,
    -1,
    TYMED_MFPICT,
};
44
static const FORMATETC _enhMetaFileFormatEtc =
45 46 47 48 49 50 51
{
    CF_ENHMETAFILE,
    NULL,
    DVASPECT_CONTENT,
    -1,
    TYMED_ENHMF,
};
52

53 54 55 56
using VLCEnumFORMATETC = VLCEnumIterator<IID_IEnumFORMATETC,
                            IEnumFORMATETC,
                            FORMATETC,
                            std::vector<FORMATETC>>;
57

58
//////////////////////////////////////////////////////////////////////////////
59

60 61 62 63 64 65 66 67 68 69 70 71
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();
};

72
//////////////////////////////////////////////////////////////////////////////
73

74 75
STDMETHODIMP VLCDataObject::DAdvise(LPFORMATETC pFormatEtc, DWORD padvf,
                              LPADVISESINK pAdviseSink, LPDWORD pdwConnection)
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
{
    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);
};

91
STDMETHODIMP VLCDataObject::EnumFormatEtc(DWORD,
92
                                          IEnumFORMATETC **ppEnum)
93
{
94
    if( NULL == ppEnum )
95 96
        return E_POINTER;

97
    *ppEnum = new VLCEnumFORMATETC(_v_formatEtc);
98 99

    return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
100 101
};

102 103
STDMETHODIMP VLCDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatEtcIn,
                                                  LPFORMATETC pFormatEtcOut)
104 105 106 107 108 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
{
    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;
};

147
STDMETHODIMP VLCDataObject::GetDataHere(LPFORMATETC,
148
                                        LPSTGMEDIUM pMedium)
149 150 151 152 153 154 155
{
    if( NULL == pMedium )
        return E_POINTER;

    return E_NOTIMPL;
}

156
//////////////////////////////////////////////////////////////////////////////
157

158 159
HRESULT VLCDataObject::getMetaFileData(LPFORMATETC pFormatEtc,
                                       LPSTGMEDIUM pMedium)
160 161 162 163 164
{
    HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
    if( NULL == hicTargetDev )
        return E_FAIL;

165
    HDC hdcMeta = CreateMetaFile(NULL);
166 167
    if( NULL != hdcMeta )
    {
168 169
        LPMETAFILEPICT pMetaFilePict =
                         (LPMETAFILEPICT)CoTaskMemAlloc(sizeof(METAFILEPICT));
170 171 172 173 174 175 176 177 178
        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;

179 180
            DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);

181
            SetMapMode(hdcMeta, MM_ANISOTROPIC);
182
            SetWindowExtEx(hdcMeta, size.cx, size.cy, NULL);
183

184
            RECTL bounds = { 0L, 0L, size.cx, size.cy };
185

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

199 200
HRESULT VLCDataObject::getEnhMetaFileData(LPFORMATETC pFormatEtc,
                                          LPSTGMEDIUM pMedium)
201 202 203 204 205 206 207
{
    HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
    if( NULL == hicTargetDev )
        return E_FAIL;

    SIZEL size = _p_instance->getExtent();

208
    HDC hdcMeta = CreateEnhMetaFile(hicTargetDev, NULL, NULL, NULL);
209 210 211 212
    if( NULL != hdcMeta )
    {
        RECTL wBounds = { 0L, 0L, size.cx, size.cy };

213
        DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);
214

215
        RECTL bounds = { 0L, 0L, size.cx, size.cy };
216

217 218
        _p_instance->onDraw(pFormatEtc->ptd, hicTargetDev,
                            hdcMeta, &bounds, &wBounds);
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
        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;
    }
244

245 246 247 248 249 250 251 252 253 254 255 256
    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;
};

257 258
STDMETHODIMP VLCDataObject::SetData(LPFORMATETC,
                                    LPSTGMEDIUM, BOOL)
259 260 261 262
{
    return E_NOTIMPL;
};

263 264 265 266 267
/*void VLCDataObject::onDataChange(void)
{
    _p_adviseHolder->SendOnDataChange(this, 0, 0);
};*/

268 269 270 271 272 273 274
void VLCDataObject::onClose(void)
{
    _p_adviseHolder->SendOnDataChange(this, 0, ADVF_DATAONSTOP);
    if( S_OK == OleIsCurrentClipboard(dynamic_cast<LPDATAOBJECT>(this)) )
        OleFlushClipboard();
};