Bläddra i källkod

DirectShow和VFW库采集摄像头的示例;注:DirectShow中Qedit.h头文件会提示dxtrans.h不存在,此时只要从C盘其他目录中搜索出来复制到Qedit.h所在目录中即可。

sat23 5 år sedan
förälder
incheckning
9657ed9d0e

+ 20 - 0
VideoCapture/VideoCapture.sln

@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoCapture", "VideoCapture\VideoCapture.vcproj", "{C123187E-3196-481D-BE98-803810B9D472}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{C123187E-3196-481D-BE98-803810B9D472}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C123187E-3196-481D-BE98-803810B9D472}.Debug|Win32.Build.0 = Debug|Win32
+		{C123187E-3196-481D-BE98-803810B9D472}.Release|Win32.ActiveCfg = Release|Win32
+		{C123187E-3196-481D-BE98-803810B9D472}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

BIN
VideoCapture/VideoCapture.suo


+ 10 - 0
VideoCapture/VideoCapture/AVICap.cpp

@@ -0,0 +1,10 @@
+#include "StdAfx.h"
+#include "AVICap.h"
+
+CAVICap::CAVICap(void)
+{
+}
+
+CAVICap::~CAVICap(void)
+{
+}

+ 16 - 0
VideoCapture/VideoCapture/AVICap.h

@@ -0,0 +1,16 @@
+#ifndef __AVI_CAP__
+#define __AVI_CAP__
+
+#include <Vfw.h>
+#pragma comment(lib, "vfw32.lib")
+
+#pragma once
+
+class CAVICap
+{
+public:
+	CAVICap(void);
+	~CAVICap(void);
+};
+
+#endif

+ 243 - 0
VideoCapture/VideoCapture/CaptureVideo.cpp

@@ -0,0 +1,243 @@
+#include "StdAfx.h"
+#include "CaptureVideo.h"
+
+CCaptureVideo::CCaptureVideo()
+{
+	//COM Library Intialization
+	if(FAILED(CoInitialize(NULL))) /*, COINIT_APARTMENTTHREADED)))*/
+	{
+		AfxMessageBox("CoInitialize Failed!\r\n");
+		return;
+	}
+	m_hWnd = NULL;
+	m_pVW = NULL;
+	m_pMC = NULL;
+	m_pGB = NULL;
+	m_pCapture = NULL;
+}
+
+CCaptureVideo::~CCaptureVideo()
+{
+	// Stop media playback
+	if(m_pMC)m_pMC->Stop();
+	if(m_pVW){
+		m_pVW->put_Visible(OAFALSE);
+		m_pVW->put_Owner(NULL);
+	}
+	SAFE_RELEASE(m_pCapture);
+	SAFE_RELEASE(m_pMC);
+	SAFE_RELEASE(m_pGB);
+	SAFE_RELEASE(m_pBF);
+	CoUninitialize( );
+}
+
+int CCaptureVideo::EnumDevices(HWND hList)
+{
+	if (!hList)
+		return -1;
+	int id = 0;
+	//枚举视频扑捉设备
+	ICreateDevEnum *pCreateDevEnum;
+	HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);
+	if (hr != NOERROR)return -1;
+	IEnumMoniker *pEm;
+	hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);
+	if (hr != NOERROR)
+		return -1;
+
+	pEm->Reset();
+	ULONG cFetched;
+	IMoniker *pM;
+	while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
+	{
+		IPropertyBag *pBag;
+		hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
+		if(SUCCEEDED(hr))
+		{
+			VARIANT var;
+			var.vt = VT_BSTR;
+			hr = pBag->Read(L"FriendlyName", &var, NULL);
+			if (hr == NOERROR)
+			{
+				TCHAR str[2048];
+				id++;
+				WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL);
+				::SendMessage(hList, CB_ADDSTRING, 0,(LPARAM)str);
+				SysFreeString(var.bstrVal);
+			}
+			pBag->Release();
+		}
+		pM->Release();
+	}
+	return id;
+}
+
+HRESULT CCaptureVideo::Init(int iDeviceID, HWND hWnd)
+{
+	HRESULT hr;
+	hr = InitCaptureGraphBuilder();
+	if (FAILED(hr)){
+		AfxMessageBox("Failed to get video interfaces!");
+		return hr;
+	}
+	// Bind Device Filter. We know the device because the id was passed in
+	if(!BindFilter(iDeviceID, &m_pBF))return S_FALSE;
+	hr = m_pGB->AddFilter(m_pBF, L"Capture Filter");
+	// hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
+	// m_pBF, NULL, NULL);
+	// create a sample grabber
+	//hr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber );
+	hr = CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_ISampleGrabber, (void**)&m_pGrabber );
+
+	if( !m_pGrabber ){
+		AfxMessageBox("Fail to create SampleGrabber, maybe qedit.dll is not registered?");
+		return hr;
+	}
+	CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabBase( m_pGrabber );
+	//设置视频格式
+	AM_MEDIA_TYPE mt;
+	ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
+	mt.majortype = MEDIATYPE_Video;
+	mt.subtype = MEDIASUBTYPE_RGB24;
+	hr = m_pGrabber->SetMediaType(&mt);
+	if( FAILED( hr ) ){
+		AfxMessageBox("Fail to set media type!");
+		return hr;
+	}
+	hr = m_pGB->AddFilter( pGrabBase, L"Grabber" );
+	if( FAILED( hr ) ){
+		AfxMessageBox("Fail to put sample grabber in graph");
+		return hr;
+	}
+	// try to render preview/capture pin
+	hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
+	if( FAILED( hr ) )
+		hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
+	if( FAILED( hr ) ){
+		AfxMessageBox("Can’t build the graph");
+		return hr;
+	}
+	hr = m_pGrabber->GetConnectedMediaType( &mt );
+	if ( FAILED( hr) ){
+		AfxMessageBox("Failt to read the connected media type");
+		return hr;
+	}
+	VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat;
+	mCB.lWidth = vih->bmiHeader.biWidth;
+	mCB.lHeight = vih->bmiHeader.biHeight;
+	FreeMediaType(mt);
+	hr = m_pGrabber->SetBufferSamples( FALSE );
+	hr = m_pGrabber->SetOneShot( FALSE );
+	hr = m_pGrabber->SetCallback( &mCB, 1 );
+	//设置视频捕捉窗口
+	m_hWnd = hWnd ;
+	SetupVideoWindow();
+	hr = m_pMC->Run();//开始视频捕捉
+	if(FAILED(hr)){AfxMessageBox("Couldn’t run the graph!");return hr;}
+	return S_OK;
+}
+
+bool CCaptureVideo::BindFilter(int deviceId, IBaseFilter **pFilter)
+{
+	if (deviceId < 0)
+		return false;
+	// enumerate all video capture devices
+	ICreateDevEnum* pCreateDevEnum;
+	HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
+		IID_ICreateDevEnum, (void**)&pCreateDevEnum);
+	if (hr != NOERROR)
+	{
+		return false;
+	}
+	IEnumMoniker* pEm;
+	hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);
+	if (hr != NOERROR)
+	{
+		return false;
+	}
+	pEm->Reset();
+	ULONG cFetched;
+	IMoniker *pM;
+	int index = 0;
+	while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK, index <= deviceId)
+	{
+		IPropertyBag *pBag;
+		hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
+		if(SUCCEEDED(hr))
+		{
+			VARIANT var;
+			var.vt = VT_BSTR;
+			hr = pBag->Read(L"FriendlyName", &var, NULL);
+			if (hr == NOERROR)
+			{
+				if (index == deviceId)
+				{
+					pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter);
+				}
+				SysFreeString(var.bstrVal);
+			}
+			pBag->Release();
+		}
+		pM->Release();
+		index++;
+	}
+	return true;
+}
+
+HRESULT CCaptureVideo::InitCaptureGraphBuilder()
+{
+	HRESULT hr;
+	// 创建IGraphBuilder接口
+	hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGB);
+	// 创建ICaptureGraphBuilder2接口
+	hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
+		IID_ICaptureGraphBuilder2, (void **) &m_pCapture);
+	if (FAILED(hr))return hr;
+	m_pCapture->SetFiltergraph(m_pGB);
+	hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
+	if (FAILED(hr))return hr;
+	hr = m_pGB->QueryInterface(IID_IVideoWindow, (LPVOID *) &m_pVW);
+	if (FAILED(hr))return hr;
+	return hr;
+}
+
+HRESULT CCaptureVideo::SetupVideoWindow()
+{
+	HRESULT hr;
+	hr = m_pVW->put_Owner((OAHWND)m_hWnd);
+	if (FAILED(hr))return hr;
+	hr = m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
+	if (FAILED(hr))return hr;
+	ResizeVideoWindow();
+	hr = m_pVW->put_Visible(OATRUE);
+	return hr;
+}
+
+void CCaptureVideo::ResizeVideoWindow()
+{
+	if (m_pVW){
+		//让图像充满整个窗口
+		CRect rc;
+		::GetClientRect(m_hWnd,&rc);
+		m_pVW->SetWindowPosition(0, 0, rc.right, rc.bottom);
+	}
+}
+
+void CCaptureVideo::GrabOneFrame(BOOL bGrab)
+{
+	bOneShot = bGrab;
+}
+
+void CCaptureVideo::FreeMediaType(AM_MEDIA_TYPE& mt)
+{
+	if (mt.cbFormat != 0) {
+		CoTaskMemFree((PVOID)mt.pbFormat);
+		// Strictly unnecessary but tidier
+		mt.cbFormat = 0;
+		mt.pbFormat = NULL;
+	}
+	if (mt.pUnk != NULL) {
+		mt.pUnk->Release();
+		mt.pUnk = NULL;
+	}
+}

+ 42 - 0
VideoCapture/VideoCapture/CaptureVideo.h

@@ -0,0 +1,42 @@
+#ifndef __CAPTURE_VIDEO__
+#define __CAPTURE_VIDEO__
+
+#pragma once
+
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE( x ) \
+	if ( NULL != x ) \
+	{ \
+		x->Release( ); \
+		x = NULL; \
+	}
+#endif
+#include "SampleGrabberCB.h"
+
+class CSampleGrabberCB;
+class CCaptureVideo
+{
+	friend class CSampleGrabberCB;
+public:
+	void GrabOneFrame(BOOL bGrab);
+	HRESULT Init(int iDeviceID,HWND hWnd);
+	int EnumDevices(HWND hList);
+	CCaptureVideo();
+	virtual ~CCaptureVideo();
+private:
+	HWND m_hWnd;
+	IGraphBuilder *m_pGB;
+	ICaptureGraphBuilder2* m_pCapture;
+	IBaseFilter* m_pBF;
+	IMediaControl* m_pMC;
+	IVideoWindow* m_pVW;
+	ISampleGrabber *m_pGrabber;
+protected:
+	void FreeMediaType(AM_MEDIA_TYPE& mt);
+	bool BindFilter(int deviceId, IBaseFilter **pFilter);
+	void ResizeVideoWindow();
+	HRESULT SetupVideoWindow();
+	HRESULT InitCaptureGraphBuilder();
+};
+
+#endif

+ 69 - 0
VideoCapture/VideoCapture/ReadMe.txt

@@ -0,0 +1,69 @@
+================================================================================
+    MICROSOFT 基础类库: VideoCapture 项目概述
+===============================================================================
+
+应用程序向导已为您创建此 VideoCapture 应用程序。此应用程序不仅演示使用 Microsoft 基础类的基本知识,而且可作为编写应用程序的起点。
+
+此文件包含组成 VideoCapture 应用程序的各个文件的内容摘要。
+
+VideoCapture.vcproj
+    这是使用应用程序向导生成的 VC++ 项目的主项目文件。
+    它包含有关生成文件的 Visual C++ 版本的信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
+
+VideoCapture.h
+    这是应用程序的主要头文件。它包括其他项目特定的头文件(包括 Resource.h),并声明 CVideoCaptureApp 应用程序类。
+
+VideoCapture.cpp
+    这是包含应用程序类 CVideoCaptureApp 的主要应用程序源文件。
+
+VideoCapture.rc
+    这是程序使用的所有 Microsoft Windows 资源的列表。它包括 RES 子目录中存储的图标、位图和光标。此文件可以直接在 Microsoft Visual C++ 中进行编辑。项目资源位于 2052 中。
+
+res\VideoCapture.ico
+    这是用作应用程序图标的图标文件。此图标包括在主要资源文件 VideoCapture.rc 中。
+
+res\VideoCapture.rc2
+    此文件包含不是由 Microsoft Visual C++ 编辑的资源。您应该将不可由资源编辑器编辑的所有资源放在此文件中。
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+应用程序向导创建一个对话框类:
+
+VideoCaptureDlg.h,VideoCaptureDlg.cpp - 对话框
+    这些文件包含 CVideoCaptureDlg 类。该类定义应用程序主对话框的行为。该对话框的模板位于 VideoCapture.rc 中,该文件可以在 Microsoft Visual C++ 中进行编辑。
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+其他功能:
+
+ActiveX 控件
+    应用程序包括对使用 ActiveX 控件的支持。
+
+打印及打印预览支持
+    应用程序向导已通过从 MFC 库调用 CView 类中的成员函数,生成了用于处理打印、打印设置和打印预览命令的代码。
+
+/////////////////////////////////////////////////////////////////////////////
+
+其他标准文件:
+
+StdAfx.h, StdAfx.cpp
+    这些文件用于生成名为 VideoCapture.pch 的预编译头(PCH)文件和名为 StdAfx.obj 的预编译类型文件。
+
+Resource.h
+    这是标准头文件,它定义新资源 ID。
+    Microsoft Visual C++ 将读取并更新此文件。
+
+VideoCapture.manifest
+	Windows XP 使用应用程序清单文件描述应用程序	对特定版本并行程序集的依赖性。加载程序使用此	信息从程序集缓存加载相应程序集或	从应用程序加载私有信息。应用程序清单可能作为	与应用程序可执行文件安装在同一文件夹中的外部 .manifest 文件包括在内以便重新发布,	也可能以资源的形式包括在该可执行文件中。
+/////////////////////////////////////////////////////////////////////////////
+
+其他注释:
+
+应用程序向导使用“TODO:”指示应添加或自定义的源代码部分。
+
+如果应用程序在共享 DLL 中使用 MFC,则将需要重新发布 MFC DLL。如果应用程序所用与操作系统的区域设置不同,则也将必须重新发布对应的本地化资源 MFC90XXX.DLL。
+有关这两个主题的详细信息,请参阅 MSDN 文档中有关重新发布 Visual C++ 应用程序的部分。
+
+/////////////////////////////////////////////////////////////////////////////

+ 55 - 0
VideoCapture/VideoCapture/SampleGrabberCB.cpp

@@ -0,0 +1,55 @@
+#include "StdAfx.h"
+#include "SampleGrabberCB.h"
+
+BOOL bOneShot = FALSE;
+CSampleGrabberCB mCB;
+CSampleGrabberCB::CSampleGrabberCB(void)
+{
+	_tcscpy_s(m_szFileName, _T("c:\\donaldo.bmp"));
+}
+
+CSampleGrabberCB::~CSampleGrabberCB(void)
+{
+}
+
+STDMETHODIMP CSampleGrabberCB::BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize )
+{
+	if( !bOneShot )
+		return 0;
+
+	if (!pBuffer)
+		return E_POINTER;
+	SaveBitmap(pBuffer, lBufferSize);
+	bOneShot = FALSE;
+	return 0;
+}
+
+//创建位图文件
+BOOL CSampleGrabberCB::SaveBitmap(BYTE * pBuffer, long lBufferSize )
+{
+	HANDLE hf = CreateFile(
+		m_szFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+		CREATE_ALWAYS, NULL, NULL );
+	if( hf == INVALID_HANDLE_VALUE )return 0;
+	// 写文件头
+	BITMAPFILEHEADER bfh;
+	memset( &bfh, 0, sizeof( bfh ) );
+	bfh.bfType = 'MB';
+	bfh.bfSize = sizeof( bfh ) + lBufferSize + sizeof( BITMAPINFOHEADER );
+	bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER );
+	DWORD dwWritten = 0;
+	WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL );
+	// 写位图格式
+	BITMAPINFOHEADER bih;
+	memset( &bih, 0, sizeof( bih ) );
+	bih.biSize = sizeof( bih );
+	bih.biWidth = lWidth;
+	bih.biHeight = lHeight;
+	bih.biPlanes = 1;
+	bih.biBitCount = 24;
+	WriteFile( hf, &bih, sizeof( bih ), &dwWritten, NULL );
+	// 写位图数据
+	WriteFile( hf, pBuffer, lBufferSize, &dwWritten, NULL );
+	CloseHandle( hf );
+	return 0;
+}

+ 42 - 0
VideoCapture/VideoCapture/SampleGrabberCB.h

@@ -0,0 +1,42 @@
+#ifndef __SAMPLE_GRABBER_CB__
+#define __SAMPLE_GRABBER_CB__
+#pragma once
+
+#include <Dshow.h>
+#include <Qedit.h>
+#pragma comment(lib, "Strmiids.lib")
+
+extern BOOL bOneShot;//È«¾Ö±äÁ¿
+class CSampleGrabberCB :public ISampleGrabberCB
+{
+public:
+	CSampleGrabberCB(void);
+	~CSampleGrabberCB(void);
+
+public:
+	long lWidth;
+	long lHeight;
+	TCHAR m_szFileName[MAX_PATH];// λͼÎļþÃû³Æ
+	STDMETHODIMP_(ULONG) AddRef() { return 2; }
+	STDMETHODIMP_(ULONG) Release() { return 1; }
+	STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
+	{
+		if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown )
+		{
+			*ppv = (void *)this;
+			return NOERROR;
+		}
+
+		return E_NOINTERFACE;
+	}
+	STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample ){
+		return 0;
+	}
+
+	STDMETHODIMP BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize );
+	BOOL SaveBitmap(BYTE * pBuffer, long lBufferSize );
+};
+
+extern CSampleGrabberCB mCB;
+
+#endif

+ 150 - 0
VideoCapture/VideoCapture/VideoCapture.cpp

@@ -0,0 +1,150 @@
+
+// VideoCapture.cpp : 定义应用程序的类行为。
+//
+
+#include "stdafx.h"
+#include "VideoCapture.h"
+#include "VideoCaptureDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CVideoCaptureApp
+
+BEGIN_MESSAGE_MAP(CVideoCaptureApp, CWinAppEx)
+	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CVideoCaptureApp 构造
+
+CVideoCaptureApp::CVideoCaptureApp()
+{
+	// TODO: 在此处添加构造代码,
+	// 将所有重要的初始化放置在 InitInstance 中
+}
+
+
+// 唯一的一个 CVideoCaptureApp 对象
+
+CVideoCaptureApp theApp;
+
+
+//列出硬件设备
+int listDevices(std::vector<std::string>& list)
+{
+	// 初始化COM环境;
+	::CoInitialize(NULL);
+	ICreateDevEnum *pDevEnum = NULL;
+	IEnumMoniker *pEnum = NULL;
+	int deviceCounter = 0;	
+
+	//HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum,reinterpret_cast<void**>(&pDevEnum));
+	HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum,(void**)(&pDevEnum));
+	if (SUCCEEDED(hr))
+	{
+		hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnum, 0);
+		if (hr == S_OK){
+
+			IMoniker *pMoniker = NULL;
+			while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
+			{
+				IPropertyBag *pPropBag;
+				hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,(void**)(&pPropBag));
+
+				if (FAILED(hr)) {
+					pMoniker->Release();
+					continue; // Skip this one, maybe the next one will work.
+				}
+
+				VARIANT varName;
+				VariantInit(&varName);
+				hr = pPropBag->Read(L"Description", &varName, 0);
+				if (FAILED(hr))
+				{
+					hr = pPropBag->Read(L"FriendlyName", &varName, 0);
+				}
+
+				if (SUCCEEDED(hr))
+				{
+					hr = pPropBag->Read(L"FriendlyName", &varName, 0);
+					int count = 0;
+					char tmp[255] = { 0 };
+					while (varName.bstrVal[count] != 0x00 && count < 255)
+					{
+						tmp[count] = (char)varName.bstrVal[count];
+						count++;
+					}
+					list.push_back(tmp);
+				}
+
+				pPropBag->Release();
+				pPropBag = NULL;
+				pMoniker->Release();
+				pMoniker = NULL;
+
+				deviceCounter++;
+			}
+
+			pDevEnum->Release();
+			pDevEnum = NULL;
+			pEnum->Release();
+			pEnum = NULL;
+		}
+	}
+
+	// 释放COM环境;
+	::CoUninitialize();
+
+	return deviceCounter;
+}
+// CVideoCaptureApp 初始化
+
+BOOL CVideoCaptureApp::InitInstance()
+{
+	// 如果一个运行在 Windows XP 上的应用程序清单指定要
+	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
+	//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
+	INITCOMMONCONTROLSEX InitCtrls;
+	InitCtrls.dwSize = sizeof(InitCtrls);
+	// 将它设置为包括所有要在应用程序中使用的
+	// 公共控件类。
+	InitCtrls.dwICC = ICC_WIN95_CLASSES;
+	InitCommonControlsEx(&InitCtrls);
+
+	CWinAppEx::InitInstance();
+
+	AfxEnableControlContainer();
+
+	// 标准初始化
+	// 如果未使用这些功能并希望减小
+	// 最终可执行文件的大小,则应移除下列
+	// 不需要的特定初始化例程
+	// 更改用于存储设置的注册表项
+	// TODO: 应适当修改该字符串,
+	// 例如修改为公司或组织名
+	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
+
+// 	std::vector<std::string> vtDevices;
+// 	listDevices(vtDevices);
+
+	CVideoCaptureDlg dlg;
+	m_pMainWnd = &dlg;
+	INT_PTR nResponse = dlg.DoModal();
+	if (nResponse == IDOK)
+	{
+		// TODO: 在此放置处理何时用
+		//  “确定”来关闭对话框的代码
+	}
+	else if (nResponse == IDCANCEL)
+	{
+		// TODO: 在此放置处理何时用
+		//  “取消”来关闭对话框的代码
+	}
+
+	// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
+	//  而不是启动应用程序的消息泵。
+	return FALSE;
+}

+ 32 - 0
VideoCapture/VideoCapture/VideoCapture.h

@@ -0,0 +1,32 @@
+
+// VideoCapture.h : PROJECT_NAME 应用程序的主头文件
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+	#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
+#endif
+
+#include "resource.h"		// 主符号
+
+
+// CVideoCaptureApp:
+// 有关此类的实现,请参阅 VideoCapture.cpp
+//
+
+class CVideoCaptureApp : public CWinAppEx
+{
+public:
+	CVideoCaptureApp();
+
+// 重写
+	public:
+	virtual BOOL InitInstance();
+
+// 实现
+
+	DECLARE_MESSAGE_MAP()
+};
+
+extern CVideoCaptureApp theApp;

+ 204 - 0
VideoCapture/VideoCapture/VideoCapture.rc

@@ -0,0 +1,204 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#ifndef APSTUDIO_INVOKED
+#include "targetver.h"
+#endif
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// 中文(中华人民共和国) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+#ifdef _WIN32
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+#pragma code_page(936)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#ifndef APSTUDIO_INVOKED\r\n"
+    "#include ""targetver.h""\r\n"
+    "#endif\r\n"
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+    "#define _AFX_NO_OLE_RESOURCES\r\n"
+    "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+    "\r\n"
+    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n"
+    "LANGUAGE 4, 2\r\n"
+    "#pragma code_page(936)\r\n"
+    "#include ""res\\VideoCapture.rc2""  // 非 Microsoft Visual C++ 编辑的资源\r\n"
+    "#include ""l.CHS\\afxres.rc""      // 标准组件\r\n"
+    "#endif\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME           ICON                    "res\\VideoCapture.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "关于 VideoCapture"
+FONT 9, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+    ICON            IDR_MAINFRAME,IDC_STATIC,14,14,21,20
+    LTEXT           "VideoCapture,1.0 版",IDC_STATIC,42,14,114,8,SS_NOPREFIX
+    LTEXT           "Copyright (C) 2020",IDC_STATIC,42,26,114,8
+    DEFPUSHBUTTON   "确定",IDOK,113,41,50,14,WS_GROUP
+END
+
+IDD_VIDEOCAPTURE_DIALOG DIALOGEX 0, 0, 279, 222
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "VideoCapture"
+FONT 9, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+    DEFPUSHBUTTON   "确定",IDOK,7,201,50,14
+    PUSHBUTTON      "取消",IDCANCEL,66,201,50,14
+    CONTROL         "",IDC_VIDEO,"Static",SS_BLACKFRAME,7,7,261,192
+    COMBOBOX        IDC_COMBO1,127,202,124,111,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "080403a8"
+        BEGIN
+            VALUE "CompanyName", "TODO: <公司名>"
+            VALUE "FileDescription", "TODO: <文件说明>"
+            VALUE "FileVersion", "1.0.0.1"
+            VALUE "InternalName", "VideoCapture.exe"
+            VALUE "LegalCopyright", "TODO: (C) <公司名>。保留所有权利。"
+            VALUE "OriginalFilename", "VideoCapture.exe"
+            VALUE "ProductName", "TODO: <产品名>"
+            VALUE "ProductVersion", "1.0.0.1"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x804, 936
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDD_ABOUTBOX, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 163
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 55
+    END
+
+    IDD_VIDEOCAPTURE_DIALOG, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 272
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 215
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE 
+BEGIN
+    IDS_ABOUTBOX            "关于 VideoCapture(&A)..."
+END
+
+#endif    // 中文(中华人民共和国) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+LANGUAGE 4, 2
+#pragma code_page(936)
+#include "res\VideoCapture.rc2"  // 非 Microsoft Visual C++ 编辑的资源
+#include "l.CHS\afxres.rc"      // 标准组件
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

+ 294 - 0
VideoCapture/VideoCapture/VideoCapture.vcproj

@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="gb2312"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="VideoCapture"
+	ProjectGUID="{C123187E-3196-481D-BE98-803810B9D472}"
+	RootNamespace="VideoCapture"
+	Keyword="MFCProj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="..\..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ConfigurationName)"
+			ConfigurationType="1"
+			UseOfMFC="2"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="_DEBUG"
+				MkTypLibCompatible="false"
+				ValidateParameters="true"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="2052"
+				AdditionalIncludeDirectories="$(IntDir)"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				UACExecutionLevel="2"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="..\..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ConfigurationName)"
+			ConfigurationType="1"
+			UseOfMFC="2"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="false"
+				ValidateParameters="true"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+				MinimalRebuild="false"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="2052"
+				AdditionalIncludeDirectories="$(IntDir)"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				UACExecutionLevel="2"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Ô´Îļþ"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\AVICap.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\CaptureVideo.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\SampleGrabberCB.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\VideoCapture.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\VideoCaptureDlg.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Í·Îļþ"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\AVICap.h"
+				>
+			</File>
+			<File
+				RelativePath=".\CaptureVideo.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Resource.h"
+				>
+			</File>
+			<File
+				RelativePath=".\SampleGrabberCB.h"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.h"
+				>
+			</File>
+			<File
+				RelativePath=".\targetver.h"
+				>
+			</File>
+			<File
+				RelativePath=".\VideoCapture.h"
+				>
+			</File>
+			<File
+				RelativePath=".\VideoCaptureDlg.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="×ÊÔ´Îļþ"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+			<File
+				RelativePath=".\res\VideoCapture.ico"
+				>
+			</File>
+			<File
+				RelativePath=".\VideoCapture.rc"
+				>
+			</File>
+			<File
+				RelativePath=".\res\VideoCapture.rc2"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

+ 270 - 0
VideoCapture/VideoCapture/VideoCaptureDlg.cpp

@@ -0,0 +1,270 @@
+
+// VideoCaptureDlg.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "VideoCapture.h"
+#include "VideoCaptureDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
+
+class CAboutDlg : public CDialog
+{
+public:
+	CAboutDlg();
+
+// 对话框数据
+	enum { IDD = IDD_ABOUTBOX };
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+// 实现
+protected:
+	DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
+{
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+END_MESSAGE_MAP()
+
+
+// CVideoCaptureDlg 对话框
+
+
+
+
+CVideoCaptureDlg::CVideoCaptureDlg(CWnd* pParent /*=NULL*/)
+	: CDialog(CVideoCaptureDlg::IDD, pParent)
+{
+	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+}
+
+void CVideoCaptureDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CVideoCaptureDlg, CDialog)
+	ON_WM_SYSCOMMAND()
+	ON_WM_PAINT()
+	ON_WM_QUERYDRAGICON()
+	//}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+// CVideoCaptureDlg 消息处理程序
+
+BOOL CVideoCaptureDlg::OnInitDialog()
+{
+	CDialog::OnInitDialog();
+
+	// 将“关于...”菜单项添加到系统菜单中。
+
+	// IDM_ABOUTBOX 必须在系统命令范围内。
+	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+	ASSERT(IDM_ABOUTBOX < 0xF000);
+
+	CMenu* pSysMenu = GetSystemMenu(FALSE);
+	if (pSysMenu != NULL)
+	{
+		BOOL bNameValid;
+		CString strAboutMenu;
+		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
+		ASSERT(bNameValid);
+		if (!strAboutMenu.IsEmpty())
+		{
+			pSysMenu->AppendMenu(MF_SEPARATOR);
+			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+		}
+	}
+
+	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
+	//  执行此操作
+	SetIcon(m_hIcon, TRUE);			// 设置大图标
+	SetIcon(m_hIcon, FALSE);		// 设置小图标
+
+	// TODO: 在此添加额外的初始化代码
+
+#if 0
+	char szDeviceName[80];
+	char szDeviceVersion[80];
+	for (int i = 0; i < 10; i++)
+	{
+		if (capGetDriverDescription(i,szDeviceName,sizeof (szDeviceName),szDeviceVersion,sizeof (szDeviceVersion)))
+		{
+			// Append name to list of installed capture drivers
+			// and then let the user select a driver to use.
+			TRACE2(_T("%s,%s\n"), szDeviceVersion, szDeviceName);
+
+		}
+	}
+	InitVideo();
+#endif
+	
+#if 1
+	CComboBox *hDeviceWnd = (CComboBox*)GetDlgItem(IDC_COMBO1);
+	m_cap.EnumDevices(hDeviceWnd->GetSafeHwnd());
+	hDeviceWnd->SetCurSel(1);
+
+	CRect rect;
+	CWnd *hVideoWnd = GetDlgItem(IDC_VIDEO);
+	hVideoWnd->GetWindowRect(rect);
+	m_cap.Init(1, hVideoWnd->GetSafeHwnd());
+#endif
+
+	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
+}
+
+void CVideoCaptureDlg::OnSysCommand(UINT nID, LPARAM lParam)
+{
+	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
+	{
+		CAboutDlg dlgAbout;
+		dlgAbout.DoModal();
+	}
+	else
+	{
+		CDialog::OnSysCommand(nID, lParam);
+	}
+}
+
+// 如果向对话框添加最小化按钮,则需要下面的代码
+//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
+//  这将由框架自动完成。
+
+void CVideoCaptureDlg::OnPaint()
+{
+	if (IsIconic())
+	{
+		CPaintDC dc(this); // 用于绘制的设备上下文
+
+		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
+
+		// 使图标在工作区矩形中居中
+		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;
+
+		// 绘制图标
+		dc.DrawIcon(x, y, m_hIcon);
+	}
+	else
+	{
+		CDialog::OnPaint();
+	}
+}
+
+//当用户拖动最小化窗口时系统调用此函数取得光标
+//显示。
+HCURSOR CVideoCaptureDlg::OnQueryDragIcon()
+{
+	return static_cast<HCURSOR>(m_hIcon);
+}
+
+HWND ghCapWnd;
+LRESULT CALLBACK FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr)    
+{   
+	return 0 ;    
+}    
+
+void CVideoCaptureDlg::InitVideo()
+{
+	CRect rect;
+	CWnd *hVideoWnd = GetDlgItem(IDC_VIDEO);
+	hVideoWnd->GetWindowRect(rect);
+	//create capture window
+	ghCapWnd = capCreateCaptureWindow("My Own Capture Window",WS_CHILD | WS_VISIBLE,0,0,(rect.right-rect.left),(rect.bottom-rect.top),hVideoWnd->GetSafeHwnd(),1235);
+	ASSERT(ghCapWnd);
+
+	//连接设备
+	if ( capDriverConnect(ghCapWnd,0) )
+	{
+		CAPDRIVERCAPS _CapDrvCap;		// CAPDRIVERCAPS 结构,定义驱动器性能 
+		CAPSTATUS _CapStatus;			// CAPSTATUS 结构,定义捕捉窗口当前状态 
+	
+		//得到驱动器的性能   
+		capDriverGetCaps(ghCapWnd,sizeof(CAPDRIVERCAPS), &_CapDrvCap);  
+		if ( _CapDrvCap.fCaptureInitialized )
+		{
+			// 如果初始化成功;
+			capSetVideoFormat(ghCapWnd, &_CapStatus, sizeof(_CapStatus));
+			// 设置预示帧频;
+			capPreviewRate(ghCapWnd, 30);
+			//capSetCallbackOnFrame(ghCapWnd, FrameCallbackProc);
+		}
+
+		//获得参数
+		CAPTUREPARMS CapParms;
+		capCaptureGetSetup(ghCapWnd,&CapParms,sizeof(CAPTUREPARMS));
+		//设置帧数
+		CapParms.fLimitEnabled=FALSE;
+		//是否捕捉音频
+		CapParms.fCaptureAudio=FALSE;
+		//MCI Device支持
+		CapParms.fMCIControl=FALSE;
+		//设置窗口,如果为false,捕捉画面在桌面上
+		CapParms.fYield=TRUE;
+		//停止捕捉键设置
+		CapParms.vKeyAbort=VK_ESCAPE;
+		CapParms.fAbortLeftMouse=FALSE;
+		CapParms.fAbortRightMouse=FALSE;
+		capCaptureSetSetup(ghCapWnd,&CapParms,sizeof(CAPTUREPARMS));
+		//设置预览时的比例
+		capPreviewScale(ghCapWnd, 66);
+		//是否支持比例变化
+		capPreviewScale(ghCapWnd, false);
+		//打开预览
+		capPreview(ghCapWnd, true);  
+	}
+	else
+	{
+		AfxMessageBox(_T("打开摄像头失败"));
+	}
+}
+
+BOOL CVideoCaptureDlg::PreTranslateMessage(MSG* pMsg)
+{
+	// TODO: 在此添加专用代码和/或调用基类
+	if (pMsg->message == WM_KEYDOWN)
+	{
+		if (pMsg->wParam == VK_F3)
+		{
+			static BOOL bTopWnd = FALSE;
+			if (bTopWnd == FALSE)
+			{
+				SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);//窗口置顶
+				CString strVersionInfo = _T("视频采集卡 - 前置窗口(请按F3取消或开启前置)");
+				SetWindowText(strVersionInfo);
+			}
+			else
+			{
+				SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);//取消窗口置顶	
+				CString strVersionInfo = _T("视频采集卡 - 取消前置(请按F3取消或开启前置)");
+				SetWindowText(strVersionInfo);
+			}
+
+			bTopWnd = !bTopWnd;
+
+			// 必须退出,否则执行2次;
+			return TRUE;
+		}
+	}
+	return CDialog::PreTranslateMessage(pMsg);
+}

+ 38 - 0
VideoCapture/VideoCapture/VideoCaptureDlg.h

@@ -0,0 +1,38 @@
+
+// VideoCaptureDlg.h : 头文件
+//
+
+#pragma once
+
+#include "CaptureVideo.h"
+
+// CVideoCaptureDlg 对话框
+class CVideoCaptureDlg : public CDialog
+{
+// 构造
+public:
+	CVideoCaptureDlg(CWnd* pParent = NULL);	// 标准构造函数
+
+// 对话框数据
+	enum { IDD = IDD_VIDEOCAPTURE_DIALOG };
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持
+
+
+	void InitVideo();
+// 实现
+protected:
+	HICON m_hIcon;
+
+	// 生成的消息映射函数
+	virtual BOOL OnInitDialog();
+	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+	afx_msg void OnPaint();
+	afx_msg HCURSOR OnQueryDragIcon();
+	DECLARE_MESSAGE_MAP()
+
+public:
+	CCaptureVideo m_cap;
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+};

BIN
VideoCapture/VideoCapture/res/VideoCapture.ico


+ 13 - 0
VideoCapture/VideoCapture/res/VideoCapture.rc2

@@ -0,0 +1,13 @@
+//
+// VideoCapture.RC2 - Microsoft Visual C++ 不会直接编辑的资源
+//
+
+#ifdef APSTUDIO_INVOKED
+#error 此文件不能用 Microsoft Visual C++ 编辑
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// 在此处添加手动编辑的资源...
+
+/////////////////////////////////////////////////////////////////////////////

+ 23 - 0
VideoCapture/VideoCapture/resource.h

@@ -0,0 +1,23 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by VideoCapture.rc
+//
+#define IDM_ABOUTBOX                    0x0010
+#define IDD_ABOUTBOX                    100
+#define IDS_ABOUTBOX                    101
+#define IDD_VIDEOCAPTURE_DIALOG         102
+#define IDR_MAINFRAME                   128
+#define IDC_VIDEO                       1000
+#define IDC_LIST2                       1002
+#define IDC_COMBO1                      1003
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        129
+#define _APS_NEXT_COMMAND_VALUE         32771
+#define _APS_NEXT_CONTROL_VALUE         1004
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif

+ 8 - 0
VideoCapture/VideoCapture/stdafx.cpp

@@ -0,0 +1,8 @@
+
+// stdafx.cpp : 只包括标准包含文件的源文件
+// VideoCapture.pch 将作为预编译头
+// stdafx.obj 将包含预编译类型信息
+
+#include "stdafx.h"
+
+

+ 65 - 0
VideoCapture/VideoCapture/stdafx.h

@@ -0,0 +1,65 @@
+
+// stdafx.h : 标准系统包含文件的包含文件,
+// 或是经常使用但不常更改的
+// 特定于项目的包含文件
+
+#pragma once
+
+#ifndef _SECURE_ATL
+#define _SECURE_ATL 1
+#endif
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN            // 从 Windows 头中排除极少使用的资料
+#endif
+
+#include "targetver.h"
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 构造函数将是显式的
+
+// 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏
+#define _AFX_ALL_WARNINGS
+
+#include <afxwin.h>         // MFC 核心组件和标准组件
+#include <afxext.h>         // MFC 扩展
+
+
+#include <afxdisp.h>        // MFC 自动化类
+
+
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxdtctl.h>           // MFC 对 Internet Explorer 4 公共控件的支持
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h>             // MFC 对 Windows 公共控件的支持
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <afxcontrolbars.h>     // 功能区和控件条的 MFC 支持
+
+
+
+
+
+#include <Vfw.h>
+#pragma comment(lib, "vfw32.lib")
+#include <Dshow.h>
+#include <strmif.h>
+#pragma comment(lib, "strmiids.lib")
+
+#include <vector>
+#include <string>
+
+#ifdef _UNICODE
+#if defined _M_IX86
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#elif defined _M_IA64
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#elif defined _M_X64
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#else
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#endif
+#endif
+
+

+ 26 - 0
VideoCapture/VideoCapture/targetver.h

@@ -0,0 +1,26 @@
+
+#pragma once
+
+// 以下宏定义要求的最低平台。要求的最低平台
+// 是具有运行应用程序所需功能的 Windows、Internet Explorer 等产品的
+// 最早版本。通过在指定版本及更低版本的平台上启用所有可用的功能,宏可以
+// 正常工作。
+
+// 如果必须要针对低于以下指定版本的平台,请修改下列定义。
+// 有关不同平台对应值的最新信息,请参考 MSDN。
+#ifndef WINVER                          // 指定要求的最低平台是 Windows Vista。
+#define WINVER 0x0600           // 将此值更改为相应的值,以适用于 Windows 的其他版本。
+#endif
+
+#ifndef _WIN32_WINNT            // 指定要求的最低平台是 Windows Vista。
+#define _WIN32_WINNT 0x0600     // 将此值更改为相应的值,以适用于 Windows 的其他版本。
+#endif
+
+#ifndef _WIN32_WINDOWS          // 指定要求的最低平台是 Windows 98。
+#define _WIN32_WINDOWS 0x0410 // 将此值更改为适当的值,以适用于 Windows Me 或更高版本。
+#endif
+
+#ifndef _WIN32_IE                       // 指定要求的最低平台是 Internet Explorer 7.0。
+#define _WIN32_IE 0x0700        // 将此值更改为相应的值,以适用于 IE 的其他版本。
+#endif
+