使用 vfw32.lib 提供的 capCreateCaptureWindow 等 API 建立捕獲視窗,透過回呼函數處理狀態、錯誤、影格資料。
HWND ghWndCap; // 捕獲視窗句柄 CAPDRIVERCAPS gCapDriverCaps; // 驅動程式能力 CAPSTATUS gCapStatus; // 捕獲狀態 char szCaptureFile[] = "MYCAP.AVI";
LRESULT CALLBACK StatusCallbackProc(HWND hWnd, int nID, LPSTR lpStatusText) {
if (!ghWndCap) return FALSE;
capGetStatus(ghWndCap, &gCapStatus, sizeof(CAPSTATUS));
SetWindowPos(ghWndCap, NULL, 0, 0, gCapStatus.uiImageWidth, gCapStatus.uiImageHeight, SWP_NOZORDER|SWP_NOMOVE);
if (nID == 0) { SetWindowText(ghWndCap, "hello"); return TRUE; }
char buf[64]; wsprintf(buf, "Status# %d: %s", nID, lpStatusText);
SetWindowText(ghWndCap, buf);
return TRUE;
}
LRESULT CALLBACK ErrorCallbackProc(HWND hWnd, int nErrID, LPSTR lpErrorText) {
if (!ghWndCap || nErrID == 0) return TRUE;
char buf[64]; wsprintf(buf, "Error# %d", nErrID);
MessageBox(hWnd, lpErrorText, buf, MB_OK|MB_ICONEXCLAMATION);
return TRUE;
}
LRESULT CALLBACK FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr) {
FILE* fp = fopen("caram.dat", "wb");
if (fp) { fwrite(lpVHdr->lpData, 1, lpVHdr->dwBufferLength, fp); fclose(fp); }
return TRUE;
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nShow) {
WNDCLASS wc = { CS_HREDRAW|CS_VREDRAW, WndProc, 0,0, hInst,
LoadIcon(NULL,IDI_APPLICATION), LoadCursor(NULL,IDC_ARROW),
(HBRUSH)GetStockObject(WHITE_BRUSH), NULL, TEXT("HelloWin") };
RegisterClass(&wc);
HWND hwnd = CreateWindow(TEXT("HelloWin"), TEXT("VFW Capture"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInst, NULL);
ShowWindow(hwnd, nShow); UpdateWindow(hwnd);
// 建立捕獲視窗
ghWndCap = capCreateCaptureWindow(TEXT("Capture"), WS_CHILD|WS_VISIBLE, 0,0,640,480, hwnd, 1);
capSetCallbackOnStatus(ghWndCap, StatusCallbackProc);
capSetCallbackOnError(ghWndCap, ErrorCallbackProc);
capSetCallbackOnFrame(ghWndCap, FrameCallbackProc);
capDriverConnect(ghWndCap, 0); // 連接第一個裝置
capPreviewRate(ghWndCap, 33); // ~30fps
capPreview(ghWndCap, TRUE);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
capDriverDisconnect(ghWndCap);
return msg.wParam;
}
cap* 函數的返回值。