]> git.sesse.net Git - vlc/commitdiff
Improved compatibility
authorDamien Fouilleul <damienf@videolan.org>
Tue, 19 Jul 2005 17:41:16 +0000 (17:41 +0000)
committerDamien Fouilleul <damienf@videolan.org>
Tue, 19 Jul 2005 17:41:16 +0000 (17:41 +0000)
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

27 files changed:
activex/Makefile.am
activex/connectioncontainer.cpp
activex/connectioncontainer.h
activex/dataobject.cpp [new file with mode: 0644]
activex/dataobject.h [new file with mode: 0644]
activex/main.cpp
activex/objectsafety.cpp
activex/objectsafety.h
activex/olecontrol.cpp
activex/olecontrol.h
activex/oleinplaceactiveobject.h
activex/oleinplaceobject.h
activex/oleobject.cpp
activex/oleobject.h
activex/persistpropbag.h
activex/persiststorage.cpp
activex/persiststorage.h
activex/persiststreaminit.h
activex/plugin.cpp
activex/plugin.h
activex/provideclassinfo.h
activex/utils.cpp
activex/utils.h
activex/viewobject.cpp
activex/viewobject.h
activex/vlccontrol.cpp
activex/vlccontrol.h

index 55c6221d82ffc3627dcd1d2f0e4dd424005edde1..9586b6e0c29702003695ee8e0c958c0151f742b5 100644 (file)
@@ -32,6 +32,8 @@ SOURCES_activex = \
     connectioncontainer.h \
     objectsafety.cpp \
     objectsafety.h \
+    dataobject.cpp \
+    dataobject.h \
     viewobject.cpp \
     viewobject.h \
     vlccontrol.cpp \
index fdda1d5c738ba3be6c57798e91f2ea1943422950..308f2645579b46305358aa6f46a3fb184e877a2e 100644 (file)
@@ -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);
 };
 
index 09b276ffaaa9b26a03f65c20ac823e2071d16c47..3713e9ee77aea0ed8b4869ae5bbdfea980547985 100644 (file)
@@ -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
diff --git a/activex/dataobject.cpp b/activex/dataobject.cpp
new file mode 100644 (file)
index 0000000..49bf812
--- /dev/null
@@ -0,0 +1,288 @@
+/*****************************************************************************
+ * 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();
+};
+
diff --git a/activex/dataobject.h b/activex/dataobject.h
new file mode 100644 (file)
index 0000000..8921a63
--- /dev/null
@@ -0,0 +1,76 @@
+/*****************************************************************************
+ * 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
+
index 9f564fe504fe9d2a306d607eff6be9dc3b437ff4..e38fecbb5cf3f6de9e7e97b9ba866f181790ecb0 100644 (file)
@@ -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);
     }
 
index c6d266ed9fe149e0c5b405db9a5bafb3ca0db9e1..b6413f3ca59e529be79f6295020af6f7f8939895 100644 (file)
@@ -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,
index ad3a4360bd459205ad9ad543cf7c2f881a02283d..1550b869d0de6a711d8a5ea5e6c6b7d5dcd7a9a6 100644 (file)
@@ -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(      
index d61f6a7472cb12603b2f1eed4197096662ba5a9b..f7519df071d8fb2fa15e49462f49c40570785906 100644 (file)
@@ -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;
 };
 
index f09536df370a42fa60499ceb04dff8d9e764d036..f5dae7047cf00011bd1b92be643a8535b8170f37 100644 (file)
@@ -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);
index f5d63a8bd401e46ab1bf825ec7ca0b1d66cb878e..1cae175651da40da71d1e6a285e3f0beb5456285 100644 (file)
@@ -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 *);
index 24514ffd5f7280c6e36a3bce208ade0e85d8d1d7..6f523a4d5951e21f19100fa43b27880854ede2de 100644 (file)
@@ -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 *);
index b8666ff3d707f84222ba63349eb42b17f54e96dd..d31694a2f519ba77e072170eea30542bd30ee3bc 100644 (file)
@@ -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();
index 168f5455675f3812a7d5e58f5e3648c3e45eb0c8..c9814d21d30816d5b3247c27c66365e163eb35ff 100644 (file)
@@ -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);
index 32268ae1dcb5abeba611935020d165865fc2a604..2a69690581d2304737e62d0b72da25ec9bfec471 100644 (file)
@@ -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);
index efbfa6cc5af9287b5188f2d4520c8c5099014a11..9848ea5c1be788629c3848f709253a0e1cd7b7a6 100644 (file)
@@ -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;
 };
 
index 12c12288cecadd920a182c3ed8f3892adcd2dc33..08b5000516a6202066937c14bbe34350ef7529dc 100644 (file)
@@ -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);
index cc3804e44949fde0ea556f3d195bf19a29926939..ead8c111b6423ff4de5bbacf911e6bb0c554899d 100644 (file)
@@ -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);
index 486eec8bebcf28272bec54ce0dad948c43665cc8..632592da9ce7bb0ad5d78a531dff9fac2560ab72 100644 (file)
@@ -34,6 +34,7 @@
 #include "objectsafety.h"
 #include "vlccontrol.h"
 #include "viewobject.h"
+#include "dataobject.h"
 
 #include "utils.h"
 
@@ -141,8 +142,19 @@ VLCPluginClass::VLCPluginClass(LONG *p_class_ref, HINSTANCE hInstance) :
         _video_wndclass_atom = 0;
     }
 
-    _inplace_hbitmap = (HBITMAP)LoadImage(getHInstance(), TEXT("INPLACE-PICT"), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
+    HBITMAP hbitmap = (HBITMAP)LoadImage(getHInstance(), TEXT("INPLACE-PICT"), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
+    if( NULL != hbitmap )
+    {
+        PICTDESC pictDesc;
+
+        pictDesc.cbSizeofstruct = sizeof(PICTDESC);
+        pictDesc.picType        = PICTYPE_BITMAP;
+        pictDesc.bmp.hbitmap    = hbitmap;
+        pictDesc.bmp.hpal       = NULL;
 
+        if( FAILED(OleCreatePictureIndirect(&pictDesc, IID_IPicture, TRUE, reinterpret_cast<LPVOID*>(&_inplace_picture))) )
+            _inplace_picture = NULL;
+    }
     AddRef();
 };
 
@@ -154,8 +166,8 @@ VLCPluginClass::~VLCPluginClass()
     if( 0 != _video_wndclass_atom )
         UnregisterClass(MAKEINTATOM(_video_wndclass_atom), _hinstance);
 
-    if( NULL != _inplace_hbitmap )
-        DeleteObject(_inplace_hbitmap);
+    if( NULL != _inplace_picture )
+        _inplace_picture->Release();
 };
 
 STDMETHODIMP VLCPluginClass::QueryInterface(REFIID riid, void **ppv)
@@ -192,17 +204,18 @@ STDMETHODIMP_(ULONG) VLCPluginClass::Release(void)
     return refcount;
 };
 
-STDMETHODIMP VLCPluginClass::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv)
+STDMETHODIMP VLCPluginClass::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void **ppv)
 {
     if( NULL == ppv )
         return E_POINTER;
 
     *ppv = NULL;
 
-    if( NULL != pUnkOuter )
+    if( (NULL != pUnkOuter) && (IID_IUnknown != riid) ) {
         return CLASS_E_NOAGGREGATION;
+    }
 
-    VLCPlugin *plugin = new VLCPlugin(this);
+    VLCPlugin *plugin = new VLCPlugin(this, pUnkOuter);
     if( NULL != plugin )
     {
         HRESULT hr = plugin->QueryInterface(riid, ppv);
@@ -224,7 +237,7 @@ STDMETHODIMP VLCPluginClass::LockServer(BOOL fLock)
 
 ////////////////////////////////////////////////////////////////////////
 
-VLCPlugin::VLCPlugin(VLCPluginClass *p_class) :
+VLCPlugin::VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter) :
     _inplacewnd(NULL),
     _p_class(p_class),
     _i_ref(1UL),
@@ -234,7 +247,6 @@ VLCPlugin::VLCPlugin(VLCPluginClass *p_class) :
     _b_loopmode(FALSE),
     _b_visible(TRUE),
     _b_mute(FALSE),
-    _b_sendevents(TRUE),
     _i_vlc(0)
 {
     p_class->AddRef();
@@ -251,6 +263,13 @@ VLCPlugin::VLCPlugin(VLCPluginClass *p_class) :
     vlcObjectSafety = new VLCObjectSafety(this);
     vlcControl = new VLCControl(this);
     vlcViewObject = new VLCViewObject(this);
+    vlcDataObject = new VLCDataObject(this);
+
+    // configure controlling IUnknown interface for implemented interfaces
+    this->pUnkOuter = (NULL != pUnkOuter) ? pUnkOuter : dynamic_cast<LPUNKNOWN>(this);
+
+    // default picure
+    _pict = p_class->getInPlacePict();
 
     // set default/preferred size (320x240) pixels in HIMETRIC
     HDC hDC = CreateDevDC(NULL);
@@ -264,6 +283,7 @@ VLCPlugin::~VLCPlugin()
     vlcOleInPlaceObject->UIDeactivate();
     vlcOleInPlaceObject->InPlaceDeactivate();
 
+    delete vlcDataObject;
     delete vlcViewObject;
     delete vlcControl;
     delete vlcObjectSafety;
@@ -277,6 +297,9 @@ VLCPlugin::~VLCPlugin()
     delete vlcOleControl;
     delete vlcOleObject;
 
+    if( _pict )
+        _pict->Release();
+
     if( _psz_src )
         free(_psz_src);
 
@@ -289,117 +312,50 @@ STDMETHODIMP VLCPlugin::QueryInterface(REFIID riid, void **ppv)
         return E_INVALIDARG;
 
     if( IID_IUnknown == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(this);
-        return NOERROR;
-    }
     else if( IID_IOleObject == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcOleObject);
-        return NOERROR;
-    }
     else if( IID_IOleControl == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcOleControl);
-        return NOERROR;
-    }
     else if( IID_IOleWindow == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcOleInPlaceObject);
-        return NOERROR;
-    }
     else if( IID_IOleInPlaceObject == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcOleInPlaceObject);
-        return NOERROR;
-    }
     else if( IID_IOleInPlaceActiveObject == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcOleInPlaceActiveObject);
-        return NOERROR;
-    }
     else if( IID_IPersist == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcPersistPropertyBag);
-        return NOERROR;
-    }
     else if( IID_IPersistStreamInit == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcPersistStreamInit);
-        return NOERROR;
-    }
     else if( IID_IPersistStorage == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcPersistStorage);
-        return NOERROR;
-    }
     else if( IID_IPersistPropertyBag == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcPersistPropertyBag);
-        return NOERROR;
-    }
     else if( IID_IProvideClassInfo == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcProvideClassInfo);
-        return NOERROR;
-    }
     else if( IID_IProvideClassInfo2 == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcProvideClassInfo);
-        return NOERROR;
-    }
     else if( IID_IConnectionPointContainer == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcConnectionPointContainer);
-        return NOERROR;
-    }
     else if( IID_IObjectSafety == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcObjectSafety);
-        return NOERROR;
-    }
     else if( IID_IDispatch == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcControl);
-        return NOERROR;
-    }
     else if( IID_IVLCControl == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcControl);
-        return NOERROR;
-    }
     else if( IID_IViewObject == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcViewObject);
-        return NOERROR;
-    }
     else if( IID_IViewObject2 == riid )
-    {
-        AddRef();
         *ppv = reinterpret_cast<LPVOID>(vlcViewObject);
-        return NOERROR;
+    else if( IID_IDataObject == riid )
+        *ppv = reinterpret_cast<LPVOID>(vlcDataObject);
+    else
+    {
+        *ppv = NULL;
+        return E_NOINTERFACE;
     }
-
-    *ppv = NULL;
-
-    return E_NOINTERFACE;
+    ((LPUNKNOWN)*ppv)->AddRef();
+    return NOERROR;
 };
 
 STDMETHODIMP_(ULONG) VLCPlugin::AddRef(void)
@@ -538,7 +494,7 @@ HRESULT VLCPlugin::onInit(void)
              RegCloseKey( h_key );
         }
 
-#if 0
+#if 1
         ppsz_argv[0] = "C:\\cygwin\\home\\Damien_Fouilleul\\dev\\videolan\\vlc-trunk\\vlc";
 #endif
 
@@ -552,7 +508,7 @@ HRESULT VLCPlugin::onInit(void)
         }
         return S_OK;
     }
-    return E_UNEXPECTED;
+    return CO_E_ALREADYINITIALIZED;
 };
 
 HRESULT VLCPlugin::onLoad(void)
@@ -581,7 +537,7 @@ HRESULT VLCPlugin::onClientSiteChanged(LPOLECLIENTSITE pActiveSite)
     {
         /*
         ** object is embedded in container 
-        ** try to activate in place if it has initialized
+        ** try to activate in place if it has already been initialized
         */
         if( _i_vlc )
         {
@@ -595,14 +551,17 @@ HRESULT VLCPlugin::onClose(DWORD dwSaveOption)
 {
     if( _i_vlc )
     {
+        int i_vlc = _i_vlc;
+
+        _i_vlc = 0;
         if( isInPlaceActive() )
         {
             onInPlaceDeactivate();
         }
+        vlcDataObject->onClose();
 
-        VLC_CleanUp(_i_vlc);
-        VLC_Destroy(_i_vlc);
-        _i_vlc = 0;
+        VLC_CleanUp(i_vlc);
+        VLC_Destroy(i_vlc);
     }
     return S_OK;
 };
@@ -724,54 +683,100 @@ BOOL VLCPlugin::hasFocus(void)
     return GetActiveWindow() == _inplacewnd;
 };
 
-void VLCPlugin::onPaint(HDC hdc, const RECT &bounds, const RECT &pr)
+void VLCPlugin::onDraw(DVTARGETDEVICE * ptd, HDC hicTargetDev,
+        HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds)
 {
     if( getVisible() )
     {
-        /*
-        ** if VLC is playing, it may not display any VIDEO content 
-        ** hence, draw control logo
-        */ 
-        int width = bounds.right-bounds.left;
-        int height = bounds.bottom-bounds.top;
+        long width = lprcBounds->right-lprcBounds->left;
+        long height = lprcBounds->bottom-lprcBounds->top;
+
+        SIZEL devSize;
+        if( NULL != hicTargetDev ) {
+            devSize.cx = GetDeviceCaps(hicTargetDev, LOGPIXELSX);
+            devSize.cy = GetDeviceCaps(hicTargetDev, LOGPIXELSY);
+        }
+        else if( NULL != (hicTargetDev = CreateDevDC(ptd)) )
+        {
+            devSize.cx = GetDeviceCaps(hicTargetDev, LOGPIXELSX);
+            devSize.cy = GetDeviceCaps(hicTargetDev, LOGPIXELSY);
+            DeleteDC(hicTargetDev);
+        }
+
+        RECT bounds = { lprcBounds->left, lprcBounds->top, lprcBounds->right, lprcBounds->bottom };
+        FillRect(hdcDraw, &bounds, (HBRUSH)GetStockObject(WHITE_BRUSH));
 
-        HBITMAP pict = _p_class->getInPlacePict();
+        LPPICTURE pict = getPicture();
         if( NULL != pict )
         {
-            HDC hdcPict = CreateCompatibleDC(hdc);
-            if( NULL != hdcPict )
+            OLE_XSIZE_HIMETRIC picWidth;
+            OLE_YSIZE_HIMETRIC picHeight;
+
+            pict->get_Width(&picWidth);
+            pict->get_Height(&picHeight);
+
+            POINT dstSize = { picWidth*devSize.cx/2540L, picHeight*devSize.cy/2540L };
+
+            DPtoLP(hdcDraw, &dstSize, 1);
+            if( dstSize.x > width-4 )
+                dstSize.x = width-4;
+            if( dstSize.y > height-4 )
+                dstSize.y = height-4;
+
+            long dstX = lprcBounds->left+(width-dstSize.x)/2;
+            long dstY = lprcBounds->top+(height-dstSize.y)/2;
+
+            if( NULL != lprcWBounds )
             {
-                BITMAP bm;
-                if( GetObject(pict, sizeof(BITMAPINFO), &bm) )
-                {
-                    int dstWidth = bm.bmWidth;
-                    if( dstWidth > width-4 )
-                        dstWidth = width-4;
-
-                    int dstHeight = bm.bmHeight;
-                    if( dstHeight > height-4 )
-                        dstHeight = height-4;
-
-                    int dstX = bounds.left+(width-dstWidth)/2;
-                    int dstY = bounds.top+(height-dstHeight)/2;
-
-                    SelectObject(hdcPict, pict);
-                    StretchBlt(hdc, dstX, dstY, dstWidth, dstHeight,
-                            hdcPict, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
-                    DeleteDC(hdcPict);
-                    ExcludeClipRect(hdc, dstX, dstY, dstWidth+dstX, dstHeight+dstY);
-                }
+                RECT wBounds = { lprcWBounds->left, lprcWBounds->top, lprcWBounds->right, lprcWBounds->bottom };
+                pict->Render(hdcDraw, dstX, dstY, dstSize.x, dstSize.y,
+                        0L, picHeight, picWidth, -picHeight, &wBounds);
             }
+            else 
+                pict->Render(hdcDraw, dstX, dstY, dstSize.x, dstSize.y,
+                        0L, picHeight, picWidth, -picHeight, NULL);
+
+            pict->Release();
         }
 
-        FillRect(hdc, &pr, (HBRUSH)GetStockObject(WHITE_BRUSH));
-        SelectObject(hdc, GetStockObject(BLACK_BRUSH));
+        SelectObject(hdcDraw, GetStockObject(BLACK_BRUSH));
 
-        MoveToEx(hdc, bounds.left, bounds.top, NULL);
-        LineTo(hdc, bounds.left+width-1, bounds.top);
-        LineTo(hdc, bounds.left+width-1, bounds.top+height-1);
-        LineTo(hdc, bounds.left, bounds.top+height-1);
-        LineTo(hdc, bounds.left, bounds.top);
+        MoveToEx(hdcDraw, bounds.left, bounds.top, NULL);
+        LineTo(hdcDraw, bounds.left+width-1, bounds.top);
+        LineTo(hdcDraw, bounds.left+width-1, bounds.top+height-1);
+        LineTo(hdcDraw, bounds.left, bounds.top+height-1);
+        LineTo(hdcDraw, bounds.left, bounds.top);
+    }
+};
+
+void VLCPlugin::onPaint(HDC hdc, const RECT &bounds, const RECT &clipRect)
+{
+    if( getVisible() )
+    {
+        /** if VLC is playing, it may not display any VIDEO content 
+        ** hence, draw control logo*/
+        HDC hdcPict = CreateCompatibleDC(hdc);
+        if( NULL != hdcPict )
+        {
+            int width = bounds.right-bounds.left;
+            int height = bounds.bottom-bounds.top;
+            HBITMAP hBitmap = CreateCompatibleBitmap(hdc, width, height);
+            if( NULL != hBitmap )
+            {
+                HBITMAP oldBmp = (HBITMAP)SelectObject(hdcPict, hBitmap);
+
+                RECTL rcBounds = { bounds.left, bounds.top, bounds.right, bounds.bottom };
+
+                onDraw(NULL, hdc, hdcPict, &rcBounds, NULL);
+
+                BitBlt(hdc, bounds.left, bounds.top, width, height,
+                        hdcPict, 0, 0, SRCCOPY);
+
+                SelectObject(hdcPict, oldBmp);
+                DeleteObject(hBitmap);
+            }
+            DeleteDC(hdcPict);
+        }
     }
 };
 
@@ -831,38 +836,31 @@ void VLCPlugin::onPositionChange(LPCRECT lprcPosRect, LPCRECT lprcClipRect)
     UpdateWindow(_videownd);
 };
 
+void VLCPlugin::freezeEvents(BOOL freeze)
+{
+    vlcConnectionPointContainer->freezeEvents(freeze);
+};
+
 void VLCPlugin::firePropChangedEvent(DISPID dispid)
 {
-    if( _b_sendevents )
-    {
-        vlcConnectionPointContainer->firePropChangedEvent(dispid); 
-    }
+    vlcConnectionPointContainer->firePropChangedEvent(dispid); 
 };
 
 void VLCPlugin::fireOnPlayEvent(void)
 {
-    if( _b_sendevents )
-    {
-        DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
-        vlcConnectionPointContainer->fireEvent(DISPID_PlayEvent, &dispparamsNoArgs); 
-    }
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_PlayEvent, &dispparamsNoArgs); 
 };
 
 void VLCPlugin::fireOnPauseEvent(void)
 {
-    if( _b_sendevents )
-    {
-        DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
-        vlcConnectionPointContainer->fireEvent(DISPID_PauseEvent, &dispparamsNoArgs); 
-    }
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_PauseEvent, &dispparamsNoArgs); 
 };
 
 void VLCPlugin::fireOnStopEvent(void)
 {
-    if( _b_sendevents )
-    {
-        DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
-        vlcConnectionPointContainer->fireEvent(DISPID_StopEvent, &dispparamsNoArgs); 
-    }
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_StopEvent, &dispparamsNoArgs); 
 };
 
index dc8220c26f99f3352d0dc3493590928864a59055..0e5c9d1976ecba747d7f5779ea7b271f9e773069 100644 (file)
@@ -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;
index 63ff0e3eb854263a95aafaf04bc718a4a222a7fd..654d96fe69ea5f0821a2e2a056fa5dbc6319d8ad 100644 (file)
@@ -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 **);
index 64b62cdf49111cdc5ff2dad9ac7937e3d573b2e5..ad9708a9dc8ed4fa8f8f1a4f29b0e57db1b2932b 100644 (file)
@@ -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;
index 0b98fc40b459488289ad8fd75d6d470a6c38e4e0..1aad39e6f82599217db5a28b5d3208b786ba49e8 100644 (file)
@@ -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>
index 1799ca212dd2115ab242565ac2a1595ae31ce1d1..42d3daff427c5e7f3b0313ffb8457f083bff8ad4 100644 (file)
@@ -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();
 
index d9975057b67713293ab2ea51e3e2eb73473866ab..501c035591a6e976f357adb481d904bb78fb8385 100644 (file)
@@ -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);
index b25b83aec7521866703f2de4181e0ce4797c028f..3ae440fc237bb106f75bad2d0a8fda650868aa24 100644 (file)
@@ -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;
 };
         
index 988d5e6214b56a9706e4cde6a6d3555e545f889d..6cd174514b5a3b0aa136a4d246d9dbc18c7ec1b7 100644 (file)
@@ -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*);