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

📄 dsdemodlg.cpp

📁 简单的COM 实际例子 用法3
💻 CPP
字号:
// DsDemoDlg.cpp : implementation file
//

#include "stdafx.h"
#include "DsDemo.h"
#include "DsDemoDlg.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDsDemoDlg dialog

CDsDemoDlg::CDsDemoDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDsDemoDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDsDemoDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CDsDemoDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDsDemoDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CDsDemoDlg, CDialog)
	//{{AFX_MSG_MAP(CDsDemoDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDsDemoDlg message handlers

BOOL CDsDemoDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CDsDemoDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CDsDemoDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}


/////////////////////////////////////////////////////////////////////////
// 枚举Filter上的Pin
IPin * CDsDemoDlg::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir)
{
    BOOL       bFound = FALSE;
    IEnumPins  *pEnum;
    IPin       *pPin;

    HRESULT hr = pFilter->EnumPins(&pEnum);
    if (FAILED(hr))
    {
        return NULL;
    }
    while(pEnum->Next(1, &pPin, 0) == S_OK)
    {
        PIN_DIRECTION PinDirThis;
        pPin->QueryDirection(&PinDirThis);
        if (bFound = (PinDir == PinDirThis))
            break;
        pPin->Release();
    }
    pEnum->Release();
    return (bFound ? pPin : NULL); 
}

// 枚举Pin上的媒体类型
BOOL CDsDemoDlg::GetMediaType(IPin * inPin)
{
	IEnumMediaTypes * pMTEnum = NULL; 
	AM_MEDIA_TYPE *   pAMType = NULL;
	if (SUCCEEDED(inPin->EnumMediaTypes(&pMTEnum)))
	{
		ASSERT(pMTEnum);
		while (pMTEnum->Next(1, &pAMType, 0) == S_OK)
		{
			// 对取得的媒体类型进行处理
			// ...

			DeleteMediaType(pAMType);
		}
		pMTEnum->Release();
		return TRUE;
	}
	return FALSE;
}

// 判断某个Filter是否已经注册
BOOL CDsDemoDlg::IsFilterRegistered(CLSID inFilterId)
{
	IBaseFilter * pFilter = NULL;
	if (SUCCEEDED(CoCreateInstance(inFilterId, NULL, CLSCTX_INPROC_SERVER,
		IID_IBaseFilter, (void **)&pFilter)))
	{
		pFilter->Release();
		return TRUE;
	}
	return FALSE;
}

// 在程序中注册某个Filter文件
BOOL CDsDemoDlg::RegisterFilter(const char * inFilterAx)
{
	typedef (WINAPI * REGISTER_FUNC) (void);
	REGISTER_FUNC   MyFunc = NULL;

	HMODULE hModule = ::LoadLibrary(inFilterAx);
	if (hModule)
	{
		MyFunc = (REGISTER_FUNC) GetProcAddress(hModule, "DllRegisterServer");
		BOOL pass = (MyFunc != NULL);
		if (pass)
		{
			MyFunc();
		}
		::FreeLibrary(hModule);
		return pass;
	}

	return FALSE;
}

// 修改Filter的Merit值
BOOL CDsDemoDlg::SetFilterMerit(const char * inClsid, DWORD inMerit)
{
	typedef struct
	{
		DWORD	dwVersion;    // 版本号
		DWORD	dwMerit;      // Merit值
		DWORD	dwPinCount;   // Pin的数量
		DWORD	dwReserved;   // 保留
	} FILTER_HEADER;

	const char *  cRegistryEntry = "CLSID\\{083863F1-70DE-11d0-BD40-00A0C911CE86}\\Instance\\";
	const long    cMaxLength = 1024 * 16;
	BYTE          filterData[cMaxLength];
	DWORD         actualLength = 0;

	// 生成Filter信息注册部分的注册表入口
	char   szEntry[1000];
	strcpy(szEntry, cRegistryEntry);
	strcat(szEntry, inClsid);
	
	HKEY hKey   = NULL;
	LONG result = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, szEntry, 0, KEY_ALL_ACCESS, &hKey);
	BOOL pass = (result == ERROR_SUCCESS);
	if (pass)
	{
		// 读取FilterData的值
		actualLength = actualLength;
		result = ::RegQueryValueEx(hKey, "FilterData", NULL, NULL, filterData, &actualLength);
		pass   = (result == ERROR_SUCCESS);
	}
	if (pass)
	{
		// 修改FiterData中Merit部分,然后写回到注册表
		FILTER_HEADER * filterHeader = (FILTER_HEADER *) filterData;
		filterHeader->dwMerit = inMerit;
		result = ::RegSetValueEx(hKey, "FilterData", NULL, REG_BINARY, filterData, actualLength);
		pass   = (result == ERROR_SUCCESS);
	}
	if (hKey)
	{
		::RegCloseKey(hKey);
	}
	return pass;
}

// 判断采集卡类型:VFW or WDM
BOOL CDsDemoDlg::IsVFWCard(IBaseFilter * pDeviceFilter)
{
	ASSERT(pDeviceFilter);

	IAMVfwCaptureDialogs * pVfw = NULL;
	HRESULT hr = pDeviceFilter->QueryInterface(IID_IAMVfwCaptureDialogs, (void**)&pVfw);
	if (SUCCEEDED(hr))
	{
		// This is a VFW card...
		pVfw->Release();
		
		return TRUE;
	}
	else
	{
		// Maybe this is a WDM card...

		return FALSE;
	}
}

BOOL CDsDemoDlg::IsWDMCard(IBaseFilter * pDeviceFilter)
{
	ASSERT(pDeviceFilter);

	IAMAnalogVideoDecoder * pWdm = NULL;
	HRESULT hr = pDeviceFilter->QueryInterface(IID_IAMAnalogVideoDecoder, (void**)&pWdm);
	if (SUCCEEDED(hr))
	{
		// This is a WDM card...
		pWdm->Release();
		
		return TRUE;
	}
	else
	{
		// Maybe this is a VFW card...

		return FALSE;
	}
}



HRESULT InitCaptureGraphBuilder(
  IGraphBuilder **ppGraph,  // Receives the pointer.
  ICaptureGraphBuilder2 **ppBuild  // Receives the pointer.
)
{
    if (!ppGraph || !ppBuild)
    {
        return E_POINTER;
    }
    IGraphBuilder *pGraph = NULL;
    ICaptureGraphBuilder2 *pBuild = NULL;

    // Create the Capture Graph Builder.
    HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, 
        CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pGraph);
    if (SUCCEEDED(hr))
    {
        // Create the Filter Graph Manager.
        hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER,
            IID_IGraphBuilder, (void**)&pGraph);
        if (SUCCEEDED(hr))
        {
            // Initialize the Capture Graph Builder.
            pBuild->SetFiltergraph(pGraph);

            // Return both interface pointers to the caller.
            *ppBuild = pBuild;
            *ppGraph = pGraph; // The caller must release both interfaces.
            return S_OK;
        }
        else
        {
            pBuild->Release();
        }
    }
    return hr; // Failed
}

// 辅助函数:在Crossbar Filter上查找指定类型的Pin
HRESULT FindCrossbarPin(
    IAMCrossbar *pXBar,                 // Pointer to the crossbar.
    PhysicalConnectorType PhysicalType, // Pin type to match.
    PIN_DIRECTION Dir,                  // Pin direction.
    long *pIndex)       // Receives the index of the pin, if found.
{
    BOOL bInput = (Dir == PINDIR_INPUT ? TRUE : FALSE);

    // Find out how many pins the crossbar has.
    long cOut, cIn;
    HRESULT hr = pXBar->get_PinCounts(&cOut, &cIn);
    if (FAILED(hr)) return hr;
    // Enumerate pins and look for a matching pin.
    long count = (bInput ? cIn : cOut);
    for (long i = 0; i < count; i++)
    {
        long iRelated = 0;
        long ThisPhysicalType = 0;
        hr = pXBar->get_CrossbarPinInfo(bInput, i, &iRelated,
            &ThisPhysicalType);
        if (SUCCEEDED(hr) && ThisPhysicalType == PhysicalType)
        {
            // Found a match, return the index.
            *pIndex = i;
            return S_OK;
        }
    }
    // Did not find a matching pin.
    return E_FAIL;
}

// 辅助函数:在Crossbar Filter上查找Audio Decoder Out Pin和Audio Tuner In Pin,
// 调用IAMCrossbar::Route函数进行电视声音的导通或者断开
HRESULT ConnectAudio(IAMCrossbar *pXBar, BOOL bActivate)
{
    // Look for the Audio Decoder output pin.
    long i = 0;
    HRESULT hr = FindCrossbarPin(pXBar, PhysConn_Audio_AudioDecoder,
        PINDIR_OUTPUT, &i);
    if (SUCCEEDED(hr))
    {
        if (bActivate)  // Activate the audio. 
        {
            // Look for the Audio Tuner input pin.
            long j = 0;
            hr = FindCrossbarPin(pXBar, PhysConn_Audio_Tuner, 
                PINDIR_INPUT, &j);
            if (SUCCEEDED(hr))
            {
                return pXBar->Route(i, j);
            }
        }
        else  // Mute the audio
        {
            return pXBar->Route(i, -1);
        }
    }
    return E_FAIL;
}

// 激活(或者关闭)电视声音,考虑到采集卡带有两个Crossbar Filter的情况
HRESULT ActivateAudio(ICaptureGraphBuilder2 *pBuild, IBaseFilter *pSrc,
  BOOL bActivate)
{
    // Search upstream for a crossbar.
    IAMCrossbar *pXBar1 = NULL;
    HRESULT hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pSrc,
        IID_IAMCrossbar, (void**)&pXBar1);
    if (SUCCEEDED(hr)) 
    {
        hr = ConnectAudio(pXBar1, bActivate);
        if (FAILED(hr))
        {
            // Look for another crossbar.
            IBaseFilter *pF = NULL;
            hr = pXBar1->QueryInterface(IID_IBaseFilter, (void**)&pF);
            if (SUCCEEDED(hr)) 
            {
                // Search upstream for another one.
                IAMCrossbar *pXBar2 = NULL;
                hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pF,
                    IID_IAMCrossbar, (void**)&pXBar2);
                pF->Release();
                if (SUCCEEDED(hr))
                {
                    hr = ConnectAudio(pXBar2, bActivate);
                    pXBar2->Release();
                }
            }
        }
        pXBar1->Release();
    }
    return hr;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -