Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

dataobject.cpp

00001 /*****************************************************************************
00002  * viewobject.cpp: ActiveX control for VLC
00003  *****************************************************************************
00004  * Copyright (C) 2005 VideoLAN
00005  *
00006  * Authors: Damien Fouilleul <[email protected]>
00007  *
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00021  *****************************************************************************/
00022 
00023 #include "plugin.h"
00024 #include "dataobject.h"
00025 
00026 #include "utils.h"
00027 
00028 using namespace std;
00029 
00031 
00032 class VLCEnumFORMATETC : public IEnumFORMATETC
00033 {
00034 public:
00035 
00036     VLCEnumFORMATETC(vector<FORMATETC> &v) :
00037         e(VLCEnum<FORMATETC>(IID_IEnumFORMATETC, v)) {};
00038 
00039     VLCEnumFORMATETC(const VLCEnumFORMATETC &vlcEnum) : e(vlcEnum.e) {};
00040     virtual ~VLCEnumFORMATETC() {};
00041 
00042     // IUnknown methods
00043     STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
00044         { return e.QueryInterface(riid, ppv); };
00045     STDMETHODIMP_(ULONG) AddRef(void)
00046         { return e.AddRef(); };
00047     STDMETHODIMP_(ULONG) Release(void)
00048         {return e.Release(); };
00049 
00050     //IEnumConnectionPoints
00051     STDMETHODIMP Next(ULONG celt, LPFORMATETC rgelt, ULONG *pceltFetched)
00052         { return e.Next(celt, rgelt, pceltFetched); };
00053     STDMETHODIMP Skip(ULONG celt)
00054         { return e.Skip(celt);};
00055     STDMETHODIMP Reset(void)
00056         { return e.Reset();};
00057     STDMETHODIMP Clone(LPENUMFORMATETC *ppenum)
00058         { if( NULL == ppenum ) return E_POINTER;
00059           *ppenum = dynamic_cast<LPENUMFORMATETC>(new VLCEnumFORMATETC(*this));
00060           return (NULL != *ppenum) ? S_OK : E_OUTOFMEMORY;
00061         };
00062 
00063 private:
00064 
00065     VLCEnum<FORMATETC> e;
00066 };
00067 
00069 
00070 static const FORMATETC _metaFileFormatEtc =
00071     {
00072         CF_METAFILEPICT,
00073         NULL,
00074         DVASPECT_CONTENT,
00075         -1,
00076         TYMED_MFPICT,
00077     };
00078 static const FORMATETC _enhMetaFileFormatEtc =
00079     {
00080         CF_ENHMETAFILE,
00081         NULL,
00082         DVASPECT_CONTENT,
00083         -1,
00084         TYMED_ENHMF,
00085     };
00086 
00087 VLCDataObject::VLCDataObject(VLCPlugin *p_instance) : _p_instance(p_instance)
00088 {
00089     _v_formatEtc.push_back(_enhMetaFileFormatEtc);
00090     _v_formatEtc.push_back(_metaFileFormatEtc);
00091     CreateDataAdviseHolder(&_p_adviseHolder);
00092 };
00093 
00094 VLCDataObject::~VLCDataObject()
00095 {
00096     _p_adviseHolder->Release();
00097 };
00098 
00100 
00101 STDMETHODIMP VLCDataObject::DAdvise(LPFORMATETC pFormatEtc, DWORD padvf, LPADVISESINK pAdviseSink, LPDWORD pdwConnection)
00102 {
00103     return _p_adviseHolder->Advise(this,
00104             pFormatEtc, padvf,pAdviseSink, pdwConnection);
00105 };
00106 
00107 STDMETHODIMP VLCDataObject::DUnadvise(DWORD dwConnection)
00108 {
00109     return _p_adviseHolder->Unadvise(dwConnection);
00110 };
00111 
00112 STDMETHODIMP VLCDataObject::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
00113 {
00114     return _p_adviseHolder->EnumAdvise(ppenumAdvise);
00115 };
00116 
00117 STDMETHODIMP VLCDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumformatetc)
00118 {
00119     if( NULL == ppenumformatetc )
00120         return E_POINTER;
00121 
00122     *ppenumformatetc = new VLCEnumFORMATETC(_v_formatEtc);
00123     return NOERROR;
00124 };
00125 
00126 STDMETHODIMP VLCDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatEtcIn, LPFORMATETC pFormatEtcOut)
00127 {
00128     HRESULT result = QueryGetData(pFormatEtcIn);
00129     if( FAILED(result) )
00130         return result;
00131 
00132     if( NULL == pFormatEtcOut )
00133         return E_POINTER;
00134 
00135     *pFormatEtcOut = *pFormatEtcIn;
00136     pFormatEtcOut->ptd = NULL;
00137 
00138     return DATA_S_SAMEFORMATETC;
00139 };
00140 
00141 STDMETHODIMP VLCDataObject::GetData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
00142 {
00143     if( NULL == pMedium )
00144         return E_POINTER;
00145 
00146     HRESULT result = QueryGetData(pFormatEtc);
00147     if( SUCCEEDED(result) )
00148     {
00149         switch( pFormatEtc->cfFormat )
00150         {
00151             case CF_METAFILEPICT:
00152                 pMedium->tymed = TYMED_MFPICT;
00153                 pMedium->hMetaFilePict = NULL;
00154                 pMedium->pUnkForRelease = NULL;
00155                 result = getMetaFileData(pFormatEtc, pMedium);
00156                 break;
00157             case CF_ENHMETAFILE:
00158                 pMedium->tymed = TYMED_ENHMF;
00159                 pMedium->hEnhMetaFile = NULL;
00160                 pMedium->pUnkForRelease = NULL;
00161                 result = getEnhMetaFileData(pFormatEtc, pMedium);
00162                 break;
00163             default:
00164                 result = DV_E_FORMATETC;
00165         }
00166     }
00167     return result;
00168 };
00169 
00170 STDMETHODIMP VLCDataObject::GetDataHere(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
00171 {
00172     if( NULL == pMedium )
00173         return E_POINTER;
00174 
00175     return E_NOTIMPL;
00176 }
00177 
00179 
00180 HRESULT VLCDataObject::getMetaFileData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
00181 {
00182     HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
00183     if( NULL == hicTargetDev )
00184         return E_FAIL;
00185 
00186     HDC hdcMeta = CreateMetaFile(NULL); 
00187     if( NULL != hdcMeta )
00188     {
00189         LPMETAFILEPICT pMetaFilePict = (LPMETAFILEPICT)CoTaskMemAlloc(sizeof(METAFILEPICT));
00190         if( NULL != pMetaFilePict )
00191         {
00192             SIZEL size = _p_instance->getExtent();
00193             RECTL wBounds = { 0L, 0L, size.cx, size.cy };
00194 
00195             pMetaFilePict->mm   = MM_ANISOTROPIC;
00196             pMetaFilePict->xExt = size.cx;
00197             pMetaFilePict->yExt = size.cy;
00198 
00199             DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);
00200 
00201             SetMapMode(hdcMeta, MM_ANISOTROPIC);
00202             SetWindowExtEx(hdcMeta, size.cx, size.cy, NULL);
00203 
00204             RECTL bounds = { 0L, 0L, size.cx, size.cy };
00205 
00206             _p_instance->onDraw(pFormatEtc->ptd, hicTargetDev, hdcMeta, &bounds, &wBounds);
00207             pMetaFilePict->hMF = CloseMetaFile(hdcMeta);
00208             if( NULL != pMetaFilePict->hMF )
00209                 pMedium->hMetaFilePict = pMetaFilePict;
00210             else
00211                 CoTaskMemFree(pMetaFilePict);
00212         }
00213     }
00214     DeleteDC(hicTargetDev);
00215     return (NULL != pMedium->hMetaFilePict) ? S_OK : E_FAIL;
00216 };
00217 
00218 HRESULT VLCDataObject::getEnhMetaFileData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
00219 {
00220     HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
00221     if( NULL == hicTargetDev )
00222         return E_FAIL;
00223 
00224     SIZEL size = _p_instance->getExtent();
00225 
00226     HDC hdcMeta = CreateEnhMetaFile(hicTargetDev, NULL, NULL, NULL); 
00227     if( NULL != hdcMeta )
00228     {
00229         RECTL wBounds = { 0L, 0L, size.cx, size.cy };
00230 
00231         DPFromHimetric(hicTargetDev, (LPPOINT)&size, 1);
00232 
00233         RECTL bounds = { 0L, 0L, size.cx, size.cy };
00234 
00235         _p_instance->onDraw(pFormatEtc->ptd, hicTargetDev, hdcMeta, &bounds, &wBounds);
00236         pMedium->hEnhMetaFile = CloseEnhMetaFile(hdcMeta);
00237     }
00238     DeleteDC(hicTargetDev);
00239 
00240     return (NULL != pMedium->hEnhMetaFile) ? S_OK : E_FAIL;
00241 };
00242 
00243 STDMETHODIMP VLCDataObject::QueryGetData(LPFORMATETC pFormatEtc)
00244 {
00245     if( NULL == pFormatEtc )
00246         return E_POINTER;
00247 
00248     const FORMATETC *formatEtc;
00249 
00250     switch( pFormatEtc->cfFormat )
00251     {
00252         case CF_METAFILEPICT:
00253             formatEtc = &_metaFileFormatEtc;
00254             break;
00255         case CF_ENHMETAFILE:
00256             formatEtc = &_enhMetaFileFormatEtc;
00257             break;
00258         default:
00259             return DV_E_FORMATETC;
00260     }
00261     
00262     if( pFormatEtc->dwAspect != formatEtc->dwAspect )
00263         return DV_E_DVASPECT;
00264 
00265     if( pFormatEtc->lindex != formatEtc->lindex )
00266         return DV_E_LINDEX;
00267 
00268     if( pFormatEtc->tymed != formatEtc->tymed )
00269         return DV_E_TYMED;
00270 
00271     return S_OK;
00272 };
00273 
00274 STDMETHODIMP VLCDataObject::SetData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium, BOOL fRelease)
00275 {
00276     return E_NOTIMPL;
00277 };
00278 
00279 /*void VLCDataObject::onDataChange(void)
00280 {
00281     _p_adviseHolder->SendOnDataChange(this, 0, 0);
00282 };*/
00283 
00284 void VLCDataObject::onClose(void)
00285 {
00286     _p_adviseHolder->SendOnDataChange(this, 0, ADVF_DATAONSTOP);
00287     if( S_OK == OleIsCurrentClipboard(dynamic_cast<LPDATAOBJECT>(this)) )
00288         OleFlushClipboard();
00289 };
00290 

Generated on Tue Dec 20 10:14:18 2005 for vlc-0.8.4a by  doxygen 1.4.2