//==========================================================================; // // tunerimpl.h : additional infrastructure to support implementing IMSVidTuner // nicely from c++ // Copyright (c) Microsoft Corporation 1999. // ///////////////////////////////////////////////////////////////////////////// #pragma once #ifndef TUNERIMPL_H #define TUNERIMPL_H #include "videoinputimpl.h" #include "tune.h" #include namespace MSVideoControl { template class DECLSPEC_NOVTABLE IMSVidTunerImpl : public IMSVidVideoInputImpl { public: TNTuningSpace m_TS; TNTuneRequest m_pCurrentTR; IMSVidTunerImpl() : m_TS(), m_pCurrentTR() {} virtual ~IMSVidTunerImpl() {} virtual HRESULT DoTune(TNTuneRequest& pTR) = 0; virtual HRESULT UpdateTR(TNTuneRequest& pTR) = 0; // IMSVidInputDevice STDMETHOD(IsViewable)(VARIANT* pv, VARIANT_BOOL *pfViewable) { if (!m_fInit) { return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidTuner), CO_E_NOTINITIALIZED); } if (!pv) { return E_POINTER; } return E_NOTIMPL; } STDMETHOD(View)(VARIANT* pv) { if (!m_fInit) { return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidTuner), CO_E_NOTINITIALIZED); } if (!pv) { return E_POINTER; } try { if (pv->vt != VT_DISPATCH && pv->vt != VT_UNKNOWN) { return ImplReportError(__uuidof(T), IDS_INVALID_CONTENT, __uuidof(IMSVidTuner), E_INVALIDARG); } PQTuneRequest tr((pv->vt == VT_UNKNOWN) ? pv->punkVal : pv->pdispVal); if (!tr) { return ImplReportError(__uuidof(T), IDS_INVALID_CONTENT, __uuidof(IMSVidTuner), E_INVALIDARG); } return put_Tune(tr); } catch(...) { return E_UNEXPECTED; } } // IMSVidTuner STDMETHOD(put_Tune)(ITuneRequest *pTR) { TRACELM(TRACE_DETAIL, "IMSVidTunerImpl<>::put_Tune()"); if (!m_fInit) { return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidTuner), CO_E_NOTINITIALIZED); } if (!pTR) { return E_POINTER; } try { TNTuneRequest req(pTR); ASSERT(req); if (m_TS) { // if this tuner has been initialized propertly it will have a tuning space // that it handles already specified. in that case, we should only // handle tune requests for our ts TNTuningSpace ts(req.TuningSpace()); if (ts != m_TS) { return ImplReportError(__uuidof(T), IDS_INVALID_TS, __uuidof(IMSVidTuner), E_INVALIDARG); } } else { // undone: if dev init is correct this case should never occur // return E_UNEXPECTED; } HRESULT hr = DoTune(req); if (SUCCEEDED(hr)) { m_pCurrentTR = req; m_pCurrentTR.Clone(); if (!m_TS) { // undone: this is bad. temporary hack until dev init is correct. m_TS = req.TuningSpace(); m_TS.Clone(); } } return hr; } catch(...) { return E_INVALIDARG; } } STDMETHOD(get_Tune)(ITuneRequest **ppTR) { if (!m_fInit) { return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidTuner), CO_E_NOTINITIALIZED); } if (!ppTR) { return E_POINTER; } try { HRESULT hr = UpdateTR(m_pCurrentTR); if (FAILED(hr)) { return hr; } return m_pCurrentTR.CopyTo(ppTR); } catch(...) { return E_INVALIDARG; } } STDMETHOD(get_TuningSpace)(ITuningSpace **ppTS) { if (!m_fInit) { return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidTuner), CO_E_NOTINITIALIZED); } if (ppTS == NULL) return E_POINTER; try { m_TS.CopyTo(ppTS); return NOERROR; } catch(...) { return E_UNEXPECTED; } } STDMETHOD(put_TuningSpace)(ITuningSpace* pTS) { return E_NOTIMPL; } }; template class CProxy_Tuner : public CProxy_DeviceEvent { //Warning this class may be recreated by the wizard. public: VOID Fire_OnTuneChanged(IMSVidTuner *pTunerDev) { T* pT = static_cast(this); int nConnectionIndex; CComVariant* pvars = new CComVariant[1]; int nConnections = m_vec.GetSize(); for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++) { pT->Lock(); CComPtr sp = m_vec.GetAt(nConnectionIndex); pT->Unlock(); IDispatch* pDispatch = reinterpret_cast(sp.p); if (pDispatch != NULL) { pvars[0] = pTunerDev; DISPPARAMS disp = { pvars, NULL, 1, 0 }; pDispatch->Invoke(eventidOnTuneChanged, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL); } } delete[] pvars; } }; }; // namespace #endif // end of file - tunerimpl.h