//==========================================================================; // // segimpl.h : additional infrastructure to support implementing IMSVidGraphSegment // nicely from c++ // Copyright (c) Microsoft Corporation 1999. // ///////////////////////////////////////////////////////////////////////////// #pragma once #ifndef SEGIMPL_H #define SEGIMPL_H #include #include #include #include "devsegimpl.h" namespace MSVideoControl { typedef CComQIPtr PQVidCtl; template class DECLSPEC_NOVTABLE IMSVidGraphSegmentImpl : public MostDerivedClass, public virtual CMSVidDeviceSegmentImpl { protected: HRESULT Unload() { if (!m_fInit || !m_pContainer) { return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidGraphSegment), CO_E_NOTINITIALIZED); } try { ASSERT(m_pContainer.GetGraph() == m_pGraph); // undone: dynamic graph building may allow this if (!m_pGraph.IsStopped()) { return ImplReportError(__uuidof(T), IDS_INVALID_STATE, __uuidof(IMSVidGraphSegment), HRESULT_FROM_WIN32(ERROR_INVALID_STATE)); } if (m_pGraph) { #ifdef CRASH std::for_each(m_Filters.begin(), m_Filters.end(), arity1_member_obj(m_pGraph, arity1_member(&DSGraph::RemoveFilter)) ); #else #if 0 std::for_each(m_Filters.begin(), m_Filters.end(), arity1opmf >( m_pGraph, arity1_member(&DSGraph::RemoveFilter))); #endif for(DSFilterList::iterator i = m_Filters.begin(); i != m_Filters.end(); ++i){ HRESULT hr = m_pGraph->RemoveFilter(*i); _ASSERT((L"Failed to remove filter from graph during Unload.", SUCCEEDED(hr))); } #endif } m_Filters.clear(); m_pGraph.Release(); // DON'T release the container. we're guaranteed nested lifetimes // and an addref creates circular refcounts so we never unload. // thus, we didn't addref and a release will over release and // cause destruction before other people are done with the container m_pContainer.p = NULL; } catch(ComException &e) { return e; } catch(...) { return E_UNEXPECTED; } return NOERROR; } public: // DON'T addref the container. we're guaranteed nested lifetimes // and an addref creates circular refcounts so we never unload. IMSVidGraphSegmentImpl() {} virtual ~IMSVidGraphSegmentImpl() { if (m_fInit && m_pContainer) { Unload(); } } STDMETHOD(GetClassID) (LPCLSID guid) { try { memcpy(guid, &__uuidof(T), sizeof(CLSID)); return NOERROR; } catch(...) { return E_POINTER; } } STDMETHOD(put_Init)(IUnknown * pInit) { if (m_fInit) { return NOERROR; } try { m_pDev = pInit; m_fInit = true; return NOERROR; } catch(...) { m_fInit = false; return E_POINTER; } } STDMETHOD(get_Init)(IUnknown ** pInit) { try{ if (!pInit) { return E_POINTER; } m_pDev.CopyTo(pInit); return NOERROR; } catch(...) { m_fInit = false; return E_POINTER; } } STDMETHOD(get_Container)(IMSVidGraphSegmentContainer **ppCtl) { if (!m_fInit) { return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidGraphSegment), CO_E_NOTINITIALIZED); } try { return m_pContainer.CopyTo(ppCtl); } catch(...) { return E_POINTER; } } STDMETHOD(put_Container)(IMSVidGraphSegmentContainer *pCtl) { try { if (!pCtl) { return Unload(); } if (m_pContainer) { if (!m_pContainer.IsEqualObject(VWSegmentContainer(pCtl))) { //undone: support moving to different graph return ImplReportError(__uuidof(T), IDS_OBJ_ALREADY_INIT, __uuidof(IMSVidGraphSegment), CO_E_ALREADYINITIALIZED); } else { return NO_ERROR; } } // DON'T addref the container. we're guaranteed nested lifetimes // and an addref creates circular refcounts so we never unload. m_pContainer.p = pCtl; m_pGraph = m_pContainer.GetGraph(); } catch(...) { return E_UNEXPECTED; } return NOERROR; } STDMETHOD(EnumFilters)(IEnumFilters * * pNewEnum) { if (!m_fInit) { return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidGraphSegment), CO_E_NOTINITIALIZED); } if (pNewEnum == NULL) return E_POINTER; PQEnumFilters p; try { p = new CFilterEnumOnDSFilterList(m_Filters); } catch (...) { return E_OUTOFMEMORY; } try { *pNewEnum = p.Detach(); } catch (...) { return E_POINTER; } return NOERROR; } STDMETHOD(get_Type)(MSVidSegmentType *pType) { try { *pType = segtype; return NOERROR; } catch(...) { return E_POINTER; } } STDMETHOD(get_Category)(GUID *pGuid) { if (!m_fInit) { return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidGraphSegment), CO_E_NOTINITIALIZED); } try { memcpy(pGuid, pCategory, sizeof(*pGuid)); return NOERROR; } catch(...) { return E_POINTER; } } STDMETHOD(Build)() { return E_NOTIMPL; } STDMETHOD(PreRun)() { return E_NOTIMPL; } STDMETHOD(PostRun)() { return E_NOTIMPL; } STDMETHOD(PreStop)() { return E_NOTIMPL; } STDMETHOD(PostStop)() { return E_NOTIMPL; } STDMETHOD(Select)(IUnknown *pItem) { return E_NOTIMPL; } STDMETHOD(OnEventNotify)(LONG lEvent, LONG_PTR lParm1, LONG_PTR lParm2) { return E_NOTIMPL; } STDMETHOD(OnWindowMessage)(UINT uMsg, WPARAM wParam, LPARAM lParam) { return E_NOTIMPL; } STDMETHOD(Decompose)(){ return E_NOTIMPL; } }; }; // namespace #endif // end of file - segimpl.h