1 /*****************************************************************************
2 * viewobject.cpp: ActiveX control for VLC
3 *****************************************************************************
4 * Copyright (C) 2005 VideoLAN
6 * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
24 #include "dataobject.h"
30 //////////////////////////////////////////////////////////////////////////////
32 static const FORMATETC _metaFileFormatEtc =
40 static const FORMATETC _enhMetaFileFormatEtc =
49 class VLCEnumFORMATETC : public VLCEnumIterator<IID_IEnumFORMATETC,
52 vector<FORMATETC>::iterator>
55 VLCEnumFORMATETC(vector<FORMATETC> v) :
56 VLCEnumIterator<IID_IEnumFORMATETC,
59 vector<FORMATETC>::iterator>(v.begin(), v.end())
63 //////////////////////////////////////////////////////////////////////////////
65 VLCDataObject::VLCDataObject(VLCPlugin *p_instance) : _p_instance(p_instance)
67 _v_formatEtc.push_back(_enhMetaFileFormatEtc);
68 _v_formatEtc.push_back(_metaFileFormatEtc);
69 CreateDataAdviseHolder(&_p_adviseHolder);
72 VLCDataObject::~VLCDataObject()
74 _p_adviseHolder->Release();
77 //////////////////////////////////////////////////////////////////////////////
79 STDMETHODIMP VLCDataObject::DAdvise(LPFORMATETC pFormatEtc, DWORD padvf,
80 LPADVISESINK pAdviseSink, LPDWORD pdwConnection)
82 return _p_adviseHolder->Advise(this,
83 pFormatEtc, padvf,pAdviseSink, pdwConnection);
86 STDMETHODIMP VLCDataObject::DUnadvise(DWORD dwConnection)
88 return _p_adviseHolder->Unadvise(dwConnection);
91 STDMETHODIMP VLCDataObject::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
93 return _p_adviseHolder->EnumAdvise(ppenumAdvise);
96 STDMETHODIMP VLCDataObject::EnumFormatEtc(DWORD dwDirection,
97 IEnumFORMATETC **ppEnum)
102 *ppEnum = new VLCEnumFORMATETC(_v_formatEtc);
104 return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
107 STDMETHODIMP VLCDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatEtcIn,
108 LPFORMATETC pFormatEtcOut)
110 HRESULT result = QueryGetData(pFormatEtcIn);
114 if( NULL == pFormatEtcOut )
117 *pFormatEtcOut = *pFormatEtcIn;
118 pFormatEtcOut->ptd = NULL;
120 return DATA_S_SAMEFORMATETC;
123 STDMETHODIMP VLCDataObject::GetData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
125 if( NULL == pMedium )
128 HRESULT result = QueryGetData(pFormatEtc);
129 if( SUCCEEDED(result) )
131 switch( pFormatEtc->cfFormat )
133 case CF_METAFILEPICT:
134 pMedium->tymed = TYMED_MFPICT;
135 pMedium->hMetaFilePict = NULL;
136 pMedium->pUnkForRelease = NULL;
137 result = getMetaFileData(pFormatEtc, pMedium);
140 pMedium->tymed = TYMED_ENHMF;
141 pMedium->hEnhMetaFile = NULL;
142 pMedium->pUnkForRelease = NULL;
143 result = getEnhMetaFileData(pFormatEtc, pMedium);
146 result = DV_E_FORMATETC;
152 STDMETHODIMP VLCDataObject::GetDataHere(LPFORMATETC pFormatEtc,
155 if( NULL == pMedium )
161 //////////////////////////////////////////////////////////////////////////////
163 HRESULT VLCDataObject::getMetaFileData(LPFORMATETC pFormatEtc,
166 HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
167 if( NULL == hicTargetDev )
170 HDC hdcMeta = CreateMetaFile(NULL);
171 if( NULL != hdcMeta )
173 LPMETAFILEPICT pMetaFilePict =
174 (LPMETAFILEPICT)CoTaskMemAlloc(sizeof(METAFILEPICT));
175 if( NULL != pMetaFilePict )
177 SIZEL size = _p_instance->getExtent();
178 RECTL wBounds = { 0L, 0L, size.cx, size.cy };
180 pMetaFilePict->mm = MM_ANISOTROPIC;
181 pMetaFilePict->xExt = size.cx;
182 pMetaFilePict->yExt = size.cy;
184 DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);
186 SetMapMode(hdcMeta, MM_ANISOTROPIC);
187 SetWindowExtEx(hdcMeta, size.cx, size.cy, NULL);
189 RECTL bounds = { 0L, 0L, size.cx, size.cy };
191 _p_instance->onDraw(pFormatEtc->ptd, hicTargetDev, hdcMeta,
193 pMetaFilePict->hMF = CloseMetaFile(hdcMeta);
194 if( NULL != pMetaFilePict->hMF )
195 pMedium->hMetaFilePict = pMetaFilePict;
197 CoTaskMemFree(pMetaFilePict);
200 DeleteDC(hicTargetDev);
201 return (NULL != pMedium->hMetaFilePict) ? S_OK : E_FAIL;
204 HRESULT VLCDataObject::getEnhMetaFileData(LPFORMATETC pFormatEtc,
207 HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
208 if( NULL == hicTargetDev )
211 SIZEL size = _p_instance->getExtent();
213 HDC hdcMeta = CreateEnhMetaFile(hicTargetDev, NULL, NULL, NULL);
214 if( NULL != hdcMeta )
216 RECTL wBounds = { 0L, 0L, size.cx, size.cy };
218 DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);
220 RECTL bounds = { 0L, 0L, size.cx, size.cy };
222 _p_instance->onDraw(pFormatEtc->ptd, hicTargetDev,
223 hdcMeta, &bounds, &wBounds);
224 pMedium->hEnhMetaFile = CloseEnhMetaFile(hdcMeta);
226 DeleteDC(hicTargetDev);
228 return (NULL != pMedium->hEnhMetaFile) ? S_OK : E_FAIL;
231 STDMETHODIMP VLCDataObject::QueryGetData(LPFORMATETC pFormatEtc)
233 if( NULL == pFormatEtc )
236 const FORMATETC *formatEtc;
238 switch( pFormatEtc->cfFormat )
240 case CF_METAFILEPICT:
241 formatEtc = &_metaFileFormatEtc;
244 formatEtc = &_enhMetaFileFormatEtc;
247 return DV_E_FORMATETC;
250 if( pFormatEtc->dwAspect != formatEtc->dwAspect )
251 return DV_E_DVASPECT;
253 if( pFormatEtc->lindex != formatEtc->lindex )
256 if( pFormatEtc->tymed != formatEtc->tymed )
262 STDMETHODIMP VLCDataObject::SetData(LPFORMATETC pFormatEtc,
263 LPSTGMEDIUM pMedium, BOOL fRelease)
268 /*void VLCDataObject::onDataChange(void)
270 _p_adviseHolder->SendOnDataChange(this, 0, 0);
273 void VLCDataObject::onClose(void)
275 _p_adviseHolder->SendOnDataChange(this, 0, ADVF_DATAONSTOP);
276 if( S_OK == OleIsCurrentClipboard(dynamic_cast<LPDATAOBJECT>(this)) )