no?crap only codes
?1
class
?CCaptureVideo?:?
public
?CWnd?
?2
{
?3
????friend?
class
?CSampleGrabberCB;
?4
public
:
?5
????
void
?GrabOneFrame(BOOL?bGrab,?
const
?CString
&
?szFileName);
?6
????HRESULT?Init(
int
?iDeviceID,HWND?hWnd);
?7
????
int
?EnumDevices(HWND?hList);
?8
????CCaptureVideo();
?9
????
virtual
?
~
CCaptureVideo();
10
private
:
11
????HWND?m_hWnd;
12
????IGraphBuilder?
*
m_pGB;
13
????ICaptureGraphBuilder2
*
?m_pCapture;
14
????IBaseFilter
*
?m_pBF;
15
????IMediaControl
*
?m_pMC;
16
????IMediaEventEx?
*
?m_pME;
17
????IVideoWindow
*
?m_pVW;
18
????CComPtr
<
ISampleGrabber
>
?m_pGrabber;
19
protected
:
20
????
void
?FreeMediaType(AM_MEDIA_TYPE
&
?mt);
21
????
bool
?BindFilter(
int
?deviceId,?IBaseFilter?
**
pFilter);
22
????
void
?ResizeVideoWindow();
23
????HRESULT?SetupVideoWindow();
24
????HRESULT?InitCaptureGraphBuilder();
25
}
;
class
?CCaptureVideo?:?
public
?CWnd??2
{?3
????friend?
class
?CSampleGrabberCB;?4
public
:?5
????
void
?GrabOneFrame(BOOL?bGrab,?
const
?CString
&
?szFileName);?6
????HRESULT?Init(
int
?iDeviceID,HWND?hWnd);?7
????
int
?EnumDevices(HWND?hList);?8
????CCaptureVideo();?9
????
virtual
?
~
CCaptureVideo();10
private
:11
????HWND?m_hWnd;12
????IGraphBuilder?
*
m_pGB;13
????ICaptureGraphBuilder2
*
?m_pCapture;14
????IBaseFilter
*
?m_pBF;15
????IMediaControl
*
?m_pMC;16
????IMediaEventEx?
*
?m_pME;17
????IVideoWindow
*
?m_pVW;18
????CComPtr
<
ISampleGrabber
>
?m_pGrabber;19
protected
:20
????
void
?FreeMediaType(AM_MEDIA_TYPE
&
?mt);21
????
bool
?BindFilter(
int
?deviceId,?IBaseFilter?
**
pFilter);22
????
void
?ResizeVideoWindow();23
????HRESULT?SetupVideoWindow();24
????HRESULT?InitCaptureGraphBuilder();25
}
;
?1
?2
class
?CSampleGrabberCB?:?
public
?ISampleGrabberCB?
?3
{
?4
public
:
?5
????
long
?lWidth;
?6
????
long
?lHeight;
?7
????
static
?CString?m_szFileName;
//
?位圖文件名稱
?8
????CSampleGrabberCB(?)
?9
????
{
10
????}
?
11
12
????STDMETHODIMP_(ULONG)?AddRef()?
13
????
{?
return
?
2
;?}
14
15
????STDMETHODIMP_(ULONG)?Release()?
16
????
{?
return
?
1
;?}
17
18
????STDMETHODIMP?QueryInterface(REFIID?riid,?
void
?
**
?ppv)
19
????
{
20
????????
if
(?riid?
==
?IID_ISampleGrabberCB?
||
?riid?
==
?IID_IUnknown?)
21
????????
{?
22
????????????
*
ppv?
=
?(
void
?
*
)?static_cast
<
ISampleGrabberCB
*>
?(?
this
?);
23
????????????
return
?NOERROR;
24
????????}
?
25
????????
return
?E_NOINTERFACE;
26
????}
27
28
????STDMETHODIMP?SampleCB(?
double
?SampleTime,?IMediaSample?
*
?pSample?)
29
????
{
30
????????
return
?
0
;
31
????}
32
33
????STDMETHODIMP?BufferCB(?
double
?dblSampleTime,?BYTE?
*
?pBuffer,?
long
?lBufferSize?)
34
????
{
35
????????
if
(?
!
bOneShot?)
return
?
0
;
36
????????
37
????????
if
?(
!
pBuffer)
38
????????????
return
?E_POINTER;
39
40
????????
if
(SaveBitmap(pBuffer,?lBufferSize))
41
????????
{
42
????????????
//
?notify?has?create?a?bitmap?file;
43
????????????CGlobalData::m_pMainView
->
HasSavedPhoto(m_szFileName);
44
????????}
45
46
????????bOneShot?
=
?FALSE;
47
48
????
49
????????
return
?
0
;
50
????}
51
????
//
創建位圖文件
52
????BOOL?SaveBitmap(BYTE?
*
?pBuffer,?
long
?lBufferSize?)
53
????
{
54
????????HANDLE?hf?
=
?CreateFile(
55
????????????m_szFileName,
56
????????????GENERIC_WRITE,?FILE_SHARE_READ,?NULL,
57
????????????CREATE_ALWAYS,
58
????????????NULL,?
59
????????????NULL?);
60
61
????????
if
(?hf?
==
?INVALID_HANDLE_VALUE?)
62
????????????
return
?FALSE;
63
64
????????
//
?寫文件頭?
65
????????BITMAPFILEHEADER?bfh;
66
????????memset(?
&
bfh,?
0
,?
sizeof
(?bfh?)?);
67
????????bfh.bfType?
=
?
'
MB
'
;
68
????????bfh.bfSize?
=
?
sizeof
(?bfh?)?
+
?lBufferSize?
+
?
sizeof
(?BITMAPINFOHEADER?);
69
????????bfh.bfOffBits?
=
?
sizeof
(?BITMAPINFOHEADER?)?
+
?
sizeof
(?BITMAPFILEHEADER?);
70
????????DWORD?dwWritten?
=
?
0
;
71
????????WriteFile(?hf,?
&
bfh,?
sizeof
(?bfh?),?
&
dwWritten,?NULL?);
72
73
????????
//
?寫位圖格式
74
????????BITMAPINFOHEADER?bih;
75
????????memset(?
&
bih,?
0
,?
sizeof
(?bih?)?);
76
????????bih.biSize?
=
?
sizeof
(?bih?);
77
????????bih.biWidth?
=
?lWidth;
78
????????bih.biHeight?
=
?lHeight;
79
????????bih.biPlanes?
=
?
1
;
80
????????bih.biBitCount?
=
?
24
;
81
????????WriteFile(?hf,?
&
bih,?
sizeof
(?bih?),?
&
dwWritten,?NULL?);
82
83
????????
//
?寫位圖數據
84
????????WriteFile(?hf,?pBuffer,?lBufferSize,?
&
dwWritten,?NULL?);
85
86
????????CloseHandle(?hf?);
87
88
????????
return
?TRUE;
89
????}
90
}
;
?2
class
?CSampleGrabberCB?:?
public
?ISampleGrabberCB??3
{?4
public
:?5
????
long
?lWidth;?6
????
long
?lHeight;?7
????
static
?CString?m_szFileName;
//
?位圖文件名稱
?8
????CSampleGrabberCB(?)?9
????
{10
????}
?11
12
????STDMETHODIMP_(ULONG)?AddRef()?13
????
{?
return
?
2
;?}
14
15
????STDMETHODIMP_(ULONG)?Release()?16
????
{?
return
?
1
;?}
17
18
????STDMETHODIMP?QueryInterface(REFIID?riid,?
void
?
**
?ppv)19
????
{20
????????
if
(?riid?
==
?IID_ISampleGrabberCB?
||
?riid?
==
?IID_IUnknown?)21
????????
{?22
????????????
*
ppv?
=
?(
void
?
*
)?static_cast
<
ISampleGrabberCB
*>
?(?
this
?);23
????????????
return
?NOERROR;24
????????}
?25
????????
return
?E_NOINTERFACE;26
????}
27
28
????STDMETHODIMP?SampleCB(?
double
?SampleTime,?IMediaSample?
*
?pSample?)29
????
{30
????????
return
?
0
;31
????}
32
33
????STDMETHODIMP?BufferCB(?
double
?dblSampleTime,?BYTE?
*
?pBuffer,?
long
?lBufferSize?)34
????
{35
????????
if
(?
!
bOneShot?)
return
?
0
;36
????????37
????????
if
?(
!
pBuffer)38
????????????
return
?E_POINTER;39
40
????????
if
(SaveBitmap(pBuffer,?lBufferSize))41
????????
{42
????????????
//
?notify?has?create?a?bitmap?file;
43
????????????CGlobalData::m_pMainView
->
HasSavedPhoto(m_szFileName);44
????????}
45
46
????????bOneShot?
=
?FALSE;47
48
????49
????????
return
?
0
;50
????}
51
????
//
創建位圖文件
52
????BOOL?SaveBitmap(BYTE?
*
?pBuffer,?
long
?lBufferSize?)53
????
{54
????????HANDLE?hf?
=
?CreateFile(55
????????????m_szFileName,56
????????????GENERIC_WRITE,?FILE_SHARE_READ,?NULL,57
????????????CREATE_ALWAYS,58
????????????NULL,?59
????????????NULL?);60
61
????????
if
(?hf?
==
?INVALID_HANDLE_VALUE?)62
????????????
return
?FALSE;63
64
????????
//
?寫文件頭?
65
????????BITMAPFILEHEADER?bfh;66
????????memset(?
&
bfh,?
0
,?
sizeof
(?bfh?)?);67
????????bfh.bfType?
=
?
'
MB
'
;68
????????bfh.bfSize?
=
?
sizeof
(?bfh?)?
+
?lBufferSize?
+
?
sizeof
(?BITMAPINFOHEADER?);69
????????bfh.bfOffBits?
=
?
sizeof
(?BITMAPINFOHEADER?)?
+
?
sizeof
(?BITMAPFILEHEADER?);70
????????DWORD?dwWritten?
=
?
0
;71
????????WriteFile(?hf,?
&
bfh,?
sizeof
(?bfh?),?
&
dwWritten,?NULL?);72
73
????????
//
?寫位圖格式
74
????????BITMAPINFOHEADER?bih;75
????????memset(?
&
bih,?
0
,?
sizeof
(?bih?)?);76
????????bih.biSize?
=
?
sizeof
(?bih?);77
????????bih.biWidth?
=
?lWidth;78
????????bih.biHeight?
=
?lHeight;79
????????bih.biPlanes?
=
?
1
;80
????????bih.biBitCount?
=
?
24
;81
????????WriteFile(?hf,?
&
bih,?
sizeof
(?bih?),?
&
dwWritten,?NULL?);82
83
????????
//
?寫位圖數據
84
????????WriteFile(?hf,?pBuffer,?lBufferSize,?
&
dwWritten,?NULL?);85
86
????????CloseHandle(?hf?);87
88
????????
return
?TRUE;89
????}
90
}
;
/**/
/////////////////////////////////////////////////////////////////////
/
//
?Construction/Destruction
/**/
/////////////////////////////////////////////////////////////////////
/
CCaptureVideo::CCaptureVideo()
{
????m_pBF?
=
?
0
;
????m_hWnd?
=
?NULL;
????m_pVW?
=
?NULL;
????m_pMC?
=
?NULL;
????m_pME?
=
?NULL;
????m_pGB?
=
?NULL;
????m_pCapture?
=
?NULL;?
}
CCaptureVideo::
~
CCaptureVideo()
{
????
//
?Stop?media?playback
????
if
(m_pMC)
????????m_pMC
->
StopWhenReady();
????
//
?Stop?receiving?events
????
if
?(m_pME)
????????m_pME
->
SetNotifyWindow(NULL,?WM_GRAPHNOTIFY,?
0
);

????
if
(m_pVW)
{
????????m_pVW
->
put_Visible(OAFALSE);
????????m_pVW
->
put_Owner(NULL);
????}
????SAFE_RELEASE(m_pMC);
????SAFE_RELEASE(m_pME);
????SAFE_RELEASE(m_pVW);
????SAFE_RELEASE(m_pGB);
????SAFE_RELEASE(m_pBF);
????SAFE_RELEASE(m_pCapture);
????
//
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
;
????CComPtr
<
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
"
Video?Capture
"
);
????
if
?(FAILED(hr))
????
{
????????m_pBF
->
Release();
????????
return
?hr;
????}
????
//
?create?a?sample?grabber
????hr?
=
?m_pGrabber.CoCreateInstance(?CLSID_SampleGrabber?);
????
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
;
????IBaseFilter?
*
?pSrc?
=
?NULL;
????
//
?enumerate?all?video?capture?devices
????CComPtr
<
ICreateDevEnum
>
?pCreateDevEnum?
=
?NULL;
????HRESULT?hr?
=
?CoCreateInstance(CLSID_SystemDeviceEnum,?NULL,?CLSCTX_INPROC,
????????IID_ICreateDevEnum,?(
void
**
)
&
pCreateDevEnum);
????
if
?(FAILED(hr))
????
{
????????
return
?
false
;
????}
????CComPtr
<
IEnumMoniker
>
?pEm?
=
?NULL;
????hr?
=
?pCreateDevEnum
->
CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&
pEm,?
0
);
????
if
?(FAILED(hr))?
????
{
????????
return
?
false
;
????}
????
//
pEm->Reset();
????ULONG?cFetched;
????IMoniker?
*
pM;
????
int
?index?
=
?
0
;
????
while
(S_OK?
==
?(pEm
->
Next(
1
,?
&
pM,?
&
cFetched))?
&&
?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
**
)
&
pSrc);
????????????????}
????????????????SysFreeString(var.bstrVal);
????????????}
????????????pBag
->
Release();
????????}
????????pM
->
Release();
????????index
++
;
????}
????
*
pFilter?
=
?pSrc;
????
return
?
true
;
}
HRESULT?CCaptureVideo::InitCaptureGraphBuilder()
{
????HRESULT?hr;
????
????
//
?創建IGraphBuilder接口
????hr
=
CoCreateInstance(CLSID_FilterGraph,?NULL,?CLSCTX_INPROC,
????????IID_IGraphBuilder,?(
void
?
**
)
&
m_pGB);
????
if
?(FAILED(hr))
????????
return
?hr;
????
//
?創建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;
????hr?
=
?m_pGB
->
QueryInterface(IID_IMediaEvent,?(LPVOID?
*
)?
&
m_pME);
????
if
?(FAILED(hr))
????????
return
?hr;
????
//
?Set?the?window?handle?used?to?process?graph?events
????hr?
=
?m_pME
->
SetNotifyWindow((OAHWND)m_hWnd,?WM_GRAPHNOTIFY,?
0
);
????
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,?
const
?CString
&
?szFileName)
{
????bOneShot?
=
?bGrab;
????CSampleGrabberCB::m_szFileName?
=
?szFileName;
}
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;
????}
}
?

