⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctlutil.cpp

📁 用DirectX制作高级动画-[Advanced.Animation.with.DirectX]
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//------------------------------------------------------------------------------
// 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 + -