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 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
, LPADVISESINK pAdviseSink
, LPDWORD pdwConnection
)
81 return _p_adviseHolder
->Advise(this,
82 pFormatEtc
, padvf
,pAdviseSink
, pdwConnection
);
85 STDMETHODIMP
VLCDataObject::DUnadvise(DWORD dwConnection
)
87 return _p_adviseHolder
->Unadvise(dwConnection
);
90 STDMETHODIMP
VLCDataObject::EnumDAdvise(IEnumSTATDATA
**ppenumAdvise
)
92 return _p_adviseHolder
->EnumAdvise(ppenumAdvise
);
95 STDMETHODIMP
VLCDataObject::EnumFormatEtc(DWORD dwDirection
, IEnumFORMATETC
**ppEnum
)
100 *ppEnum
= dynamic_cast<IEnumFORMATETC
*>(new VLCEnumFORMATETC(_v_formatEtc
));
102 return (NULL
!= *ppEnum
) ? S_OK
: E_OUTOFMEMORY
;
105 STDMETHODIMP
VLCDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatEtcIn
, LPFORMATETC pFormatEtcOut
)
107 HRESULT result
= QueryGetData(pFormatEtcIn
);
111 if( NULL
== pFormatEtcOut
)
114 *pFormatEtcOut
= *pFormatEtcIn
;
115 pFormatEtcOut
->ptd
= NULL
;
117 return DATA_S_SAMEFORMATETC
;
120 STDMETHODIMP
VLCDataObject::GetData(LPFORMATETC pFormatEtc
, LPSTGMEDIUM pMedium
)
122 if( NULL
== pMedium
)
125 HRESULT result
= QueryGetData(pFormatEtc
);
126 if( SUCCEEDED(result
) )
128 switch( pFormatEtc
->cfFormat
)
130 case CF_METAFILEPICT
:
131 pMedium
->tymed
= TYMED_MFPICT
;
132 pMedium
->hMetaFilePict
= NULL
;
133 pMedium
->pUnkForRelease
= NULL
;
134 result
= getMetaFileData(pFormatEtc
, pMedium
);
137 pMedium
->tymed
= TYMED_ENHMF
;
138 pMedium
->hEnhMetaFile
= NULL
;
139 pMedium
->pUnkForRelease
= NULL
;
140 result
= getEnhMetaFileData(pFormatEtc
, pMedium
);
143 result
= DV_E_FORMATETC
;
149 STDMETHODIMP
VLCDataObject::GetDataHere(LPFORMATETC pFormatEtc
, LPSTGMEDIUM pMedium
)
151 if( NULL
== pMedium
)
157 ////////////////////////////////////////////////////////////////////////////////////////////////
159 HRESULT
VLCDataObject::getMetaFileData(LPFORMATETC pFormatEtc
, LPSTGMEDIUM pMedium
)
161 HDC hicTargetDev
= CreateDevDC(pFormatEtc
->ptd
);
162 if( NULL
== hicTargetDev
)
165 HDC hdcMeta
= CreateMetaFile(NULL
);
166 if( NULL
!= hdcMeta
)
168 LPMETAFILEPICT pMetaFilePict
= (LPMETAFILEPICT
)CoTaskMemAlloc(sizeof(METAFILEPICT
));
169 if( NULL
!= pMetaFilePict
)
171 SIZEL size
= _p_instance
->getExtent();
172 RECTL wBounds
= { 0L, 0L, size
.cx
, size
.cy
};
174 pMetaFilePict
->mm
= MM_ANISOTROPIC
;
175 pMetaFilePict
->xExt
= size
.cx
;
176 pMetaFilePict
->yExt
= size
.cy
;
178 DPFromHimetric(hicTargetDev
, (LPPOINT
)&size
, 1);
180 SetMapMode(hdcMeta
, MM_ANISOTROPIC
);
181 SetWindowExtEx(hdcMeta
, size
.cx
, size
.cy
, NULL
);
183 RECTL bounds
= { 0L, 0L, size
.cx
, size
.cy
};
185 _p_instance
->onDraw(pFormatEtc
->ptd
, hicTargetDev
, hdcMeta
, &bounds
, &wBounds
);
186 pMetaFilePict
->hMF
= CloseMetaFile(hdcMeta
);
187 if( NULL
!= pMetaFilePict
->hMF
)
188 pMedium
->hMetaFilePict
= pMetaFilePict
;
190 CoTaskMemFree(pMetaFilePict
);
193 DeleteDC(hicTargetDev
);
194 return (NULL
!= pMedium
->hMetaFilePict
) ? S_OK
: E_FAIL
;
197 HRESULT
VLCDataObject::getEnhMetaFileData(LPFORMATETC pFormatEtc
, LPSTGMEDIUM pMedium
)
199 HDC hicTargetDev
= CreateDevDC(pFormatEtc
->ptd
);
200 if( NULL
== hicTargetDev
)
203 SIZEL size
= _p_instance
->getExtent();
205 HDC hdcMeta
= CreateEnhMetaFile(hicTargetDev
, NULL
, NULL
, NULL
);
206 if( NULL
!= hdcMeta
)
208 RECTL wBounds
= { 0L, 0L, size
.cx
, size
.cy
};
210 DPFromHimetric(hicTargetDev
, (LPPOINT
)&size
, 1);
212 RECTL bounds
= { 0L, 0L, size
.cx
, size
.cy
};
214 _p_instance
->onDraw(pFormatEtc
->ptd
, hicTargetDev
, hdcMeta
, &bounds
, &wBounds
);
215 pMedium
->hEnhMetaFile
= CloseEnhMetaFile(hdcMeta
);
217 DeleteDC(hicTargetDev
);
219 return (NULL
!= pMedium
->hEnhMetaFile
) ? S_OK
: E_FAIL
;
222 STDMETHODIMP
VLCDataObject::QueryGetData(LPFORMATETC pFormatEtc
)
224 if( NULL
== pFormatEtc
)
227 const FORMATETC
*formatEtc
;
229 switch( pFormatEtc
->cfFormat
)
231 case CF_METAFILEPICT
:
232 formatEtc
= &_metaFileFormatEtc
;
235 formatEtc
= &_enhMetaFileFormatEtc
;
238 return DV_E_FORMATETC
;
241 if( pFormatEtc
->dwAspect
!= formatEtc
->dwAspect
)
242 return DV_E_DVASPECT
;
244 if( pFormatEtc
->lindex
!= formatEtc
->lindex
)
247 if( pFormatEtc
->tymed
!= formatEtc
->tymed
)
253 STDMETHODIMP
VLCDataObject::SetData(LPFORMATETC pFormatEtc
, LPSTGMEDIUM pMedium
, BOOL fRelease
)
258 /*void VLCDataObject::onDataChange(void)
260 _p_adviseHolder->SendOnDataChange(this, 0, 0);
263 void VLCDataObject::onClose(void)
265 _p_adviseHolder
->SendOnDataChange(this, 0, ADVF_DATAONSTOP
);
266 if( S_OK
== OleIsCurrentClipboard(dynamic_cast<LPDATAOBJECT
>(this)) )