00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
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
00280
00281
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