179 lines
6.1 KiB
C
179 lines
6.1 KiB
C
|
//==========================================================================;
|
||
|
//
|
||
|
// 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 <deviceeventimpl.h>
|
||
|
|
||
|
namespace MSVideoControl {
|
||
|
|
||
|
template<class T, LPCGUID LibID, LPCGUID KSCategory, class MostDerivedInterface = IMSVidTuner>
|
||
|
class DECLSPEC_NOVTABLE IMSVidTunerImpl :
|
||
|
public IMSVidVideoInputImpl<T, LibID, KSCategory, MostDerivedInterface> {
|
||
|
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 T, const IID* piid = &IID_IMSVidTunerEvent, class CDV = CComDynamicUnkArray>
|
||
|
class CProxy_Tuner : public CProxy_DeviceEvent<T, piid, CDV>
|
||
|
{
|
||
|
//Warning this class may be recreated by the wizard.
|
||
|
public:
|
||
|
VOID Fire_OnTuneChanged(IMSVidTuner *pTunerDev)
|
||
|
{
|
||
|
T* pT = static_cast<T*>(this);
|
||
|
int nConnectionIndex;
|
||
|
CComVariant* pvars = new CComVariant[1];
|
||
|
int nConnections = m_vec.GetSize();
|
||
|
|
||
|
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
|
||
|
{
|
||
|
pT->Lock();
|
||
|
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
|
||
|
pT->Unlock();
|
||
|
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(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
|