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
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
24 #include "dataobject.h"
30 ////////////////////////////////////////////////////////////////////////////////////////////////
32 class VLCEnumFORMATETC : public IEnumFORMATETC
36 VLCEnumFORMATETC(vector<FORMATETC> &v) :
37 e(VLCEnum<FORMATETC>(IID_IEnumFORMATETC, v)) {};
39 VLCEnumFORMATETC(const VLCEnumFORMATETC &vlcEnum) : e(vlcEnum.e) {};
40 virtual ~VLCEnumFORMATETC() {};
43 STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
44 { return e.QueryInterface(riid, ppv); };
45 STDMETHODIMP_(ULONG) AddRef(void)
46 { return e.AddRef(); };
47 STDMETHODIMP_(ULONG) Release(void)
48 {return e.Release(); };
50 //IEnumConnectionPoints
51 STDMETHODIMP Next(ULONG celt, LPFORMATETC rgelt, ULONG *pceltFetched)
52 { return e.Next(celt, rgelt, pceltFetched); };
53 STDMETHODIMP Skip(ULONG celt)
54 { return e.Skip(celt);};
55 STDMETHODIMP Reset(void)
57 STDMETHODIMP Clone(LPENUMFORMATETC *ppenum)
58 { if( NULL == ppenum ) return E_POINTER;
59 *ppenum = dynamic_cast<LPENUMFORMATETC>(new VLCEnumFORMATETC(*this));
60 return (NULL != *ppenum) ? S_OK : E_OUTOFMEMORY;
68 ////////////////////////////////////////////////////////////////////////////////////////////////
70 static const FORMATETC _metaFileFormatEtc =
78 static const FORMATETC _enhMetaFileFormatEtc =
87 VLCDataObject::VLCDataObject(VLCPlugin *p_instance) : _p_instance(p_instance)
89 _v_formatEtc.push_back(_enhMetaFileFormatEtc);
90 _v_formatEtc.push_back(_metaFileFormatEtc);
91 CreateDataAdviseHolder(&_p_adviseHolder);
94 VLCDataObject::~VLCDataObject()
96 _p_adviseHolder->Release();
99 ////////////////////////////////////////////////////////////////////////////////////////////////
101 STDMETHODIMP VLCDataObject::DAdvise(LPFORMATETC pFormatEtc, DWORD padvf, LPADVISESINK pAdviseSink, LPDWORD pdwConnection)
103 return _p_adviseHolder->Advise(this,
104 pFormatEtc, padvf,pAdviseSink, pdwConnection);
107 STDMETHODIMP VLCDataObject::DUnadvise(DWORD dwConnection)
109 return _p_adviseHolder->Unadvise(dwConnection);
112 STDMETHODIMP VLCDataObject::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
114 return _p_adviseHolder->EnumAdvise(ppenumAdvise);
117 STDMETHODIMP VLCDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumformatetc)
119 if( NULL == ppenumformatetc )
122 *ppenumformatetc = new VLCEnumFORMATETC(_v_formatEtc);
126 STDMETHODIMP VLCDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatEtcIn, LPFORMATETC pFormatEtcOut)
128 HRESULT result = QueryGetData(pFormatEtcIn);
132 if( NULL == pFormatEtcOut )
135 *pFormatEtcOut = *pFormatEtcIn;
136 pFormatEtcOut->ptd = NULL;
138 return DATA_S_SAMEFORMATETC;
141 STDMETHODIMP VLCDataObject::GetData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
143 if( NULL == pMedium )
146 HRESULT result = QueryGetData(pFormatEtc);
147 if( SUCCEEDED(result) )
149 switch( pFormatEtc->cfFormat )
151 case CF_METAFILEPICT:
152 pMedium->tymed = TYMED_MFPICT;
153 pMedium->hMetaFilePict = NULL;
154 pMedium->pUnkForRelease = NULL;
155 result = getMetaFileData(pFormatEtc, pMedium);
158 pMedium->tymed = TYMED_ENHMF;
159 pMedium->hEnhMetaFile = NULL;
160 pMedium->pUnkForRelease = NULL;
161 result = getEnhMetaFileData(pFormatEtc, pMedium);
164 result = DV_E_FORMATETC;
170 STDMETHODIMP VLCDataObject::GetDataHere(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
172 if( NULL == pMedium )
178 ////////////////////////////////////////////////////////////////////////////////////////////////
180 HRESULT VLCDataObject::getMetaFileData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
182 HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
183 if( NULL == hicTargetDev )
186 HDC hdcMeta = CreateMetaFile(NULL);
187 if( NULL != hdcMeta )
189 LPMETAFILEPICT pMetaFilePict = (LPMETAFILEPICT)CoTaskMemAlloc(sizeof(METAFILEPICT));
190 if( NULL != pMetaFilePict )
192 SIZEL size = _p_instance->getExtent();
193 RECTL wBounds = { 0L, 0L, size.cx, size.cy };
195 pMetaFilePict->mm = MM_ANISOTROPIC;
196 pMetaFilePict->xExt = size.cx;
197 pMetaFilePict->yExt = size.cy;
199 DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);
201 SetMapMode(hdcMeta, MM_ANISOTROPIC);
202 SetWindowExtEx(hdcMeta, size.cx, size.cy, NULL);
204 RECTL bounds = { 0L, 0L, size.cx, size.cy };
206 _p_instance->onDraw(pFormatEtc->ptd, hicTargetDev, hdcMeta, &bounds, &wBounds);
207 pMetaFilePict->hMF = CloseMetaFile(hdcMeta);
208 if( NULL != pMetaFilePict->hMF )
209 pMedium->hMetaFilePict = pMetaFilePict;
211 CoTaskMemFree(pMetaFilePict);
214 DeleteDC(hicTargetDev);
215 return (NULL != pMedium->hMetaFilePict) ? S_OK : E_FAIL;
218 HRESULT VLCDataObject::getEnhMetaFileData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
220 HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
221 if( NULL == hicTargetDev )
224 SIZEL size = _p_instance->getExtent();
226 HDC hdcMeta = CreateEnhMetaFile(hicTargetDev, NULL, NULL, NULL);
227 if( NULL != hdcMeta )
229 RECTL wBounds = { 0L, 0L, size.cx, size.cy };
231 DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);
233 RECTL bounds = { 0L, 0L, size.cx, size.cy };
235 _p_instance->onDraw(pFormatEtc->ptd, hicTargetDev, hdcMeta, &bounds, &wBounds);
236 pMedium->hEnhMetaFile = CloseEnhMetaFile(hdcMeta);
238 DeleteDC(hicTargetDev);
240 return (NULL != pMedium->hEnhMetaFile) ? S_OK : E_FAIL;
243 STDMETHODIMP VLCDataObject::QueryGetData(LPFORMATETC pFormatEtc)
245 if( NULL == pFormatEtc )
248 const FORMATETC *formatEtc;
250 switch( pFormatEtc->cfFormat )
252 case CF_METAFILEPICT:
253 formatEtc = &_metaFileFormatEtc;
256 formatEtc = &_enhMetaFileFormatEtc;
259 return DV_E_FORMATETC;
262 if( pFormatEtc->dwAspect != formatEtc->dwAspect )
263 return DV_E_DVASPECT;
265 if( pFormatEtc->lindex != formatEtc->lindex )
268 if( pFormatEtc->tymed != formatEtc->tymed )
274 STDMETHODIMP VLCDataObject::SetData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium, BOOL fRelease)
279 /*void VLCDataObject::onDataChange(void)
281 _p_adviseHolder->SendOnDataChange(this, 0, 0);
284 void VLCDataObject::onClose(void)
286 _p_adviseHolder->SendOnDataChange(this, 0, ADVF_DATAONSTOP);
287 if( S_OK == OleIsCurrentClipboard(dynamic_cast<LPDATAOBJECT>(this)) )