?? dsdemodlg.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 + -