📄 ctlutil.cpp
字号:
//------------------------------------------------------------------------------
// File: CtlUtil.cpp
//
// Desc: DirectShow base classes.
//
// Copyright (c) 1992-2002 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
// Base classes implementing IDispatch parsing for the basic control dual
// interfaces. Derive from these and implement just the custom method and
// property methods. We also implement CPosPassThru that can be used by
// renderers and transforms to pass by IMediaPosition and IMediaSeeking
#include <streams.h>
#include <limits.h>
#include "seekpt.h"
// 'bool' non standard reserved word
#pragma warning(disable:4237)
// --- CBaseDispatch implementation ----------
CBaseDispatch::~CBaseDispatch()
{
if (m_pti) {
m_pti->Release();
}
}
// return 1 if we support GetTypeInfo
STDMETHODIMP
CBaseDispatch::GetTypeInfoCount(UINT * pctinfo)
{
CheckPointer(pctinfo,E_POINTER);
ValidateReadWritePtr(pctinfo,sizeof(UINT *));
*pctinfo = 1;
return S_OK;
}
typedef HRESULT (STDAPICALLTYPE *LPLOADTYPELIB)(
const OLECHAR FAR *szFile,
ITypeLib FAR* FAR* pptlib);
typedef HRESULT (STDAPICALLTYPE *LPLOADREGTYPELIB)(REFGUID rguid,
WORD wVerMajor,
WORD wVerMinor,
LCID lcid,
ITypeLib FAR* FAR* pptlib);
// attempt to find our type library
STDMETHODIMP
CBaseDispatch::GetTypeInfo(
REFIID riid,
UINT itinfo,
LCID lcid,
ITypeInfo ** pptinfo)
{
CheckPointer(pptinfo,E_POINTER);
ValidateReadWritePtr(pptinfo,sizeof(ITypeInfo *));
HRESULT hr;
*pptinfo = NULL;
// we only support one type element
if (0 != itinfo) {
return TYPE_E_ELEMENTNOTFOUND;
}
if (NULL == pptinfo) {
return E_POINTER;
}
// always look for neutral
if (NULL == m_pti) {
LPLOADTYPELIB lpfnLoadTypeLib;
LPLOADREGTYPELIB lpfnLoadRegTypeLib;
ITypeLib *ptlib;
HINSTANCE hInst;
static const char szTypeLib[] = "LoadTypeLib";
static const char szRegTypeLib[] = "LoadRegTypeLib";
static const WCHAR szControl[] = L"control.tlb";
//
// Try to get the Ole32Aut.dll module handle.
//
hInst = LoadOLEAut32();
if (hInst == NULL) {
DWORD dwError = GetLastError();
return AmHresultFromWin32(dwError);
}
lpfnLoadRegTypeLib = (LPLOADREGTYPELIB)GetProcAddress(hInst,
szRegTypeLib);
if (lpfnLoadRegTypeLib == NULL) {
DWORD dwError = GetLastError();
return AmHresultFromWin32(dwError);
}
hr = (*lpfnLoadRegTypeLib)(LIBID_QuartzTypeLib, 1, 0, // version 1.0
lcid, &ptlib);
if (FAILED(hr)) {
// attempt to load directly - this will fill the
// registry in if it finds it
lpfnLoadTypeLib = (LPLOADTYPELIB)GetProcAddress(hInst, szTypeLib);
if (lpfnLoadTypeLib == NULL) {
DWORD dwError = GetLastError();
return AmHresultFromWin32(dwError);
}
hr = (*lpfnLoadTypeLib)(szControl, &ptlib);
if (FAILED(hr)) {
return hr;
}
}
hr = ptlib->GetTypeInfoOfGuid(
riid,
&m_pti);
ptlib->Release();
if (FAILED(hr)) {
return hr;
}
}
*pptinfo = m_pti;
m_pti->AddRef();
return S_OK;
}
STDMETHODIMP
CBaseDispatch::GetIDsOfNames(
REFIID riid,
OLECHAR ** rgszNames,
UINT cNames,
LCID lcid,
DISPID * rgdispid)
{
// although the IDispatch riid is dead, we use this to pass from
// the interface implementation class to us the iid we are talking about.
ITypeInfo * pti;
HRESULT hr = GetTypeInfo(riid, 0, lcid, &pti);
if (SUCCEEDED(hr)) {
hr = pti->GetIDsOfNames(rgszNames, cNames, rgdispid);
pti->Release();
}
return hr;
}
// --- CMediaControl implementation ---------
CMediaControl::CMediaControl(const TCHAR * name,LPUNKNOWN pUnk) :
CUnknown(name, pUnk)
{
}
// expose our interfaces IMediaControl and IUnknown
STDMETHODIMP
CMediaControl::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
ValidateReadWritePtr(ppv,sizeof(PVOID));
if (riid == IID_IMediaControl) {
return GetInterface( (IMediaControl *) this, ppv);
} else {
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
}
// return 1 if we support GetTypeInfo
STDMETHODIMP
CMediaControl::GetTypeInfoCount(UINT * pctinfo)
{
return m_basedisp.GetTypeInfoCount(pctinfo);
}
// attempt to find our type library
STDMETHODIMP
CMediaControl::GetTypeInfo(
UINT itinfo,
LCID lcid,
ITypeInfo ** pptinfo)
{
return m_basedisp.GetTypeInfo(
IID_IMediaControl,
itinfo,
lcid,
pptinfo);
}
STDMETHODIMP
CMediaControl::GetIDsOfNames(
REFIID riid,
OLECHAR ** rgszNames,
UINT cNames,
LCID lcid,
DISPID * rgdispid)
{
return m_basedisp.GetIDsOfNames(
IID_IMediaControl,
rgszNames,
cNames,
lcid,
rgdispid);
}
STDMETHODIMP
CMediaControl::Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS * pdispparams,
VARIANT * pvarResult,
EXCEPINFO * pexcepinfo,
UINT * puArgErr)
{
// this parameter is a dead leftover from an earlier interface
if (IID_NULL != riid) {
return DISP_E_UNKNOWNINTERFACE;
}
ITypeInfo * pti;
HRESULT hr = GetTypeInfo(0, lcid, &pti);
if (FAILED(hr)) {
return hr;
}
hr = pti->Invoke(
(IMediaControl *)this,
dispidMember,
wFlags,
pdispparams,
pvarResult,
pexcepinfo,
puArgErr);
pti->Release();
return hr;
}
// --- CMediaEvent implementation ----------
CMediaEvent::CMediaEvent(const TCHAR * name,LPUNKNOWN pUnk) :
CUnknown(name, pUnk)
{
}
// expose our interfaces IMediaEvent and IUnknown
STDMETHODIMP
CMediaEvent::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
ValidateReadWritePtr(ppv,sizeof(PVOID));
if (riid == IID_IMediaEvent || riid == IID_IMediaEventEx) {
return GetInterface( (IMediaEventEx *) this, ppv);
} else {
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
}
// return 1 if we support GetTypeInfo
STDMETHODIMP
CMediaEvent::GetTypeInfoCount(UINT * pctinfo)
{
return m_basedisp.GetTypeInfoCount(pctinfo);
}
// attempt to find our type library
STDMETHODIMP
CMediaEvent::GetTypeInfo(
UINT itinfo,
LCID lcid,
ITypeInfo ** pptinfo)
{
return m_basedisp.GetTypeInfo(
IID_IMediaEvent,
itinfo,
lcid,
pptinfo);
}
STDMETHODIMP
CMediaEvent::GetIDsOfNames(
REFIID riid,
OLECHAR ** rgszNames,
UINT cNames,
LCID lcid,
DISPID * rgdispid)
{
return m_basedisp.GetIDsOfNames(
IID_IMediaEvent,
rgszNames,
cNames,
lcid,
rgdispid);
}
STDMETHODIMP
CMediaEvent::Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS * pdispparams,
VARIANT * pvarResult,
EXCEPINFO * pexcepinfo,
UINT * puArgErr)
{
// this parameter is a dead leftover from an earlier interface
if (IID_NULL != riid) {
return DISP_E_UNKNOWNINTERFACE;
}
ITypeInfo * pti;
HRESULT hr = GetTypeInfo(0, lcid, &pti);
if (FAILED(hr)) {
return hr;
}
hr = pti->Invoke(
(IMediaEvent *)this,
dispidMember,
wFlags,
pdispparams,
pvarResult,
pexcepinfo,
puArgErr);
pti->Release();
return hr;
}
// --- CMediaPosition implementation ----------
CMediaPosition::CMediaPosition(const TCHAR * name,LPUNKNOWN pUnk) :
CUnknown(name, pUnk)
{
}
CMediaPosition::CMediaPosition(const TCHAR * name,
LPUNKNOWN pUnk,
HRESULT * phr) :
CUnknown(name, pUnk)
{
UNREFERENCED_PARAMETER(phr);
}
// expose our interfaces IMediaPosition and IUnknown
STDMETHODIMP
CMediaPosition::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
ValidateReadWritePtr(ppv,sizeof(PVOID));
if (riid == IID_IMediaPosition) {
return GetInterface( (IMediaPosition *) this, ppv);
} else {
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
}
// return 1 if we support GetTypeInfo
STDMETHODIMP
CMediaPosition::GetTypeInfoCount(UINT * pctinfo)
{
return m_basedisp.GetTypeInfoCount(pctinfo);
}
// attempt to find our type library
STDMETHODIMP
CMediaPosition::GetTypeInfo(
UINT itinfo,
LCID lcid,
ITypeInfo ** pptinfo)
{
return m_basedisp.GetTypeInfo(
IID_IMediaPosition,
itinfo,
lcid,
pptinfo);
}
STDMETHODIMP
CMediaPosition::GetIDsOfNames(
REFIID riid,
OLECHAR ** rgszNames,
UINT cNames,
LCID lcid,
DISPID * rgdispid)
{
return m_basedisp.GetIDsOfNames(
IID_IMediaPosition,
rgszNames,
cNames,
lcid,
rgdispid);
}
STDMETHODIMP
CMediaPosition::Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS * pdispparams,
VARIANT * pvarResult,
EXCEPINFO * pexcepinfo,
UINT * puArgErr)
{
// this parameter is a dead leftover from an earlier interface
if (IID_NULL != riid) {
return DISP_E_UNKNOWNINTERFACE;
}
ITypeInfo * pti;
HRESULT hr = GetTypeInfo(0, lcid, &pti);
if (FAILED(hr)) {
return hr;
}
hr = pti->Invoke(
(IMediaPosition *)this,
dispidMember,
wFlags,
pdispparams,
pvarResult,
pexcepinfo,
puArgErr);
pti->Release();
return hr;
}
// --- IMediaPosition and IMediaSeeking pass through class ----------
CPosPassThru::CPosPassThru(const TCHAR *pName,
LPUNKNOWN pUnk,
HRESULT *phr,
IPin *pPin) :
CMediaPosition(pName,pUnk),
m_pPin(pPin)
{
if (pPin == NULL) {
*phr = E_POINTER;
return;
}
}
// Expose our IMediaSeeking and IMediaPosition interfaces
STDMETHODIMP
CPosPassThru::NonDelegatingQueryInterface(REFIID riid,void **ppv)
{
CheckPointer(ppv,E_POINTER);
*ppv = NULL;
if (riid == IID_IMediaSeeking) {
return GetInterface( static_cast<IMediaSeeking *>(this), ppv);
}
return CMediaPosition::NonDelegatingQueryInterface(riid,ppv);
}
// Return the IMediaPosition interface from our peer
HRESULT
CPosPassThru::GetPeer(IMediaPosition ** ppMP)
{
*ppMP = NULL;
IPin *pConnected;
HRESULT hr = m_pPin->ConnectedTo(&pConnected);
if (FAILED(hr)) {
return E_NOTIMPL;
}
IMediaPosition * pMP;
hr = pConnected->QueryInterface(IID_IMediaPosition, (void **) &pMP);
pConnected->Release();
if (FAILED(hr)) {
return E_NOTIMPL;
}
*ppMP = pMP;
return S_OK;
}
// Return the IMediaSeeking interface from our peer
HRESULT
CPosPassThru::GetPeerSeeking(IMediaSeeking ** ppMS)
{
*ppMS = NULL;
IPin *pConnected;
HRESULT hr = m_pPin->ConnectedTo(&pConnected);
if (FAILED(hr)) {
return E_NOTIMPL;
}
IMediaSeeking * pMS;
hr = pConnected->QueryInterface(IID_IMediaSeeking, (void **) &pMS);
pConnected->Release();
if (FAILED(hr)) {
return E_NOTIMPL;
}
*ppMS = pMS;
return S_OK;
}
// --- IMediaSeeking methods ----------
STDMETHODIMP
CPosPassThru::GetCapabilities(DWORD * pCaps)
{
IMediaSeeking* pMS;
HRESULT hr = GetPeerSeeking(&pMS);
if (FAILED(hr)) {
return hr;
}
hr = pMS->GetCapabilities(pCaps);
pMS->Release();
return hr;
}
STDMETHODIMP
CPosPassThru::CheckCapabilities(DWORD * pCaps)
{
IMediaSeeking* pMS;
HRESULT hr = GetPeerSeeking(&pMS);
if (FAILED(hr)) {
return hr;
}
hr = pMS->CheckCapabilities(pCaps);
pMS->Release();
return hr;
}
STDMETHODIMP
CPosPassThru::IsFormatSupported(const GUID * pFormat)
{
IMediaSeeking* pMS;
HRESULT hr = GetPeerSeeking(&pMS);
if (FAILED(hr)) {
return hr;
}
hr = pMS->IsFormatSupported(pFormat);
pMS->Release();
return hr;
}
STDMETHODIMP
CPosPassThru::QueryPreferredFormat(GUID *pFormat)
{
IMediaSeeking* pMS;
HRESULT hr = GetPeerSeeking(&pMS);
if (FAILED(hr)) {
return hr;
}
hr = pMS->QueryPreferredFormat(pFormat);
pMS->Release();
return hr;
}
STDMETHODIMP
CPosPassThru::SetTimeFormat(const GUID * pFormat)
{
IMediaSeeking* pMS;
HRESULT hr = GetPeerSeeking(&pMS);
if (FAILED(hr)) {
return hr;
}
hr = pMS->SetTimeFormat(pFormat);
pMS->Release();
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -