380 lines
11 KiB
C
380 lines
11 KiB
C
|
//==========================================================================;
|
||
|
//
|
||
|
// Devices.h : Declaration of the CDevices
|
||
|
// Copyright (c) Microsoft Corporation 1999.
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#ifndef DEVICES_H_
|
||
|
#define DEVICES_H_
|
||
|
|
||
|
#include <vector>
|
||
|
#include <objectwithsiteimplsec.h>
|
||
|
#include "devseq.h"
|
||
|
|
||
|
#if 0
|
||
|
#define DEBUGREGISTRY
|
||
|
#endif
|
||
|
|
||
|
#ifdef DEBUGREGISTRY
|
||
|
#include <statreg.h>
|
||
|
#endif
|
||
|
|
||
|
void CtorStaticVWDevicesFwdSeqPMFs(void);
|
||
|
void DtorStaticVWDevicesFwdSeqPMFs(void);
|
||
|
|
||
|
template<class DEVICETYPECOLLECTIONINTERFACE,
|
||
|
class DEVICETYPEINTERFACE,
|
||
|
const CLSID* DEVICETYPE_CLSID,
|
||
|
int IDSPROGID,
|
||
|
int IDSDESC> class CTypedDevices;
|
||
|
|
||
|
template<class DEVICETYPECOLLECTIONINTERFACE, class DEVICETYPEINTERFACE, const CLSID* DEVICETYPE_CLSID, int IDSPROGID, int IDSDESC> class ATL_NO_VTABLE CTypedDevicesBase :
|
||
|
public CComObjectRootEx<CComSingleThreadModel>,
|
||
|
public CComCoClass<CTypedDevices<DEVICETYPECOLLECTIONINTERFACE, DEVICETYPEINTERFACE, DEVICETYPE_CLSID, IDSPROGID, IDSDESC>, DEVICETYPE_CLSID>,
|
||
|
public ISupportErrorInfo,
|
||
|
public IObjectWithSiteImplSec<CTypedDevicesBase>,
|
||
|
public IDispatchImpl<DEVICETYPECOLLECTIONINTERFACE, &__uuidof(DEVICETYPECOLLECTIONINTERFACE), &LIBID_MSVidCtlLib>
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||
|
|
||
|
BEGIN_COM_MAP(CTypedDevicesBase)
|
||
|
COM_INTERFACE_ENTRY(DEVICETYPECOLLECTIONINTERFACE)
|
||
|
COM_INTERFACE_ENTRY(IDispatch)
|
||
|
COM_INTERFACE_ENTRY(IObjectWithSite)
|
||
|
COM_INTERFACE_ENTRY(ISupportErrorInfo)
|
||
|
END_COM_MAP()
|
||
|
|
||
|
BEGIN_CATEGORY_MAP(CTypedDevicesBase)
|
||
|
IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
|
||
|
IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)
|
||
|
IMPLEMENTED_CATEGORY(CATID_PersistsToPropertyBag)
|
||
|
END_CATEGORY_MAP()
|
||
|
|
||
|
// ISupportsErrorInfo
|
||
|
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
|
||
|
{
|
||
|
static const IID* arr[] =
|
||
|
{
|
||
|
&__uuidof(DEVICETYPECOLLECTIONINTERFACE)
|
||
|
};
|
||
|
for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
|
||
|
{
|
||
|
if (InlineIsEqualGUID(*arr[i],riid))
|
||
|
return S_OK;
|
||
|
}
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
virtual ~CTypedDevicesBase() {}
|
||
|
|
||
|
};
|
||
|
|
||
|
class CDevEnum;
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CTypedDevices
|
||
|
template<class DEVICETYPECOLLECTIONINTERFACE,
|
||
|
class DEVICETYPEINTERFACE,
|
||
|
const CLSID* DEVICETYPE_CLSID,
|
||
|
int IDSPROGID,
|
||
|
int IDSDESC> class CTypedDevices :
|
||
|
public CComObject<CTypedDevicesBase<DEVICETYPECOLLECTIONINTERFACE, DEVICETYPEINTERFACE, DEVICETYPE_CLSID, IDSPROGID, IDSDESC> >
|
||
|
{
|
||
|
typedef CComQIPtr<DEVICETYPECOLLECTIONINTERFACE> PQDEVICETYPECOLLECTIONINTERFACE;
|
||
|
typedef CComQIPtr<DEVICETYPEINTERFACE> PQDEVICETYPEINTERFACE;
|
||
|
PQDEVICETYPECOLLECTIONINTERFACE m_Collection;
|
||
|
bool m_fRO;
|
||
|
bool m_fValid;
|
||
|
public:
|
||
|
CTypedDevices(const DeviceCollection &Devices = DeviceCollection(), bool fRO = false, bool fValid = false) :
|
||
|
m_fRO(fRO), m_fValid(fValid) {
|
||
|
m_Devices.clear();
|
||
|
m_Devices.insert(m_Devices.end(), Devices.begin(), Devices.end());
|
||
|
}
|
||
|
CTypedDevices(bool fRO, bool fValid = false) :
|
||
|
m_Devices(DeviceCollection()), m_fRO(fRO), m_fValid(fValid) {}
|
||
|
CTypedDevices(const CTypedDevices &src) :
|
||
|
m_fRO(src.m_fRO), m_fValid(src.m_fValid) {
|
||
|
m_Devices.clear();
|
||
|
m_Devices.insert(m_Devices.end(), src.m_Devices.begin(), src.m_Devices.end());
|
||
|
}
|
||
|
CTypedDevices(const PQDEVICETYPECOLLECTIONINTERFACE& src) :
|
||
|
m_fRO(static_cast<CTypedDevices<DEVICETYPECOLLECTIONINTERFACE,
|
||
|
DEVICETYPEINTERFACE,
|
||
|
DEVICETYPE_CLSID,
|
||
|
IDSPROGID,
|
||
|
IDSDESC> *>(src.p)->m_fRO),
|
||
|
m_fValid(static_cast<CTypedDevices<DEVICETYPECOLLECTIONINTERFACE,
|
||
|
DEVICETYPEINTERFACE,
|
||
|
DEVICETYPE_CLSID,
|
||
|
IDSPROGID,
|
||
|
IDSDESC> *>(src.p)->m_fValid) {
|
||
|
m_Devices.clear();
|
||
|
m_Devices.insert(m_Devices.end(),
|
||
|
static_cast<CTypedDevices<DEVICETYPECOLLECTIONINTERFACE,
|
||
|
DEVICETYPEINTERFACE,
|
||
|
DEVICETYPE_CLSID,
|
||
|
IDSPROGID,
|
||
|
IDSDESC> *>(src.p)->m_Devices.begin(),
|
||
|
static_cast<CTypedDevices<DEVICETYPECOLLECTIONINTERFACE,
|
||
|
DEVICETYPEINTERFACE,
|
||
|
DEVICETYPE_CLSID,
|
||
|
IDSPROGID,
|
||
|
IDSDESC> *>(src.p)->m_Devices.end()
|
||
|
);
|
||
|
}
|
||
|
CTypedDevices<DEVICETYPECOLLECTIONINTERFACE, DEVICETYPEINTERFACE, DEVICETYPE_CLSID, IDSPROGID, IDSDESC> &operator=(const CTypedDevices<DEVICETYPECOLLECTIONINTERFACE, DEVICETYPEINTERFACE, DEVICETYPE_CLSID, IDSPROGID, IDSDESC> &rhs) {
|
||
|
if (this != &rhs) {
|
||
|
m_Devices.clear();
|
||
|
m_Devices.insert(m_Devices.end(), rhs.m_Devices.begin(), rhs.m_Devices.end());
|
||
|
m_fRO = rhs.m_fRO;
|
||
|
m_fValid = rhs.m_fValid;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
virtual ~CTypedDevices() {
|
||
|
}
|
||
|
|
||
|
static HRESULT WINAPI UpdateRegistry(BOOL bRegister) {
|
||
|
CRegObject ro;
|
||
|
return CObjRegHelp::RegisterAutomationClass(bRegister ? true : false,
|
||
|
ro,
|
||
|
IDS_PROJNAME,
|
||
|
IDSPROGID,
|
||
|
IDSDESC,
|
||
|
*DEVICETYPE_CLSID,
|
||
|
LIBID_MSVidCtlLib);
|
||
|
}
|
||
|
|
||
|
// IMSVidDevices
|
||
|
public:
|
||
|
inline bool IsRO() { return m_fRO; }
|
||
|
inline bool GetValid() { return m_fValid; }
|
||
|
inline void SetValid(bool fValid) { m_fValid = fValid; }
|
||
|
__declspec(property(get=GetValid, put=SetValid)) bool Valid;
|
||
|
DeviceCollection m_Devices;
|
||
|
// IMSVidDevices
|
||
|
STDMETHOD(get_Count)(LONG * lCount)
|
||
|
{
|
||
|
if (lCount == NULL)
|
||
|
return E_POINTER;
|
||
|
|
||
|
try {
|
||
|
*lCount = m_Devices.size();
|
||
|
} catch(...) {
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP get__NewEnum(IEnumVARIANT * * pD)
|
||
|
{
|
||
|
if (pD == NULL)
|
||
|
return E_POINTER;
|
||
|
|
||
|
PQEnumVARIANT temp;
|
||
|
try {
|
||
|
temp = new CDevEnum(PQDispatch(this), m_Devices);
|
||
|
} catch(...) {
|
||
|
return E_OUTOFMEMORY;
|
||
|
}
|
||
|
try {
|
||
|
*pD = temp.Detach();
|
||
|
} catch(...) {
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
STDMETHOD(get_Item)(VARIANT v, DEVICETYPEINTERFACE * * pDB)
|
||
|
{
|
||
|
if (pDB == NULL)
|
||
|
return E_POINTER;
|
||
|
int idx;
|
||
|
CComVariant vidx;
|
||
|
try {
|
||
|
if (SUCCEEDED(vidx.ChangeType(VT_I4, &v))) {
|
||
|
idx = vidx.lVal;
|
||
|
} else {
|
||
|
return DISP_E_TYPEMISMATCH;
|
||
|
}
|
||
|
if (idx >= m_Devices.size()) {
|
||
|
return DISP_E_BADINDEX;
|
||
|
}
|
||
|
} catch(...) {
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
try {
|
||
|
PQDevice pd(m_Devices[idx]);
|
||
|
if (!pd) {
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
*pDB = PQDEVICETYPEINTERFACE(pd);
|
||
|
if (!*pDB) {
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
(*pDB)->AddRef();
|
||
|
} catch(...) {
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
|
||
|
return NOERROR;
|
||
|
}
|
||
|
STDMETHOD(Add)(DEVICETYPEINTERFACE * pDB)
|
||
|
{
|
||
|
if (m_fRO) {
|
||
|
return Error(IDS_E_ROCOLLECTION, __uuidof(DEVICETYPECOLLECTIONINTERFACE), E_ACCESSDENIED);
|
||
|
}
|
||
|
try {
|
||
|
PQDevice p(pDB);
|
||
|
try {
|
||
|
m_Devices.push_back(p);
|
||
|
} catch(...) {
|
||
|
return E_OUTOFMEMORY;
|
||
|
}
|
||
|
} catch(...) {
|
||
|
E_POINTER;
|
||
|
}
|
||
|
|
||
|
return NOERROR;
|
||
|
}
|
||
|
STDMETHOD(Remove)(VARIANT v)
|
||
|
{
|
||
|
if (m_fRO) {
|
||
|
return E_ACCESSDENIED;
|
||
|
}
|
||
|
|
||
|
int idx;
|
||
|
CComVariant vidx;
|
||
|
try {
|
||
|
if (SUCCEEDED(vidx.ChangeType(VT_I4, &v))) {
|
||
|
idx = vidx.lVal;
|
||
|
} else {
|
||
|
return DISP_E_TYPEMISMATCH;
|
||
|
}
|
||
|
if (idx >= m_Devices.size()) {
|
||
|
return DISP_E_BADINDEX;
|
||
|
}
|
||
|
|
||
|
m_Devices.erase(m_Devices.begin() + idx);
|
||
|
} catch(...) {
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
return NOERROR;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
typedef CTypedDevices<IMSVidInputDevices, IMSVidInputDevice, &CLSID_MSVidInputDevices, IDS_INPUTDEVICES_PROGID, IDS_INPUTDEVICES_DESCRIPTION> CInputDevices;
|
||
|
typedef CTypedDevices<IMSVidOutputDevices, IMSVidOutputDevice, &CLSID_MSVidOutputDevices, IDS_OUTPUTDEVICES_PROGID, IDS_OUTPUTDEVICES_DESCRIPTION> COutputDevices;
|
||
|
typedef CTypedDevices<IMSVidVideoRendererDevices, IMSVidVideoRenderer, &CLSID_MSVidVideoRendererDevices, IDS_VIDEORENDERERS_PROGID, IDS_VIDEORENDERERS_DESCRIPTION> CVideoRendererDevices;
|
||
|
typedef CTypedDevices<IMSVidAudioRendererDevices, IMSVidAudioRenderer, &CLSID_MSVidAudioRendererDevices, IDS_AUDIORENDERERS_PROGID, IDS_AUDIORENDERERS_DESCRIPTION> CAudioRendererDevices;
|
||
|
typedef CTypedDevices<IMSVidFeatures, IMSVidFeature, &CLSID_MSVidFeatures, IDS_FEATURES_PROGID, IDS_FEATURES_DESCRIPTION> CFeatures;
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CDevEnum
|
||
|
class ATL_NO_VTABLE CDevEnumBase :
|
||
|
public CComObjectRootEx<CComSingleThreadModel>,
|
||
|
public IObjectWithSiteImplSec<CDevEnumBase>,
|
||
|
public IEnumVARIANT
|
||
|
{
|
||
|
BEGIN_COM_MAP(CDevEnumBase)
|
||
|
COM_INTERFACE_ENTRY(IEnumVARIANT)
|
||
|
COM_INTERFACE_ENTRY(IObjectWithSite)
|
||
|
END_COM_MAP()
|
||
|
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||
|
|
||
|
virtual ~CDevEnumBase() {}
|
||
|
};
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
class CDevEnum : public CComObject<CDevEnumBase>
|
||
|
{
|
||
|
public:
|
||
|
CDevEnum(const PQDispatch& pDevices, DeviceCollection& dci) :
|
||
|
m_pDevices(pDevices), m_DC(dci), i(dci.begin()) {}
|
||
|
CDevEnum(const CDevEnum &orig) :
|
||
|
m_pDevices(orig.m_pDevices), m_DC(orig.m_DC), i(orig.i) {}
|
||
|
virtual ~CDevEnum() {}
|
||
|
|
||
|
// IDevEnum
|
||
|
public:
|
||
|
PQDispatch m_pDevices;
|
||
|
DeviceCollection& m_DC;
|
||
|
DeviceCollection::iterator i;
|
||
|
// IEnumVARIANT
|
||
|
STDMETHOD(Next)(ULONG celt, VARIANT * rgvar, ULONG * pceltFetched)
|
||
|
{
|
||
|
// pceltFetched can legally == 0
|
||
|
//
|
||
|
if (pceltFetched != NULL) {
|
||
|
try {
|
||
|
*pceltFetched = 0;
|
||
|
} catch(...) {
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (ULONG l=0; l < celt; l++) {
|
||
|
try {
|
||
|
VariantInit( &rgvar[l] ) ;
|
||
|
} catch(...) {
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Retrieve the next celt elements.
|
||
|
HRESULT hr = NOERROR ;
|
||
|
for (l = 0;i != m_DC.end() && celt != 0 ; ++i, ++l, --celt) {
|
||
|
rgvar[l].vt = VT_DISPATCH ;
|
||
|
rgvar[l].pdispVal = PQDevice(*i).Detach();
|
||
|
if (pceltFetched != NULL) {
|
||
|
(*pceltFetched)++ ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (celt != 0) {
|
||
|
hr = ResultFromScode( S_FALSE ) ;
|
||
|
}
|
||
|
|
||
|
return hr ;
|
||
|
}
|
||
|
STDMETHOD(Skip)(ULONG celt)
|
||
|
{
|
||
|
for (;i != m_DC.end() && celt--; ++i);
|
||
|
return (celt == 0 ? NOERROR : ResultFromScode( S_FALSE )) ;
|
||
|
}
|
||
|
STDMETHOD(Reset)()
|
||
|
{
|
||
|
i = m_DC.begin();
|
||
|
return NOERROR;
|
||
|
}
|
||
|
STDMETHOD(Clone)(IEnumVARIANT * * ppenum)
|
||
|
{
|
||
|
if (ppenum == NULL)
|
||
|
return E_POINTER;
|
||
|
PQEnumVARIANT temp;
|
||
|
try {
|
||
|
temp = new CDevEnum(*this);
|
||
|
} catch(...) {
|
||
|
return E_OUTOFMEMORY;
|
||
|
}
|
||
|
try {
|
||
|
*ppenum = temp.Detach();
|
||
|
} catch(...) {
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
return NOERROR;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#endif
|
||
|
//end of file devices.h
|
||
|
|