#include <windows.h>
#include <vfw.h>
#include <TCHAR.H>
#pragma comment(lib, "vfw32.lib")
HWND AVIhwnd;
HWND hwnd;
HDC hdc, hdcScene;
DWORD AVIwidth = 640, AVIheight = 480;
BYTE BmpByte[1920*480];
BITMAPINFO bmpInfo;
HBITMAP hBmpScene;
HGDIOBJ hGDIObj;
long InputWidth, OutputWidth;
long cB, cG, cR;
long X, Y;
TCHAR szClassName[] = TEXT("Vedio");
TCHAR szWindowTitle[] = TEXT("Vedio Catch");
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK FrameCallbackProc(HWND, LPVIDEOHDR);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASS wc;
MSG msg;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_3DSHADOW;
wc.lpszMenuName = 0;
wc.lpszClassName = szClassName;
if (!RegisterClass(&wc))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"), TEXT("ERROR NOTE!"), MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szClassName, szWindowTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, AVIwidth, AVIheight,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);
//DIB结构体的各种属性设置
ZeroMemory(&bmpInfo.bmiHeader, sizeof(BITMAPINFOHEADER));
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biBitCount = 24;
bmpInfo.bmiHeader.biWidth = AVIwidth;
bmpInfo.bmiHeader.biHeight = AVIheight;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biClrUsed = 0;
bmpInfo.bmiHeader.biClrImportant = 0;
bmpInfo.bmiHeader.biSizeImage = AVIwidth * AVIheight * bmpInfo.bmiHeader.biBitCount / 8;
//把上面的biSizeImage写成了和前面一样的biSize,调试结果视频画面不动;找了好久原因~~~~不能马虎啊!
//创建应用程序可以直接写入的、与设备无关的位图(DIB)
hdcScene = CreateCompatibleDC(hdc);
hBmpScene = CreateDIBSection(hdcScene, &bmpInfo, DIB_RGB_COLORS, NULL, 0, 0);
hGDIObj = SelectObject(hdcScene, hBmpScene);
OutputWidth = AVIwidth * 3;
InputWidth = AVIwidth * 3;
//创建视频捕获窗口
AVIhwnd = capCreateCaptureWindow(szWindowTitle, WS_CHILD | WS_VISIBLE,
0, 0, AVIwidth, AVIheight, hwnd, 1);
if (NULL == AVIhwnd)
{
MessageBox(hwnd, TEXT("Create Failed!"), TEXT("视频捕获"), MB_ICONERROR);
return 0;
}
else
{
hdc = GetWindowDC(hwnd);
//设置回调函数 macro
capSetCallbackOnFrame(AVIhwnd, FrameCallbackProc);
//The capDriverConnect macro connects a capture window to a capture driver.
BOOL flag = capDriverConnect(AVIhwnd, 0);
if (flag)
{
CAPDRIVERCAPS Cps;
capDriverGetCaps(AVIhwnd, &Cps, sizeof(CAPDRIVERCAPS));
//The capPreviewRate macro sets the frame display rate in preview mode.
capPreviewRate(AVIhwnd, 30);
}
else
{
MessageBox(hwnd, TEXT("不能打开设备驱动!"), TEXT("提示"), MB_ICONERROR);
return 0;
}
}
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
SelectObject(hdcScene, hGDIObj);
DeleteObject(hBmpScene);
DeleteDC(hdcScene);
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK FrameCallbackProc(HWND ghwnd, LPVIDEOHDR lpVData)
{
for (Y = 1; Y <= AVIheight; ++Y)
{
for (X = 1; X <= AVIwidth; ++X)
{
cB = lpVData->lpData[((AVIheight-Y)*InputWidth)+(X*3)];
cG = lpVData->lpData[((AVIheight-Y)*InputWidth)+(X*3)+1];
cR = lpVData->lpData[((AVIheight-Y)*InputWidth)+(X*3)+2];
BmpByte[((Y-1)*OutputWidth)+(X*3)]=cB;
BmpByte[((Y-1)*OutputWidth)+(X*3)+1]=cG;
BmpByte[((Y-1)*OutputWidth)+(X*3)+2]=cR;
}
}
SetBitmapBits(hBmpScene, sizeof(BmpByte), BmpByte);
BitBlt(hdc, 0, 0, AVIwidth, AVIheight, hdcScene, 0, 0, SRCCOPY);
return 0;
}