]> git.sesse.net Git - vlc/blob - projects/activex/dataobject.cpp
Use var_Inherit* instead of var_CreateGet*.
[vlc] / projects / activex / dataobject.cpp
1 /*****************************************************************************
2  * viewobject.cpp: ActiveX control for VLC
3  *****************************************************************************
4  * Copyright (C) 2005 VideoLAN
5  *
6  * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
7  *
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.
12  *
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.
17  *
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  *****************************************************************************/
22
23 #include "plugin.h"
24 #include "dataobject.h"
25
26 #include "utils.h"
27
28 using namespace std;
29
30 //////////////////////////////////////////////////////////////////////////////
31
32 static const FORMATETC _metaFileFormatEtc =
33 {
34     CF_METAFILEPICT,
35     NULL,
36     DVASPECT_CONTENT,
37     -1,
38     TYMED_MFPICT,
39 };
40 static const FORMATETC _enhMetaFileFormatEtc =
41 {
42     CF_ENHMETAFILE,
43     NULL,
44     DVASPECT_CONTENT,
45     -1,
46     TYMED_ENHMF,
47 };
48
49 class VLCEnumFORMATETC : public VLCEnumIterator<IID_IEnumFORMATETC,
50     IEnumFORMATETC,
51     FORMATETC,
52     vector<FORMATETC>::iterator>
53 {
54 public:
55     VLCEnumFORMATETC(vector<FORMATETC> v) :
56         VLCEnumIterator<IID_IEnumFORMATETC,
57         IEnumFORMATETC,
58         FORMATETC,
59         vector<FORMATETC>::iterator>(v.begin(), v.end())
60     {};
61 };
62
63 //////////////////////////////////////////////////////////////////////////////
64
65 VLCDataObject::VLCDataObject(VLCPlugin *p_instance) : _p_instance(p_instance)
66 {
67     _v_formatEtc.push_back(_enhMetaFileFormatEtc);
68     _v_formatEtc.push_back(_metaFileFormatEtc);
69     CreateDataAdviseHolder(&_p_adviseHolder);
70 };
71
72 VLCDataObject::~VLCDataObject()
73 {
74     _p_adviseHolder->Release();
75 };
76
77 //////////////////////////////////////////////////////////////////////////////
78
79 STDMETHODIMP VLCDataObject::DAdvise(LPFORMATETC pFormatEtc, DWORD padvf,
80                               LPADVISESINK pAdviseSink, LPDWORD pdwConnection)
81 {
82     return _p_adviseHolder->Advise(this,
83             pFormatEtc, padvf,pAdviseSink, pdwConnection);
84 };
85
86 STDMETHODIMP VLCDataObject::DUnadvise(DWORD dwConnection)
87 {
88     return _p_adviseHolder->Unadvise(dwConnection);
89 };
90
91 STDMETHODIMP VLCDataObject::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
92 {
93     return _p_adviseHolder->EnumAdvise(ppenumAdvise);
94 };
95
96 STDMETHODIMP VLCDataObject::EnumFormatEtc(DWORD dwDirection,
97                                           IEnumFORMATETC **ppEnum)
98 {
99     if( NULL == ppEnum )
100         return E_POINTER;
101
102     *ppEnum = new VLCEnumFORMATETC(_v_formatEtc);
103
104     return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
105 };
106
107 STDMETHODIMP VLCDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatEtcIn,
108                                                   LPFORMATETC pFormatEtcOut)
109 {
110     HRESULT result = QueryGetData(pFormatEtcIn);
111     if( FAILED(result) )
112         return result;
113
114     if( NULL == pFormatEtcOut )
115         return E_POINTER;
116
117     *pFormatEtcOut = *pFormatEtcIn;
118     pFormatEtcOut->ptd = NULL;
119
120     return DATA_S_SAMEFORMATETC;
121 };
122
123 STDMETHODIMP VLCDataObject::GetData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
124 {
125     if( NULL == pMedium )
126         return E_POINTER;
127
128     HRESULT result = QueryGetData(pFormatEtc);
129     if( SUCCEEDED(result) )
130     {
131         switch( pFormatEtc->cfFormat )
132         {
133             case CF_METAFILEPICT:
134                 pMedium->tymed = TYMED_MFPICT;
135                 pMedium->hMetaFilePict = NULL;
136                 pMedium->pUnkForRelease = NULL;
137                 result = getMetaFileData(pFormatEtc, pMedium);
138                 break;
139             case CF_ENHMETAFILE:
140                 pMedium->tymed = TYMED_ENHMF;
141                 pMedium->hEnhMetaFile = NULL;
142                 pMedium->pUnkForRelease = NULL;
143                 result = getEnhMetaFileData(pFormatEtc, pMedium);
144                 break;
145             default:
146                 result = DV_E_FORMATETC;
147         }
148     }
149     return result;
150 };
151
152 STDMETHODIMP VLCDataObject::GetDataHere(LPFORMATETC pFormatEtc,
153                                         LPSTGMEDIUM pMedium)
154 {
155     if( NULL == pMedium )
156         return E_POINTER;
157
158     return E_NOTIMPL;
159 }
160
161 //////////////////////////////////////////////////////////////////////////////
162
163 HRESULT VLCDataObject::getMetaFileData(LPFORMATETC pFormatEtc,
164                                        LPSTGMEDIUM pMedium)
165 {
166     HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
167     if( NULL == hicTargetDev )
168         return E_FAIL;
169
170     HDC hdcMeta = CreateMetaFile(NULL);
171     if( NULL != hdcMeta )
172     {
173         LPMETAFILEPICT pMetaFilePict =
174                          (LPMETAFILEPICT)CoTaskMemAlloc(sizeof(METAFILEPICT));
175         if( NULL != pMetaFilePict )
176         {
177             SIZEL size = _p_instance->getExtent();
178             RECTL wBounds = { 0L, 0L, size.cx, size.cy };
179
180             pMetaFilePict->mm   = MM_ANISOTROPIC;
181             pMetaFilePict->xExt = size.cx;
182             pMetaFilePict->yExt = size.cy;
183
184             DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);
185
186             SetMapMode(hdcMeta, MM_ANISOTROPIC);
187             SetWindowExtEx(hdcMeta, size.cx, size.cy, NULL);
188
189             RECTL bounds = { 0L, 0L, size.cx, size.cy };
190
191             _p_instance->onDraw(pFormatEtc->ptd, hicTargetDev, hdcMeta,
192                                 &bounds, &wBounds);
193             pMetaFilePict->hMF = CloseMetaFile(hdcMeta);
194             if( NULL != pMetaFilePict->hMF )
195                 pMedium->hMetaFilePict = pMetaFilePict;
196             else
197                 CoTaskMemFree(pMetaFilePict);
198         }
199     }
200     DeleteDC(hicTargetDev);
201     return (NULL != pMedium->hMetaFilePict) ? S_OK : E_FAIL;
202 };
203
204 HRESULT VLCDataObject::getEnhMetaFileData(LPFORMATETC pFormatEtc,
205                                           LPSTGMEDIUM pMedium)
206 {
207     HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
208     if( NULL == hicTargetDev )
209         return E_FAIL;
210
211     SIZEL size = _p_instance->getExtent();
212
213     HDC hdcMeta = CreateEnhMetaFile(hicTargetDev, NULL, NULL, NULL);
214     if( NULL != hdcMeta )
215     {
216         RECTL wBounds = { 0L, 0L, size.cx, size.cy };
217
218         DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);
219
220         RECTL bounds = { 0L, 0L, size.cx, size.cy };
221
222         _p_instance->onDraw(pFormatEtc->ptd, hicTargetDev,
223                             hdcMeta, &bounds, &wBounds);
224         pMedium->hEnhMetaFile = CloseEnhMetaFile(hdcMeta);
225     }
226     DeleteDC(hicTargetDev);
227
228     return (NULL != pMedium->hEnhMetaFile) ? S_OK : E_FAIL;
229 };
230
231 STDMETHODIMP VLCDataObject::QueryGetData(LPFORMATETC pFormatEtc)
232 {
233     if( NULL == pFormatEtc )
234         return E_POINTER;
235
236     const FORMATETC *formatEtc;
237
238     switch( pFormatEtc->cfFormat )
239     {
240         case CF_METAFILEPICT:
241             formatEtc = &_metaFileFormatEtc;
242             break;
243         case CF_ENHMETAFILE:
244             formatEtc = &_enhMetaFileFormatEtc;
245             break;
246         default:
247             return DV_E_FORMATETC;
248     }
249  
250     if( pFormatEtc->dwAspect != formatEtc->dwAspect )
251         return DV_E_DVASPECT;
252
253     if( pFormatEtc->lindex != formatEtc->lindex )
254         return DV_E_LINDEX;
255
256     if( pFormatEtc->tymed != formatEtc->tymed )
257         return DV_E_TYMED;
258
259     return S_OK;
260 };
261
262 STDMETHODIMP VLCDataObject::SetData(LPFORMATETC pFormatEtc,
263                                     LPSTGMEDIUM pMedium, BOOL fRelease)
264 {
265     return E_NOTIMPL;
266 };
267
268 /*void VLCDataObject::onDataChange(void)
269 {
270     _p_adviseHolder->SendOnDataChange(this, 0, 0);
271 };*/
272
273 void VLCDataObject::onClose(void)
274 {
275     _p_adviseHolder->SendOnDataChange(this, 0, ADVF_DATAONSTOP);
276     if( S_OK == OleIsCurrentClipboard(dynamic_cast<LPDATAOBJECT>(this)) )
277         OleFlushClipboard();
278 };
279