//==========================================================================; // // Devices.h : Declaration of the CDevices // Copyright (c) Microsoft Corporation 1999. // ///////////////////////////////////////////////////////////////////////////// #pragma once #ifndef DEVICES_H_ #define DEVICES_H_ #include #include #include "devseq.h" #if 0 #define DEBUGREGISTRY #endif #ifdef DEBUGREGISTRY #include #endif void CtorStaticVWDevicesFwdSeqPMFs(void); void DtorStaticVWDevicesFwdSeqPMFs(void); template class CTypedDevices; template class ATL_NO_VTABLE CTypedDevicesBase : public CComObjectRootEx, public CComCoClass, DEVICETYPE_CLSID>, public ISupportErrorInfo, public IObjectWithSiteImplSec, public IDispatchImpl { 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 CTypedDevices : public CComObject > { typedef CComQIPtr PQDEVICETYPECOLLECTIONINTERFACE; typedef CComQIPtr 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 *>(src.p)->m_fRO), m_fValid(static_cast *>(src.p)->m_fValid) { m_Devices.clear(); m_Devices.insert(m_Devices.end(), static_cast *>(src.p)->m_Devices.begin(), static_cast *>(src.p)->m_Devices.end() ); } CTypedDevices &operator=(const CTypedDevices &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 CInputDevices; typedef CTypedDevices COutputDevices; typedef CTypedDevices CVideoRendererDevices; typedef CTypedDevices CAudioRendererDevices; typedef CTypedDevices CFeatures; ///////////////////////////////////////////////////////////////////////////// // CDevEnum class ATL_NO_VTABLE CDevEnumBase : public CComObjectRootEx, public IObjectWithSiteImplSec, 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 { 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