⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connectioncontainer.cpp

📁 VLC Player Source Code
💻 CPP
字号:
/***************************************************************************** * connectioncontainer.cpp: ActiveX control for VLC ***************************************************************************** * Copyright (C) 2005 the VideoLAN team * * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/#include "plugin.h"#include "connectioncontainer.h"#include "utils.h"using namespace std;/////////////////////////////////////////////////////////////////////////////////////////////////* this function object is used to return the value from a map pair */struct VLCEnumConnectionsDereference{    CONNECTDATA operator()(const map<DWORD,LPUNKNOWN>::iterator& i)    {        CONNECTDATA cd;        i->second->AddRef();        cd.dwCookie = i->first;        cd.pUnk     = i->second;        return cd;    };};class VLCEnumConnections : public VLCEnumIterator<IID_IEnumConnections,    IEnumConnections,    CONNECTDATA,    map<DWORD,LPUNKNOWN>::iterator,    VLCEnumConnectionsDereference>{public:    VLCEnumConnections(map<DWORD,LPUNKNOWN> &m) :        VLCEnumIterator<IID_IEnumConnections,            IEnumConnections,            CONNECTDATA,            map<DWORD,LPUNKNOWN>::iterator,            VLCEnumConnectionsDereference> (m.begin(), m.end())    {};};/////////////////////////////////////////////////////////////////////////////////////////////////* this function object is used to retain the dereferenced iterator value */struct VLCEnumConnectionPointsDereference{    LPCONNECTIONPOINT operator()(const vector<LPCONNECTIONPOINT>::iterator& i)    {        LPCONNECTIONPOINT cp = *i;        cp->AddRef();        return cp;    }};class VLCEnumConnectionPoints: public VLCEnumIterator<IID_IEnumConnectionPoints,    IEnumConnectionPoints,    LPCONNECTIONPOINT,    vector<LPCONNECTIONPOINT>::iterator,    VLCEnumConnectionPointsDereference>{public:    VLCEnumConnectionPoints(vector<LPCONNECTIONPOINT>& v) :        VLCEnumIterator<IID_IEnumConnectionPoints,            IEnumConnectionPoints,            LPCONNECTIONPOINT,            vector<LPCONNECTIONPOINT>::iterator,            VLCEnumConnectionPointsDereference> (v.begin(), v.end())    {};};////////////////////////////////////////////////////////////////////////////////////////////////STDMETHODIMP VLCConnectionPoint::GetConnectionInterface(IID *iid){    if( NULL == iid )        return E_POINTER;    *iid = _iid;    return S_OK;};STDMETHODIMP VLCConnectionPoint::GetConnectionPointContainer(LPCONNECTIONPOINTCONTAINER *ppCPC){    if( NULL == ppCPC )        return E_POINTER;    _p_cpc->AddRef();    *ppCPC = _p_cpc;    return S_OK;};STDMETHODIMP VLCConnectionPoint::Advise(IUnknown *pUnk, DWORD *pdwCookie){    static DWORD dwCookieCounter = 0;    if( (NULL == pUnk) || (NULL == pdwCookie) )        return E_POINTER;    if( SUCCEEDED(pUnk->QueryInterface(_iid, (LPVOID *)&pUnk)) )    {        *pdwCookie = ++dwCookieCounter;        _connections[*pdwCookie] = pUnk;        return S_OK;    }    return CONNECT_E_CANNOTCONNECT;};STDMETHODIMP VLCConnectionPoint::Unadvise(DWORD pdwCookie){    map<DWORD,LPUNKNOWN>::iterator pcd = _connections.find((DWORD)pdwCookie);    if( pcd != _connections.end() )    {        pcd->second->Release();        _connections.erase(pdwCookie);        return S_OK;    }    return CONNECT_E_NOCONNECTION;};STDMETHODIMP VLCConnectionPoint::EnumConnections(IEnumConnections **ppEnum){    if( NULL == ppEnum )        return E_POINTER;    *ppEnum = dynamic_cast<LPENUMCONNECTIONS>(new VLCEnumConnections(_connections));    return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;};void VLCConnectionPoint::fireEvent(DISPID dispId, DISPPARAMS *pDispParams){    map<DWORD,LPUNKNOWN>::iterator end = _connections.end();    map<DWORD,LPUNKNOWN>::iterator iter = _connections.begin();    while( iter != end )    {        LPUNKNOWN pUnk = iter->second;        if( NULL != pUnk )        {            IDispatch *pDisp;            if( SUCCEEDED(pUnk->QueryInterface(_iid, (LPVOID *)&pDisp)) )            {                pDisp->Invoke(dispId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, pDispParams, NULL, NULL, NULL);                pDisp->Release();            }        }        ++iter;    }};void VLCConnectionPoint::firePropChangedEvent(DISPID dispId){    map<DWORD,LPUNKNOWN>::iterator end = _connections.end();    map<DWORD,LPUNKNOWN>::iterator iter = _connections.begin();    while( iter != end )    {        LPUNKNOWN pUnk = iter->second;        if( NULL != pUnk )        {            IPropertyNotifySink *pPropSink;            if( SUCCEEDED(pUnk->QueryInterface(IID_IPropertyNotifySink, (LPVOID *)&pPropSink)) )            {                pPropSink->OnChanged(dispId);                pPropSink->Release();            }        }        ++iter;    }};////////////////////////////////////////////////////////////////////////////////////////////////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), _b_freeze(FALSE){    _p_events = new VLCConnectionPoint(dynamic_cast<LPCONNECTIONPOINTCONTAINER>(this),            _p_instance->getDispEventID());    _v_cps.push_back(dynamic_cast<LPCONNECTIONPOINT>(_p_events));    _p_props = new VLCConnectionPoint(dynamic_cast<LPCONNECTIONPOINTCONTAINER>(this),            IID_IPropertyNotifySink);    _v_cps.push_back(dynamic_cast<LPCONNECTIONPOINT>(_p_props));};VLCConnectionPointContainer::~VLCConnectionPointContainer(){    delete _p_props;    delete _p_events;};STDMETHODIMP VLCConnectionPointContainer::EnumConnectionPoints(LPENUMCONNECTIONPOINTS *ppEnum){    if( NULL == ppEnum )        return E_POINTER;    *ppEnum = dynamic_cast<LPENUMCONNECTIONPOINTS>(new VLCEnumConnectionPoints(_v_cps));    return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;};STDMETHODIMP VLCConnectionPointContainer::FindConnectionPoint(REFIID riid, IConnectionPoint **ppCP){    if( NULL == ppCP )        return E_POINTER;    *ppCP = NULL;    if( IID_IPropertyNotifySink == riid )    {        _p_props->AddRef();        *ppCP = dynamic_cast<LPCONNECTIONPOINT>(_p_props);    }    else if( _p_instance->getDispEventID() == riid )    {        _p_events->AddRef();        *ppCP = dynamic_cast<LPCONNECTIONPOINT>(_p_events);    }    else        return CONNECT_E_NOCONNECTION;    return NOERROR;};void VLCConnectionPointContainer::freezeEvents(BOOL freeze){    if( ! freeze )    {        // release queued events        while( ! _q_events.empty() )        {            VLCDispatchEvent *ev = _q_events.front();            _q_events.pop();            _p_events->fireEvent(ev->_dispId, &ev->_dispParams);            delete ev;        }    }    _b_freeze = freeze;};void VLCConnectionPointContainer::fireEvent(DISPID dispId, DISPPARAMS* pDispParams){    if( _b_freeze )    {        // queue event for later use when container is ready        _q_events.push(new VLCDispatchEvent(dispId, *pDispParams));        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);    }};void VLCConnectionPointContainer::firePropChangedEvent(DISPID dispId){    if( ! _b_freeze )        _p_props->firePropChangedEvent(dispId);};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -