Commit 24235e8a authored by Damien Fouilleul's avatar Damien Fouilleul

Improved compatibility

tested to work with
- Visual Basic 6
- Visual C++ 6
- Microsoft Office 2003
- Internet Explorer 6

all: support for aggregation + bug fixes
dataobject.cpp, dataobject.h: initial support for embedding
parent 661a9e7b
...@@ -32,6 +32,8 @@ SOURCES_activex = \ ...@@ -32,6 +32,8 @@ SOURCES_activex = \
connectioncontainer.h \ connectioncontainer.h \
objectsafety.cpp \ objectsafety.cpp \
objectsafety.h \ objectsafety.h \
dataobject.cpp \
dataobject.h \
viewobject.cpp \ viewobject.cpp \
viewobject.h \ viewobject.h \
vlccontrol.cpp \ vlccontrol.cpp \
......
...@@ -221,8 +221,23 @@ private: ...@@ -221,8 +221,23 @@ private:
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
VLCDispatchEvent::~VLCDispatchEvent()
{
//clear event arguments
if( NULL != _dispParams.rgvarg )
{
for(unsigned int c=0; c<_dispParams.cArgs; ++c)
VariantClear(_dispParams.rgvarg+c);
CoTaskMemFree(_dispParams.rgvarg);
}
if( NULL != _dispParams.rgdispidNamedArgs )
CoTaskMemFree(_dispParams.rgdispidNamedArgs);
};
////////////////////////////////////////////////////////////////////////////////////////////////
VLCConnectionPointContainer::VLCConnectionPointContainer(VLCPlugin *p_instance) : VLCConnectionPointContainer::VLCConnectionPointContainer(VLCPlugin *p_instance) :
_p_instance(p_instance) _p_instance(p_instance), _b_freeze(FALSE)
{ {
_p_events = new VLCConnectionPoint(dynamic_cast<LPCONNECTIONPOINTCONTAINER>(this), _p_events = new VLCConnectionPoint(dynamic_cast<LPCONNECTIONPOINTCONTAINER>(this),
_p_instance->getDispEventID()); _p_instance->getDispEventID());
...@@ -237,7 +252,6 @@ VLCConnectionPointContainer::VLCConnectionPointContainer(VLCPlugin *p_instance) ...@@ -237,7 +252,6 @@ VLCConnectionPointContainer::VLCConnectionPointContainer(VLCPlugin *p_instance)
VLCConnectionPointContainer::~VLCConnectionPointContainer() VLCConnectionPointContainer::~VLCConnectionPointContainer()
{ {
_v_cps.clear();
delete _p_props; delete _p_props;
delete _p_events; delete _p_events;
}; };
...@@ -275,13 +289,46 @@ STDMETHODIMP VLCConnectionPointContainer::FindConnectionPoint(REFIID riid, IConn ...@@ -275,13 +289,46 @@ STDMETHODIMP VLCConnectionPointContainer::FindConnectionPoint(REFIID riid, IConn
return NOERROR; return NOERROR;
}; };
void VLCConnectionPointContainer::freezeEvents(BOOL freeze)
{
if( ! freeze )
{
// release queued events
while( ! _q_events.empty() )
{
VLCDispatchEvent *ev = _q_events.front();
_p_events->fireEvent(ev->_dispId, &ev->_dispParams);
delete ev;
_q_events.pop();
}
}
_b_freeze = freeze;
};
void VLCConnectionPointContainer::fireEvent(DISPID dispId, DISPPARAMS* pDispParams) void VLCConnectionPointContainer::fireEvent(DISPID dispId, DISPPARAMS* pDispParams)
{ {
_p_events->fireEvent(dispId, pDispParams); VLCDispatchEvent *evt = new VLCDispatchEvent(dispId, *pDispParams);
if( _b_freeze )
{
// queue event for later use when container is ready
_q_events.push(evt);
if( _q_events.size() > 10 )
{
// too many events in queue, get rid of older one
delete _q_events.front();
_q_events.pop();
}
}
else
{
_p_events->fireEvent(dispId, pDispParams);
delete evt;
}
}; };
void VLCConnectionPointContainer::firePropChangedEvent(DISPID dispId) void VLCConnectionPointContainer::firePropChangedEvent(DISPID dispId)
{ {
_p_props->firePropChangedEvent(dispId); if( ! _b_freeze )
_p_props->firePropChangedEvent(dispId);
}; };
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
#include <ocidl.h> #include <ocidl.h>
#include <vector> #include <vector>
#include <queue>
using namespace std;
class VLCConnectionPoint : public IConnectionPoint class VLCConnectionPoint : public IConnectionPoint
{ {
...@@ -68,11 +67,23 @@ private: ...@@ -68,11 +67,23 @@ private:
REFIID _iid; REFIID _iid;
IConnectionPointContainer *_p_cpc; IConnectionPointContainer *_p_cpc;
vector<CONNECTDATA> _connections; std::vector<CONNECTDATA> _connections;
}; };
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
class VLCDispatchEvent {
public:
VLCDispatchEvent(DISPID dispId, DISPPARAMS dispParams) :
_dispId(dispId), _dispParams(dispParams) {};
VLCDispatchEvent(const VLCDispatchEvent&);
~VLCDispatchEvent();
DISPID _dispId;
DISPPARAMS _dispParams;
};
class VLCConnectionPointContainer : public IConnectionPointContainer class VLCConnectionPointContainer : public IConnectionPointContainer
{ {
...@@ -91,25 +102,28 @@ public: ...@@ -91,25 +102,28 @@ public:
*ppv = reinterpret_cast<LPVOID>(this); *ppv = reinterpret_cast<LPVOID>(this);
return NOERROR; return NOERROR;
} }
return _p_instance->QueryInterface(riid, ppv); return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
}; };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->AddRef(); }; STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->Release(); }; STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IConnectionPointContainer methods // IConnectionPointContainer methods
STDMETHODIMP EnumConnectionPoints(LPENUMCONNECTIONPOINTS *); STDMETHODIMP EnumConnectionPoints(LPENUMCONNECTIONPOINTS *);
STDMETHODIMP FindConnectionPoint(REFIID, LPCONNECTIONPOINT *); STDMETHODIMP FindConnectionPoint(REFIID, LPCONNECTIONPOINT *);
void freezeEvents(BOOL);
void fireEvent(DISPID, DISPPARAMS*); void fireEvent(DISPID, DISPPARAMS*);
void firePropChangedEvent(DISPID dispId); void firePropChangedEvent(DISPID dispId);
private: private:
VLCPlugin *_p_instance; VLCPlugin *_p_instance;
BOOL _b_freeze;
VLCConnectionPoint *_p_events; VLCConnectionPoint *_p_events;
VLCConnectionPoint *_p_props; VLCConnectionPoint *_p_props;
vector<LPCONNECTIONPOINT> _v_cps; std::vector<LPCONNECTIONPOINT> _v_cps;
std::queue<class VLCDispatchEvent *> _q_events;
}; };
#endif #endif
......
/*****************************************************************************
* viewobject.cpp: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 VideoLAN
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include "plugin.h"
#include "dataobject.h"
#include "utils.h"
using namespace std;
////////////////////////////////////////////////////////////////////////////////////////////////
class VLCEnumFORMATETC : public IEnumFORMATETC
{
public:
VLCEnumFORMATETC(vector<FORMATETC> &v) :
e(VLCEnum<FORMATETC>(IID_IEnumFORMATETC, v)) {};
VLCEnumFORMATETC(const VLCEnumFORMATETC &vlcEnum) : e(vlcEnum.e) {};
virtual ~VLCEnumFORMATETC() {};
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{ return e.QueryInterface(riid, ppv); };
STDMETHODIMP_(ULONG) AddRef(void)
{ return e.AddRef(); };
STDMETHODIMP_(ULONG) Release(void)
{return e.Release(); };
//IEnumConnectionPoints
STDMETHODIMP Next(ULONG celt, LPFORMATETC rgelt, ULONG *pceltFetched)
{ return e.Next(celt, rgelt, pceltFetched); };
STDMETHODIMP Skip(ULONG celt)
{ return e.Skip(celt);};
STDMETHODIMP Reset(void)
{ return e.Reset();};
STDMETHODIMP Clone(LPENUMFORMATETC *ppenum)
{ if( NULL == ppenum ) return E_POINTER;
*ppenum = dynamic_cast<LPENUMFORMATETC>(new VLCEnumFORMATETC(*this));
return (NULL != *ppenum) ? S_OK : E_OUTOFMEMORY;
};
private:
VLCEnum<FORMATETC> e;
};
////////////////////////////////////////////////////////////////////////////////////////////////
static const FORMATETC _metaFileFormatEtc =
{
CF_METAFILEPICT,
NULL,
DVASPECT_CONTENT,
-1,
TYMED_MFPICT,
};
static const FORMATETC _enhMetaFileFormatEtc =
{
CF_ENHMETAFILE,
NULL,
DVASPECT_CONTENT,
-1,
TYMED_ENHMF,
};
VLCDataObject::VLCDataObject(VLCPlugin *p_instance) : _p_instance(p_instance)
{
_v_formatEtc.push_back(_enhMetaFileFormatEtc);
_v_formatEtc.push_back(_metaFileFormatEtc);
CreateDataAdviseHolder(&_p_adviseHolder);
};
VLCDataObject::~VLCDataObject()
{
_p_adviseHolder->Release();
};
////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP VLCDataObject::DAdvise(LPFORMATETC pFormatEtc, DWORD padvf, LPADVISESINK pAdviseSink, LPDWORD pdwConnection)
{
return _p_adviseHolder->Advise(this,
pFormatEtc, padvf,pAdviseSink, pdwConnection);
};
STDMETHODIMP VLCDataObject::DUnadvise(DWORD dwConnection)
{
return _p_adviseHolder->Unadvise(dwConnection);
};
STDMETHODIMP VLCDataObject::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
{
return _p_adviseHolder->EnumAdvise(ppenumAdvise);
};
STDMETHODIMP VLCDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumformatetc)
{
if( NULL == ppenumformatetc )
return E_POINTER;
*ppenumformatetc = new VLCEnumFORMATETC(_v_formatEtc);
return NOERROR;
};
STDMETHODIMP VLCDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatEtcIn, LPFORMATETC pFormatEtcOut)
{
HRESULT result = QueryGetData(pFormatEtcIn);
if( FAILED(result) )
return result;
if( NULL == pFormatEtcOut )
return E_POINTER;
*pFormatEtcOut = *pFormatEtcIn;
pFormatEtcOut->ptd = NULL;
return DATA_S_SAMEFORMATETC;
};
STDMETHODIMP VLCDataObject::GetData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
{
if( NULL == pMedium )
return E_POINTER;
HRESULT result = QueryGetData(pFormatEtc);
if( SUCCEEDED(result) )
{
switch( pFormatEtc->cfFormat )
{
case CF_METAFILEPICT:
pMedium->tymed = TYMED_MFPICT;
pMedium->hMetaFilePict = NULL;
pMedium->pUnkForRelease = NULL;
result = getMetaFileData(pFormatEtc, pMedium);
break;
case CF_ENHMETAFILE:
pMedium->tymed = TYMED_ENHMF;
pMedium->hEnhMetaFile = NULL;
pMedium->pUnkForRelease = NULL;
result = getEnhMetaFileData(pFormatEtc, pMedium);
break;
default:
result = DV_E_FORMATETC;
}
}
return result;
};
STDMETHODIMP VLCDataObject::GetDataHere(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
{
if( NULL == pMedium )
return E_POINTER;
return E_NOTIMPL;
}
////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT VLCDataObject::getMetaFileData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
{
HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
if( NULL == hicTargetDev )
return E_FAIL;
HDC hdcMeta = CreateMetaFile(NULL);
if( NULL != hdcMeta )
{
LPMETAFILEPICT pMetaFilePict = (LPMETAFILEPICT)CoTaskMemAlloc(sizeof(METAFILEPICT));
if( NULL != pMetaFilePict )
{
SIZEL size = _p_instance->getExtent();
RECTL wBounds = { 0L, 0L, size.cx, size.cy };
LONG width = size.cx*GetDeviceCaps(hicTargetDev, LOGPIXELSX)/2540L;
LONG height = size.cy*GetDeviceCaps(hicTargetDev, LOGPIXELSY)/2540L;
pMetaFilePict->mm = MM_ANISOTROPIC;
pMetaFilePict->xExt = size.cx;
pMetaFilePict->yExt = size.cy;
SetMapMode(hdcMeta, MM_ANISOTROPIC);
SetWindowOrgEx(hdcMeta, 0, 0, NULL);
SetWindowExtEx(hdcMeta, width, height, NULL);
RECTL bounds = { 0L, 0L, width, height };
_p_instance->onDraw(pFormatEtc->ptd, hicTargetDev, hdcMeta, &bounds, &wBounds);
pMetaFilePict->hMF = CloseMetaFile(hdcMeta);
if( NULL != pMetaFilePict->hMF )
pMedium->hMetaFilePict = pMetaFilePict;
else
CoTaskMemFree(pMetaFilePict);
}
}
DeleteDC(hicTargetDev);
return (NULL != pMedium->hMetaFilePict) ? S_OK : E_FAIL;
};
HRESULT VLCDataObject::getEnhMetaFileData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
{
HDC hicTargetDev = CreateDevDC(pFormatEtc->ptd);
if( NULL == hicTargetDev )
return E_FAIL;
SIZEL size = _p_instance->getExtent();
HDC hdcMeta = CreateEnhMetaFile(hicTargetDev, NULL, NULL, NULL);
if( NULL != hdcMeta )
{
RECTL wBounds = { 0L, 0L, size.cx, size.cy };
LONG width = size.cx*GetDeviceCaps(hicTargetDev, LOGPIXELSX)/2540L;
LONG height = size.cy*GetDeviceCaps(hicTargetDev, LOGPIXELSY)/2540L;
RECTL bounds = { 0L, 0L, width, height };
_p_instance->onDraw(pFormatEtc->ptd, hicTargetDev, hdcMeta, &bounds, &wBounds);
pMedium->hEnhMetaFile = CloseEnhMetaFile(hdcMeta);
}
DeleteDC(hicTargetDev);
return (NULL != pMedium->hEnhMetaFile) ? S_OK : E_FAIL;
};
STDMETHODIMP VLCDataObject::QueryGetData(LPFORMATETC pFormatEtc)
{
if( NULL == pFormatEtc )
return E_POINTER;
const FORMATETC *formatEtc;
switch( pFormatEtc->cfFormat )
{
case CF_METAFILEPICT:
formatEtc = &_metaFileFormatEtc;
break;
case CF_ENHMETAFILE:
formatEtc = &_enhMetaFileFormatEtc;
break;
default:
return DV_E_FORMATETC;
}
if( pFormatEtc->dwAspect != formatEtc->dwAspect )
return DV_E_DVASPECT;
if( pFormatEtc->lindex != formatEtc->lindex )
return DV_E_LINDEX;
if( pFormatEtc->tymed != formatEtc->tymed )
return DV_E_TYMED;
return S_OK;
};
STDMETHODIMP VLCDataObject::SetData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium, BOOL fRelease)
{
return E_NOTIMPL;
};
void VLCDataObject::onClose(void)
{
_p_adviseHolder->SendOnDataChange(this, 0, ADVF_DATAONSTOP);
if( S_OK == OleIsCurrentClipboard(dynamic_cast<LPDATAOBJECT>(this)) )
OleFlushClipboard();
};
/*****************************************************************************
* persiststorage.h: ActiveX control for VLC
*****************************************************************************
* Copyright (C) 2005 VideoLAN
*
* Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef __DATAOBJECT_H__
#define __DATAOBJECT_H__
#include <objidl.h>
#include <vector>
class VLCDataObject : public IDataObject
{
public:
VLCDataObject(VLCPlugin *p_instance);
virtual ~VLCDataObject();
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( (NULL != ppv)
&& (IID_IUnknown == riid)
&& (IID_IDataObject == riid) ) {
AddRef();
*ppv = reinterpret_cast<LPVOID>(this);
return NOERROR;
}
return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
};
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IDataObject methods
STDMETHODIMP DAdvise(LPFORMATETC,DWORD,LPADVISESINK,LPDWORD);
STDMETHODIMP DUnadvise(DWORD);
STDMETHODIMP EnumDAdvise(IEnumSTATDATA**);
STDMETHODIMP EnumFormatEtc(DWORD, IEnumFORMATETC**);
STDMETHODIMP GetCanonicalFormatEtc(LPFORMATETC,LPFORMATETC);
STDMETHODIMP GetData(LPFORMATETC,LPSTGMEDIUM);
STDMETHODIMP GetDataHere(LPFORMATETC,LPSTGMEDIUM);
STDMETHODIMP QueryGetData(LPFORMATETC);
STDMETHODIMP SetData(LPFORMATETC,LPSTGMEDIUM,BOOL);
void onClose(void);
private:
HRESULT getMetaFileData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
HRESULT getEnhMetaFileData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
VLCPlugin *_p_instance;
std::vector<FORMATETC> _v_formatEtc;
IDataAdviseHolder *_p_adviseHolder;
};
#endif
...@@ -186,6 +186,10 @@ STDAPI DllRegisterServer(VOID) ...@@ -186,6 +186,10 @@ STDAPI DllRegisterServer(VOID)
hSubKey = keyCreate(hClassKey, TEXT("Control")); hSubKey = keyCreate(hClassKey, TEXT("Control"));
RegCloseKey(hSubKey); RegCloseKey(hSubKey);
// Insertable key value
//hSubKey = keyCreate(hClassKey, TEXT("Insertable"));
//RegCloseKey(hSubKey);
// ToolboxBitmap32 key value // ToolboxBitmap32 key value
hSubKey = keyCreate(hClassKey, TEXT("ToolboxBitmap32")); hSubKey = keyCreate(hClassKey, TEXT("ToolboxBitmap32"));
strcpy(DllPath+DllPathLen, ",1"); strcpy(DllPath+DllPathLen, ",1");
...@@ -294,6 +298,9 @@ STDAPI DllRegisterServer(VOID) ...@@ -294,6 +298,9 @@ STDAPI DllRegisterServer(VOID)
RegCloseKey(hSubKey); RegCloseKey(hSubKey);
} }
//hSubKey = keyCreate(hBaseKey, TEXT("Insertable"));
//RegCloseKey(hSubKey);
RegCloseKey(hBaseKey); RegCloseKey(hBaseKey);
} }
......
...@@ -30,6 +30,8 @@ const GUID IID_IObjectSafety = ...@@ -30,6 +30,8 @@ const GUID IID_IObjectSafety =
{0xCB5BDC81,0x93C1,0x11cf,{0x8F,0x20,0x00,0x80,0x5F,0x2C,0xD0,0x64}}; {0xCB5BDC81,0x93C1,0x11cf,{0x8F,0x20,0x00,0x80,0x5F,0x2C,0xD0,0x64}};
#endif #endif
using namespace std;
STDMETHODIMP VLCObjectSafety::GetInterfaceSafetyOptions( STDMETHODIMP VLCObjectSafety::GetInterfaceSafetyOptions(
REFIID riid, REFIID riid,
DWORD *pdwSupportedOptions, DWORD *pdwSupportedOptions,
......
...@@ -30,6 +30,9 @@ ...@@ -30,6 +30,9 @@
#include <objsafe.h> #include <objsafe.h>
#else #else
/*
** mingw does not yet support objsafe.h, redefine what we need here
*/
// {CB5BDC81-93C1-11cf-8F20-00805F2CD064} // {CB5BDC81-93C1-11cf-8F20-00805F2CD064}
extern "C" const IID IID_IObjectSafety; extern "C" const IID IID_IObjectSafety;
...@@ -72,11 +75,11 @@ public: ...@@ -72,11 +75,11 @@ public:
*ppv = reinterpret_cast<LPVOID>(this); *ppv = reinterpret_cast<LPVOID>(this);
return NOERROR; return NOERROR;
} }
return _p_instance->QueryInterface(riid, ppv); return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
}; };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->AddRef(); }; STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->Release(); }; STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IUnknown methods // IUnknown methods
STDMETHODIMP GetInterfaceSafetyOptions( STDMETHODIMP GetInterfaceSafetyOptions(
......
...@@ -127,7 +127,7 @@ STDMETHODIMP VLCOleControl::OnAmbientPropertyChange(DISPID dispID) ...@@ -127,7 +127,7 @@ STDMETHODIMP VLCOleControl::OnAmbientPropertyChange(DISPID dispID)
STDMETHODIMP VLCOleControl::FreezeEvents(BOOL bFreeze) STDMETHODIMP VLCOleControl::FreezeEvents(BOOL bFreeze)
{ {
_p_instance->setSendEvents(! bFreeze); _p_instance->freezeEvents(bFreeze);
return S_OK; return S_OK;
}; };
...@@ -44,11 +44,11 @@ public: ...@@ -44,11 +44,11 @@ public:
*ppv = reinterpret_cast<LPVOID>(this); *ppv = reinterpret_cast<LPVOID>(this);
return NOERROR; return NOERROR;
} }
return _p_instance->QueryInterface(riid, ppv); return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
}; };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->AddRef(); }; STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->Release(); }; STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IOleControl methods // IOleControl methods
STDMETHODIMP GetControlInfo(CONTROLINFO *pCI); STDMETHODIMP GetControlInfo(CONTROLINFO *pCI);
......
...@@ -45,11 +45,11 @@ public: ...@@ -45,11 +45,11 @@ public:
*ppv = reinterpret_cast<LPVOID>(this); *ppv = reinterpret_cast<LPVOID>(this);
return NOERROR; return NOERROR;
} }
return _p_instance->QueryInterface(riid, ppv); return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
}; };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->AddRef(); }; STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->Release(); }; STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IOleWindow methods // IOleWindow methods
STDMETHODIMP GetWindow(HWND *); STDMETHODIMP GetWindow(HWND *);
......
...@@ -43,11 +43,11 @@ public: ...@@ -43,11 +43,11 @@ public:
*ppv = reinterpret_cast<LPVOID>(this); *ppv = reinterpret_cast<LPVOID>(this);
return NOERROR; return NOERROR;
} }
return _p_instance->QueryInterface(riid, ppv); return _p_instance->pUnkOuter->QueryInterface(riid, ppv);
}; };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->AddRef(); }; STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->Release(); }; STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IOleWindow methods // IOleWindow methods
STDMETHODIMP GetWindow(HWND *); STDMETHODIMP GetWindow(HWND *);
......
...@@ -49,7 +49,6 @@ STDMETHODIMP VLCOleObject::Advise(IAdviseSink *pAdvSink, DWORD *dwConnection) ...@@ -49,7 +49,6 @@ STDMETHODIMP VLCOleObject::Advise(IAdviseSink *pAdvSink, DWORD *dwConnection)
STDMETHODIMP VLCOleObject::Close(DWORD dwSaveOption) STDMETHODIMP VLCOleObject::Close(DWORD dwSaveOption)
{ {
_p_advise_holder->SendOnClose(); _p_advise_holder->SendOnClose();
OleFlushClipboard();
return _p_instance->onClose(dwSaveOption); return _p_instance->onClose(dwSaveOption);
}; };
...@@ -61,6 +60,8 @@ STDMETHODIMP VLCOleObject::DoVerb(LONG iVerb, LPMSG lpMsg, LPOLECLIENTSITE pActi ...@@ -61,6 +60,8 @@ STDMETHODIMP VLCOleObject::DoVerb(LONG iVerb, LPMSG lpMsg, LPOLECLIENTSITE pActi
case OLEIVERB_PRIMARY: case OLEIVERB_PRIMARY: