Commit 35db6dd6 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 15c91596
......@@ -32,6 +32,8 @@ SOURCES_activex = \
connectioncontainer.h \
objectsafety.cpp \
objectsafety.h \
dataobject.cpp \
dataobject.h \
viewobject.cpp \
viewobject.h \
vlccontrol.cpp \
......
......@@ -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) :
_p_instance(p_instance)
_p_instance(p_instance), _b_freeze(FALSE)
{
_p_events = new VLCConnectionPoint(dynamic_cast<LPCONNECTIONPOINTCONTAINER>(this),
_p_instance->getDispEventID());
......@@ -237,7 +252,6 @@ VLCConnectionPointContainer::VLCConnectionPointContainer(VLCPlugin *p_instance)
VLCConnectionPointContainer::~VLCConnectionPointContainer()
{
_v_cps.clear();
delete _p_props;
delete _p_events;
};
......@@ -275,13 +289,46 @@ STDMETHODIMP VLCConnectionPointContainer::FindConnectionPoint(REFIID riid, IConn
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)
{
_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)
{
_p_props->firePropChangedEvent(dispId);
if( ! _b_freeze )
_p_props->firePropChangedEvent(dispId);
};
......@@ -25,8 +25,7 @@
#include <ocidl.h>
#include <vector>
using namespace std;
#include <queue>
class VLCConnectionPoint : public IConnectionPoint
{
......@@ -68,11 +67,23 @@ private:
REFIID _iid;
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
{
......@@ -91,25 +102,28 @@ public:
*ppv = reinterpret_cast<LPVOID>(this);
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) Release(void) { return _p_instance->Release(); };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IConnectionPointContainer methods
STDMETHODIMP EnumConnectionPoints(LPENUMCONNECTIONPOINTS *);
STDMETHODIMP FindConnectionPoint(REFIID, LPCONNECTIONPOINT *);
void freezeEvents(BOOL);
void fireEvent(DISPID, DISPPARAMS*);
void firePropChangedEvent(DISPID dispId);
private:
VLCPlugin *_p_instance;
BOOL _b_freeze;
VLCConnectionPoint *_p_events;
VLCConnectionPoint *_p_props;
vector<LPCONNECTIONPOINT> _v_cps;
std::vector<LPCONNECTIONPOINT> _v_cps;
std::queue<class VLCDispatchEvent *> _q_events;
};
#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)
hSubKey = keyCreate(hClassKey, TEXT("Control"));
RegCloseKey(hSubKey);
// Insertable key value
//hSubKey = keyCreate(hClassKey, TEXT("Insertable"));
//RegCloseKey(hSubKey);
// ToolboxBitmap32 key value
hSubKey = keyCreate(hClassKey, TEXT("ToolboxBitmap32"));
strcpy(DllPath+DllPathLen, ",1");
......@@ -294,6 +298,9 @@ STDAPI DllRegisterServer(VOID)
RegCloseKey(hSubKey);
}
//hSubKey = keyCreate(hBaseKey, TEXT("Insertable"));
//RegCloseKey(hSubKey);
RegCloseKey(hBaseKey);
}
......
......@@ -30,6 +30,8 @@ const GUID IID_IObjectSafety =
{0xCB5BDC81,0x93C1,0x11cf,{0x8F,0x20,0x00,0x80,0x5F,0x2C,0xD0,0x64}};
#endif
using namespace std;
STDMETHODIMP VLCObjectSafety::GetInterfaceSafetyOptions(
REFIID riid,
DWORD *pdwSupportedOptions,
......
......@@ -30,6 +30,9 @@
#include <objsafe.h>
#else
/*
** mingw does not yet support objsafe.h, redefine what we need here
*/
// {CB5BDC81-93C1-11cf-8F20-00805F2CD064}
extern "C" const IID IID_IObjectSafety;
......@@ -72,11 +75,11 @@ public:
*ppv = reinterpret_cast<LPVOID>(this);
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) Release(void) { return _p_instance->Release(); };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IUnknown methods
STDMETHODIMP GetInterfaceSafetyOptions(
......
......@@ -127,7 +127,7 @@ STDMETHODIMP VLCOleControl::OnAmbientPropertyChange(DISPID dispID)
STDMETHODIMP VLCOleControl::FreezeEvents(BOOL bFreeze)
{
_p_instance->setSendEvents(! bFreeze);
_p_instance->freezeEvents(bFreeze);
return S_OK;
};
......@@ -44,11 +44,11 @@ public:
*ppv = reinterpret_cast<LPVOID>(this);
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) Release(void) { return _p_instance->Release(); };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IOleControl methods
STDMETHODIMP GetControlInfo(CONTROLINFO *pCI);
......
......@@ -45,11 +45,11 @@ public:
*ppv = reinterpret_cast<LPVOID>(this);
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) Release(void) { return _p_instance->Release(); };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IOleWindow methods
STDMETHODIMP GetWindow(HWND *);
......
......@@ -43,11 +43,11 @@ public:
*ppv = reinterpret_cast<LPVOID>(this);
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) Release(void) { return _p_instance->Release(); };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IOleWindow methods
STDMETHODIMP GetWindow(HWND *);
......
......@@ -49,7 +49,6 @@ STDMETHODIMP VLCOleObject::Advise(IAdviseSink *pAdvSink, DWORD *dwConnection)
STDMETHODIMP VLCOleObject::Close(DWORD dwSaveOption)
{
_p_advise_holder->SendOnClose();
OleFlushClipboard();
return _p_instance->onClose(dwSaveOption);
};
......@@ -61,6 +60,8 @@ STDMETHODIMP VLCOleObject::DoVerb(LONG iVerb, LPMSG lpMsg, LPOLECLIENTSITE pActi
case OLEIVERB_PRIMARY:
case OLEIVERB_SHOW:
case OLEIVERB_OPEN:
// force control to be visible when activating in place
_p_instance->setVisible(TRUE);
case OLEIVERB_INPLACEACTIVATE:
return doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
......@@ -75,7 +76,12 @@ STDMETHODIMP VLCOleObject::DoVerb(LONG iVerb, LPMSG lpMsg, LPOLECLIENTSITE pActi
return S_OK;
default:
return OLEOBJ_S_INVALIDVERB;
if( iVerb > 0 ) {
_p_instance->setVisible(TRUE);
doInPlaceActivate(lpMsg, pActiveSite, hwndParent, lprcPosRect);
return OLEOBJ_S_INVALIDVERB;
}
return E_NOTIMPL;
}
};
......@@ -91,8 +97,8 @@ HRESULT VLCOleObject::doInPlaceActivate(LPMSG lpMsg, LPOLECLIENTSITE pActiveSite
if( _p_instance->isInPlaceActive() )
{
// just attempt to show object then
pActiveSite->ShowObject();
_p_instance->setVisible(TRUE);
if( _p_instance->getVisible() )
pActiveSite->ShowObject();
return S_OK;
}
......@@ -204,7 +210,8 @@ STDMETHODIMP VLCOleObject::EnumAdvise(IEnumSTATDATA **ppEnumAdvise)
STDMETHODIMP VLCOleObject::EnumVerbs(IEnumOleVerb **ppEnumOleVerb)
{
return OLE_S_USEREG;
return OleRegEnumVerbs(_p_instance->getClassID(),
ppEnumOleVerb);
};
STDMETHODIMP VLCOleObject::GetClientSite(LPOLECLIENTSITE *ppClientSite)
......@@ -221,7 +228,7 @@ STDMETHODIMP VLCOleObject::GetClientSite(LPOLECLIENTSITE *ppClientSite)
STDMETHODIMP VLCOleObject::GetClipboardData(DWORD dwReserved, LPDATAOBJECT *ppDataObject)
{
return E_NOTIMPL;
return _p_instance->pUnkOuter->QueryInterface(IID_IDataObject, (void **)ppDataObject);
};
STDMETHODIMP VLCOleObject::GetExtent(DWORD dwDrawAspect, SIZEL *pSizel)
......@@ -241,7 +248,7 @@ STDMETHODIMP VLCOleObject::GetExtent(DWORD dwDrawAspect, SIZEL *pSizel)
STDMETHODIMP VLCOleObject::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
{
if( NULL != pdwStatus )
if( NULL == pdwStatus )
return E_POINTER;
switch( dwAspect )
......@@ -273,13 +280,14 @@ STDMETHODIMP VLCOleObject::GetUserClassID(LPCLSID pClsid)
if( NULL == pClsid )
return E_POINTER;
pClsid = const_cast<LPCLSID>(&_p_instance->getClassID());
*pClsid = _p_instance->getClassID();
return S_OK;
};
STDMETHODIMP VLCOleObject::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType)
{
return OLE_S_USEREG;
return OleRegGetUserType(_p_instance->getClassID(),
dwFormOfType, pszUserType);
};
STDMETHODIMP VLCOleObject::InitFromData(LPDATAOBJECT pDataObject, BOOL fCreation, DWORD dwReserved)
......@@ -294,7 +302,6 @@ STDMETHODIMP VLCOleObject::IsUpToDate(void)
STDMETHODIMP VLCOleObject::SetClientSite(LPOLECLIENTSITE pClientSite)
{
if( NULL != pClientSite )
{
pClientSite->AddRef();
......
......@@ -42,11 +42,11 @@ public:
*ppv = reinterpret_cast<LPVOID>(this);
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) Release(void) { return _p_instance->Release(); };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IOleObject methods
STDMETHODIMP Advise(IAdviseSink *, LPDWORD);
......
......@@ -44,11 +44,11 @@ public:
*ppv = reinterpret_cast<LPVOID>(this);
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) Release(void) { return _p_instance->Release(); };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IPersist methods
STDMETHODIMP GetClassID(LPCLSID);
......
......@@ -66,9 +66,6 @@ STDMETHODIMP VLCPersistStorage::Save(IStorage *pStg, BOOL fSameAsLoad)
STDMETHODIMP VLCPersistStorage::SaveCompleted(IStorage *pStg)
{
if( NULL == pStg )
return E_POINTER;
return S_OK;
};
......
......@@ -44,11 +44,11 @@ public:
*ppv = reinterpret_cast<LPVOID>(this);
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) Release(void) { return _p_instance->Release(); };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IPersist methods
STDMETHODIMP GetClassID(LPCLSID);
......
......@@ -44,11 +44,11 @@ public:
*ppv = reinterpret_cast<LPVOID>(this);
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) Release(void) { return _p_instance->Release(); };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IPersist methods
STDMETHODIMP GetClassID(LPCLSID);
......
This diff is collapsed.
......@@ -45,13 +45,14 @@ public:
STDMETHODIMP_(ULONG) Release(void);
/* IClassFactory methods */
STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv);
STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void **ppv);
STDMETHODIMP LockServer(BOOL fLock);
LPCSTR getInPlaceWndClassName(void) const { return TEXT("VLC Plugin In-Place"); };
LPCSTR getVideoWndClassName(void) const { return TEXT("VLC Plugin Video"); };
HINSTANCE getHInstance(void) const { return _hinstance; };
HBITMAP getInPlacePict(void) const { return _inplace_hbitmap; };
LPPICTURE getInPlacePict(void) const
{ if( NULL != _inplace_picture) _inplace_picture->AddRef(); return _inplace_picture; };
protected:
......@@ -63,7 +64,7 @@ private:
HINSTANCE _hinstance;
ATOM _inplace_wndclass_atom;
ATOM _video_wndclass_atom;
HBITMAP _inplace_hbitmap;
LPPICTURE _inplace_picture;
};
class VLCPlugin : public IUnknown
......@@ -71,7 +72,7 @@ class VLCPlugin : public IUnknown
public:
VLCPlugin(VLCPluginClass *p_class);
VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter);
/* IUnknown methods */
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
......@@ -107,15 +108,18 @@ public:
void setAutoStart(BOOL autostart) { _b_autostart = autostart; };
void setLoopMode(BOOL loopmode) { _b_loopmode = loopmode; };
void setMute(BOOL mute) { _b_mute = mute; };
void setSendEvents(BOOL sendevents) { _b_sendevents = sendevents; };
void setVisible(BOOL fVisible);
BOOL getVisible(void) { return _b_visible; };
LPPICTURE getPicture(void) { if( NULL != _pict ) _pict->AddRef(); return _pict; };
// container events
void onPositionChange(LPCRECT lprcPosRect, LPCRECT lprcClipRect);
void onDraw(DVTARGETDEVICE * ptd, HDC hicTargetDev,
HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds);
void onPaint(HDC hdc, const RECT &bounds, const RECT &pr);
// control events
void freezeEvents(BOOL freeze);
void firePropChangedEvent(DISPID dispid);
void fireOnPlayEvent(void);
void fireOnPauseEvent(void);
......@@ -128,6 +132,9 @@ public:
// control geometry within container
RECT getPosRect(void) { return _posRect; };
// controlling IUnknown interface
LPUNKNOWN pUnkOuter;
protected:
virtual ~VLCPlugin();
......@@ -147,6 +154,7 @@ private:
class VLCObjectSafety *vlcObjectSafety;
class VLCControl *vlcControl;
class VLCViewObject *vlcViewObject;
class VLCDataObject *vlcDataObject;
// in place activated window (Clipping window)
HWND _inplacewnd;
......@@ -156,13 +164,13 @@ private:
VLCPluginClass *_p_class;
ULONG _i_ref;
LPPICTURE _pict;
UINT _codepage;
char *_psz_src;
BOOL _b_autostart;
BOOL _b_loopmode;
BOOL _b_visible;
BOOL _b_mute;
BOOL _b_sendevents;
int _i_vlc;
SIZEL _extent;
......
......@@ -44,11 +44,11 @@ public:
*ppv = reinterpret_cast<LPVOID>(this);
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) Release(void) { return _p_instance->Release(); };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IProvideClassInfo methods
STDMETHODIMP GetClassInfo(ITypeInfo **);
......
......@@ -37,7 +37,7 @@ char *CStrFromBSTR(int codePage, BSTR bstr)
0, bstr, len, NULL, 0, NULL, NULL);
if( mblen > 0 )
{
char *buffer = (char *)malloc(mblen+1);
char *buffer = (char *)CoTaskMemAlloc(mblen+1);
ZeroMemory(buffer, mblen+1);
if( WideCharToMultiByte(codePage, 0, bstr, len, buffer, mblen, NULL, NULL) )
return buffer;
......@@ -51,7 +51,7 @@ BSTR BSTRFromCStr(int codePage, const char *s)
int wideLen = MultiByteToWideChar(codePage, 0, s, -1, NULL, 0);
if( wideLen )
{
WCHAR* wideStr = (WCHAR*)malloc(wideLen*sizeof(WCHAR));
WCHAR* wideStr = (WCHAR*)CoTaskMemAlloc(wideLen*sizeof(WCHAR));
if( NULL != wideStr )
{
BSTR bstr;
......
......@@ -99,6 +99,7 @@ VLCEnum<T>& VLCEnum<T>::operator=(const VLCEnum<T> &e)
this->_riid = e._riid;
this->_v = e._v;
this->_i = e._i;
return this;
};
template<class T>
......
......@@ -33,12 +33,7 @@ STDMETHODIMP VLCViewObject::Draw(DWORD dwAspect, LONG lindex, PVOID pvAspect,
{
if( dwAspect & DVASPECT_CONTENT )
{
RECT bounds;
bounds.left = lprcBounds->left;
bounds.top = lprcBounds->top;
bounds.right = lprcBounds->right;
bounds.bottom = lprcBounds->bottom;
_p_instance->onPaint(hdcDraw, bounds, bounds);
_p_instance->onDraw(ptd, hicTargetDev, hdcDraw, lprcBounds, lprcWBounds);
return S_OK;
}
return E_NOTIMPL;
......@@ -47,9 +42,6 @@ STDMETHODIMP VLCViewObject::Draw(DWORD dwAspect, LONG lindex, PVOID pvAspect,
STDMETHODIMP VLCViewObject::Freeze(DWORD dwAspect, LONG lindex,
PVOID pvAspect, LPDWORD pdwFreeze)
{
if( NULL != pvAspect )
return E_INVALIDARG;
return E_NOTIMPL;
};
......@@ -81,7 +73,6 @@ STDMETHODIMP VLCViewObject::GetColorSet(DWORD dwAspect, LONG lindex,
STDMETHODIMP VLCViewObject::SetAdvise(DWORD dwAspect, DWORD advf,
LPADVISESINK pAdvSink)
{
if( NULL != pAdvSink )
pAdvSink->AddRef();
......
......@@ -46,11 +46,11 @@ public:
*ppv = reinterpret_cast<LPVOID>(this);
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) Release(void) { return _p_instance->Release(); };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IViewObject methods
STDMETHODIMP Draw(DWORD,LONG,PVOID,DVTARGETDEVICE*,HDC,HDC,LPCRECTL,LPCRECTL,BOOL(CALLBACK *)(DWORD),DWORD);
......
......@@ -126,6 +126,26 @@ STDMETHODIMP VLCControl::play(void)
int i_vlc = _p_instance->getVLCObject();
if( i_vlc )
{
if( ! _p_instance->isInPlaceActive() )
{
/*
** object has not yet been activated. try doing it by ourself
** if parent container is known
*/
LPOLEOBJECT p_oleobject;
if( SUCCEEDED(QueryInterface(IID_IOleObject, (LPVOID *)&p_oleobject)) )
{
LPOLECLIENTSITE p_clientsite;
if( SUCCEEDED(p_oleobject->GetClientSite(&p_clientsite)
&& (NULL != p_clientsite)) )
{
p_oleobject->DoVerb(OLEIVERB_INPLACEACTIVATE,
NULL, p_clientsite, 0, NULL, NULL);
p_clientsite->Release();
}
p_oleobject->Release();
}
}
VLC_Play(i_vlc);
_p_instance->fireOnPlayEvent();
return NOERROR;
......@@ -442,9 +462,9 @@ STDMETHODIMP VLCControl::setVariable( BSTR name, VARIANT value)
hr = (VLC_SUCCESS == VLC_VariableSet(i_vlc, psz_varname, val)) ? NOERROR : E_FAIL;
if( (VLC_VAR_STRING == i_type) && (NULL != val.psz_string) )
free(val.psz_string);
CoTaskMemFree(val.psz_string);
}
free(psz_varname);
CoTaskMemFree(psz_varname);
return hr;
}
......@@ -501,7 +521,7 @@ STDMETHODIMP VLCControl::getVariable( BSTR name, VARIANT *value)
case VLC_VAR_VARIABLE:
V_VT(value) = VT_BSTR;
V_BSTR(value) = BSTRFromCStr(codePage, val.psz_string);
free(val.psz_string);
CoTaskMemFree(val.psz_string);
break;
case VLC_VAR_TIME:
......@@ -514,7 +534,7 @@ STDMETHODIMP VLCControl::getVariable( BSTR name, VARIANT *value)
hr = DISP_E_TYPEMISMATCH;
}
}
free(psz_varname);
CoTaskMemFree(psz_varname);
return hr;
}
return E_UNEXPECTED;
......@@ -523,16 +543,18 @@ STDMETHODIMP VLCControl::getVariable( BSTR name, VARIANT *value)
static void freeTargetOptions(char **cOptions, int cOptionCount)
{
// clean up
for( long pos=0; pos<cOptionCount; ++pos )
if( NULL != cOptions )
{
char *cOption = cOptions[pos];
if( NULL != cOption )
free(cOption);
else
break;
for( int pos=0; pos<cOptionCount; ++pos )
{
char *cOption = cOptions[pos];
if( NULL != cOption )
CoTaskMemFree(cOption);
else
break;
}
CoTaskMemFree(cOptions);
}
if( NULL != cOptions )
free(cOptions);
};
static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOptions, int *cOptionCount)
......@@ -571,7 +593,7 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
long capacity = 16;
VARIANT option;
*cOptions = (char **)malloc(capacity*sizeof(char *));
*cOptions = (char **)CoTaskMemAlloc(capacity*sizeof(char *));
if( NULL != *cOptions )
{
ZeroMemory(*cOptions, sizeof(char *)*capacity);
......@@ -586,7 +608,7 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
++pos;
if( pos == capacity )
{
char **moreOptions = (char **)realloc(*cOptions, (capacity+16)*sizeof(char *));
char **moreOptions = (char **)CoTaskMemRealloc(*cOptions, (capacity+16)*sizeof(char *));
if( NULL != moreOptions )
{
ZeroMemory(moreOptions+capacity, sizeof(char *)*16);
......@@ -598,7 +620,8 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
}
}
else
hr = E_OUTOFMEMORY;
hr = ( SysStringLen(V_BSTR(&option)) > 0 ) ?
E_OUTOFMEMORY : E_INVALIDARG;
}
else
hr = E_INVALIDARG;
......@@ -614,6 +637,7 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
}
else
hr = E_OUTOFMEMORY;
enumVar->Release();
}
}
......@@ -635,7 +659,7 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
if( uBound > lBound )
{
VARTYPE vType;
HRESULT hr = SafeArrayGetVartype(array, &vType);
hr = SafeArrayGetVartype(array, &vType);
if( FAILED(hr) )
return hr;
......@@ -644,10 +668,11 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
// marshall options into an array of C strings
if( VT_VARIANT == vType )
{
*cOptions = (char **)malloc(sizeof(char *)*(uBound-lBound));
if( NULL != options )
*cOptions = (char **)CoTaskMemAlloc(sizeof(char *)*(uBound-lBound));
if( NULL == *cOptions )
return E_OUTOFMEMORY;
ZeroMemory(*cOptions, sizeof(char *)*(uBound-lBound));
for(pos=lBound; SUCCEEDED(hr) && (pos<uBound); ++pos )
{
VARIANT option;
......@@ -659,7 +684,8 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
char *cOption = CStrFromBSTR(codePage, V_BSTR(&option));
(*cOptions)[pos-lBound] = cOption;
if( NULL == cOption )
hr = E_OUTOFMEMORY;
hr = ( SysStringLen(V_BSTR(&option)) > 0 ) ?
E_OUTOFMEMORY : E_INVALIDARG;
}
else
hr = E_INVALIDARG;
......@@ -669,28 +695,32 @@ static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOpti
}
else if( VT_BSTR == vType )
{
*cOptions = (char **)malloc(sizeof(char *)*(uBound-lBound));
if( NULL != options )
*cOptions = (char **)CoTaskMemAlloc(sizeof(char *)*(uBound-lBound));
if( NULL == *cOptions )
return E_OUTOFMEMORY;
ZeroMemory(cOptions, sizeof(char *)*(uBound-lBound));
for(pos=lBound; SUCCEEDED(hr) && (pos<uBound); ++pos )
ZeroMemory(*cOptions, sizeof(char *)*(uBound-lBound));
for(pos=lBound; (pos<uBound) && SUCCEEDED(hr); ++pos )
{
BSTR option;
hr = SafeArrayGetElement(array, &pos, &option);
if( SUCCEEDED(hr) )
{
char *cOption = CStrFromBSTR(codePage, option);
(*cOptions)[pos-lBound] = cOption;
if( NULL == cOption )
hr = E_OUTOFMEMORY;
hr = ( SysStringLen(option) > 0 ) ?
E_OUTOFMEMORY : E_INVALIDARG;
SysFreeString(option);
}
}
}
else
else
{
// unsupported type
return E_INVALIDARG;
}
*cOptionCount = pos-lBound;
if( FAILED(hr) )
......@@ -750,7 +780,7 @@ STDMETHODIMP VLCControl::addTarget( BSTR uri, VARIANT options, enum VLCPlaylistM
}
freeTargetOptions(cOptions, cOptionsCount);
free(cUri);
CoTaskMemFree(cUri);
}
return hr;
};
......@@ -778,6 +808,7 @@ STDMETHODIMP VLCControl::get_PlaylistCount(int *count)
*count = VLC_PlaylistNumberOfItems(i_vlc);
return NOERROR;
}
*count = 0;
return E_UNEXPECTED;
};
......
......@@ -42,14 +42,14 @@ public:
&& (IID_IDispatch == riid)
&& (IID_IVLCControl == riid) ) {
AddRef();
*ppv = dynamic_cast<LPVOID>(this);
*ppv = reinterpret_cast<LPVOID>(this);
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) Release(void) { return _p_instance->Release(); };
STDMETHODIMP_(ULONG) AddRef(void) { return _p_instance->pUnkOuter->AddRef(); };
STDMETHODIMP_(ULONG) Release(void) { return _p_instance->pUnkOuter->Release(); };
// IDispatch methods
STDMETHODIMP GetTypeInfoCount(UINT*);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment