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)) )