CapPicture.CPP
Upload User: hzllkj
Upload Date: 2009-12-19
Package Size: 21k
Code Size: 18k
Category:

Video Capture

Development Platform:

Visual C++

  1. /********************************************************************
  2. *  CapPicture.c: Source code for generic                             *
  3. *                                                                    *
  4. *  Comments: Video capture and display with some processing          *
  5. *                                                                    *
  6. *  Functions:                                                        *
  7. *     WinMain      - Application entry point                         *
  8. *     MainWndProc  - main window procedure                           *
  9. *                                                                    *
  10. *                                                                    *
  11. ********************************************************************/
  12. /*********************  Header Files  *********************/
  13. #include <windows.h> // windows GUI and services
  14. #include <vfw.h> // video for windows library
  15. #include <commdlg.h> // common dialogs
  16. #include "CapPicture.h" // resource header
  17. /*********************  Prototypes  ***********************/
  18. // main window procedure
  19. LRESULT WINAPI MainWndProc( HWND, UINT, WPARAM, LPARAM ); 
  20. // Select Capture Driver Procedure
  21. LRESULT WINAPI SelCapDrvProc( HWND, UINT, WPARAM, LPARAM );
  22. // Enumerate Capture Drivers
  23. int EnumCapDrv();
  24. // Create the buttons on the main window
  25. //int CreateWndButtons(); this doesnt work
  26. // handle the right click popup menu
  27. VOID APIENTRY HandlePopupMenu(HWND, POINT);
  28. // video thread procedure
  29. DWORD WINAPI videoThreadProc(LPVOID lParam);
  30. /*******************  Global Variables ********************/
  31. HANDLE ghInstance; // application instance
  32. HWND hwndMain; // main window handle
  33. HWND hwndVideo; // video capture window
  34. HWND hwndSelCapDrvDlg; // Select the capture driver dialog
  35. HWND hwndSelCapDrvDlg_LBox; // list box for select capture driver dialog
  36. HWND hwndExit; // exit button
  37. HWND hwndMin; // minimize button
  38. HWND hwndHelp; // help button
  39. HWND hwndRecord; // record button
  40. HANDLE hVideoThread; // thread to stop the hang when recording video
  41. HRGN hRegion1; // region for window shaping
  42. CAPDRIVERCAPS CapDrvCaps; // driver capabilities
  43. bool isRecordFileOpen = false; // flag set if record file is open 
  44. char recordFile[260]; // file to hold recording
  45. bool isPicFileOpen = false; // flag set if snapshot file is open
  46. char pictureFile[260]; // file to hold snapshot
  47. bool isRecording = false; // are we recording?
  48. bool threadEnd = false; // should the video thread end?
  49. /********************************************************************
  50. *  *
  51. *  CLASSES, ENUMS, & STRUCTS  *
  52. *   *
  53. /********************************************************************/ 
  54. /********************************************************************
  55. *  Function: int PASCAL WinMain(HINSTANCE, HINSTANCE, LPSTR, int)    *
  56. *                                                                    *
  57. *   Purpose: Initializes Application                                 *
  58. *                                                                    *
  59. *  Comments: Register window class, create and display the main      *
  60. *            window, and enter message loop.                         *
  61. *                                                                    *
  62. *                                                                    *
  63. ********************************************************************/
  64. int PASCAL WinMain( HINSTANCE hInstance,
  65.     HINSTANCE hPrevInstance,
  66.     LPSTR lpszCmdLine,
  67.     int nCmdShow )
  68. {
  69.    WNDCLASS wc;
  70.    MSG msg;
  71.    if( !hPrevInstance )
  72.    {
  73.       wc.lpszClassName = "GenericAppClass";
  74.       wc.lpfnWndProc = MainWndProc;
  75.       wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
  76.       wc.hInstance = hInstance;
  77.       wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
  78.       wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  79.       wc.hbrBackground = CreateSolidBrush (RGB(0, 64, 128));
  80.       wc.lpszMenuName = "GenericAppMenu";
  81.       wc.cbClsExtra = 0;
  82.       wc.cbWndExtra = 0;
  83.       RegisterClass( &wc );
  84.    }
  85.    ghInstance = hInstance;
  86.    hwndMain = CreateWindow( "GenericAppClass",
  87.       "Super Video",
  88.       WS_POPUP,
  89.       0,
  90.       0,
  91.       500,
  92.       500,
  93.       NULL,
  94.       NULL,
  95.       hInstance,
  96.       NULL
  97.    );
  98.    ShowWindow( hwndMain, nCmdShow );
  99.    
  100.    //Set the main window to the region
  101.    SetWindowRgn(hwndMain,hRegion1,1);
  102.    while( GetMessage( &msg, NULL, 0, 0 ) ) {
  103.       TranslateMessage( &msg );
  104.       DispatchMessage( &msg );
  105.    }
  106.    return msg.wParam;
  107. }
  108. /********************************************************************
  109. * Function: LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM) *
  110. *                                                                    *
  111. *  Purpose: Processes Application Messages                           *
  112. *                                                                    *
  113. * Comments: The following messages are processed                     *
  114. *                                                                    *
  115. *           WM_PAINT                                                 *
  116. *           WM_CREATE                                                *
  117. *           WM_DESTROY                                               *
  118. *                                                                    *
  119. *                                                                    *
  120. ********************************************************************/
  121. LRESULT CALLBACK MainWndProc( HWND hwndMain, UINT msg, WPARAM wParam,
  122.    LPARAM lParam )
  123. {
  124.    HDC hDC = GetDC(hwndMain);
  125.    RECT rc;    // client area             
  126.    POINT pt;   // location of mouse click    
  127.    switch( msg ) {
  128. /**************************************************************
  129. *     WM_LBUTTONDBLCLK:                                        *
  130. **************************************************************/
  131.   case WM_LBUTTONDBLCLK:
  132.        SetFocus(hwndMain);
  133.        break;
  134. /**************************************************************
  135. *     WM_LBUTTONDOWN:                                          *
  136. **************************************************************/
  137.       case WM_RBUTTONDOWN: 
  138.             // Get the bounding rectangle of the client area. 
  139.  
  140.             GetClientRect(hwndMain, (LPRECT) &rc); 
  141.  
  142.             // Get the client coordinates for the mouse click.  
  143.  
  144.             pt.x = LOWORD(lParam); 
  145.             pt.y = HIWORD(lParam); 
  146.  
  147.             // If the mouse click took place inside the client 
  148.             // area, execute the application-defined function 
  149.             // that displays the shortcut menu. 
  150.  
  151.             if (PtInRect((LPRECT) &rc, pt)) 
  152.                 HandlePopupMenu(hwndMain, pt); 
  153.             break; 
  154.             
  155. /**************************************************************
  156. *     WM_PAINT:                                                *
  157. **************************************************************/
  158.       case WM_PAINT:
  159.         //Give the region a red border
  160.          FrameRgn(hDC,hRegion1,CreateSolidBrush(RGB(0,0,0)),2,2); 
  161.          
  162.          // brung our dialog to the foreground
  163.  BringWindowToTop(hwndSelCapDrvDlg);
  164.          return( DefWindowProc( hwndMain, msg, wParam, lParam ));
  165. /**************************************************************
  166. *     WM_COMMAND:                                              *
  167. **************************************************************/
  168.   case WM_COMMAND:
  169.     CAPSTATUS CapStatus;
  170.   
  171.     switch( wParam ) {
  172.  
  173.   case SOURCE:
  174.         if(CapDrvCaps.fHasDlgVideoSource)
  175.          capDlgVideoSource(hwndVideo);
  176.         break;
  177.      case FORMAT://why doesnt this work
  178.         //if(CapDrvCaps.fHasDlgVideoFormat)
  179.         //{
  180.          capDlgVideoFormat(hwndMain);
  181.          // Are there new image dimensions
  182.          capGetStatus(hwndVideo, &CapStatus, sizeof(CAPSTATUS));
  183.          SetWindowPos(hwndVideo, NULL, 0, 0, CapStatus.uiImageWidth,
  184.          CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE);
  185.         //}
  186.         break;
  187.      case DISPLAY://why doesnt this work
  188.      //if (CapDrvCaps.fHasDlgVideoDisplay)
  189.      capDlgVideoDisplay(hwndVideo);
  190.      break;
  191.             case EXIT:
  192.                SendMessage(hwndMain, WM_SYSCOMMAND, SC_CLOSE, 0);
  193.                break;
  194.             case MINIMIZE:
  195.                SendMessage(hwndMain, WM_SYSCOMMAND, SC_MINIMIZE, 0);
  196.                break;
  197.             case HELP:
  198.                SendMessage(hwndMain, WM_SYSCOMMAND, SC_CONTEXTHELP, 0);
  199.                break;
  200.             case RECORDVIDEO:
  201.             if(HIWORD(wParam) == BN_CLICKED && (HWND) lParam == hwndRecord)
  202.             {
  203.    if (!isRecordFileOpen)
  204.    {
  205.     OPENFILENAME ofn; // open file name structure
  206.    
  207.     // initialize OPENFILENAME
  208.     ZeroMemory(&ofn, sizeof(OPENFILENAME));
  209. ofn.lStructSize = sizeof(OPENFILENAME);
  210. ofn.hwndOwner = hwndMain;
  211. ofn.lpstrFile = recordFile;
  212. ofn.nMaxFile = sizeof(recordFile);
  213. ofn.lpstrFilter = "Video*.avi";
  214. ofn.nFilterIndex = 1;
  215. ofn.lpstrFileTitle = NULL;
  216. ofn.nMaxFileTitle = 0;
  217. ofn.lpstrInitialDir = NULL;
  218. ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
  219. // Display the Save dialog box. 
  220. if(GetSaveFileName(&ofn) == TRUE)
  221. {
  222. strcpy(recordFile, ofn.lpstrFile);
  223. strcat(recordFile, ".avi");
  224. isRecordFileOpen = true; 
  225. // create the video capture thread
  226. DWORD id;
  227. SECURITY_ATTRIBUTES sa;
  228. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  229. sa.lpSecurityDescriptor = NULL;
  230. sa.bInheritHandle = TRUE;
  231. hVideoThread = CreateThread(&sa, (ULONG)0, 
  232. videoThreadProc, (LPVOID)(ULONG)0, (ULONG)0, &id);
  233. if(hVideoThread == NULL)
  234. MessageBox(NULL, "Creation of Record Thread failed!", "Thread", MB_OK | MB_ICONEXCLAMATION);
  235. break;
  236. }
  237. }
  238. if (isRecordFileOpen) // we already have a file selected
  239. {
  240. if(isRecording) // we're already recording
  241. {
  242. threadEnd = true;
  243. // end the capture and save it
  244. capFileSaveAs(hwndVideo, recordFile);
  245. // make the record button say "Record Video"
  246. SetWindowText(hwndRecord, "Record Video");
  247. isRecording = false;
  248. break;
  249. }
  250. if(!isRecording ) // we're not recording, but a file's selected
  251. {
  252. int a = 0;
  253. MessageBox(hwndMain, "Do you want to write over the open file?",
  254. "File warning", MB_YESNO | MB_ICONWARNING);
  255. if (a != IDYES)
  256. {
  257. isRecordFileOpen = false;
  258. SendMessage(hwndMain, WM_COMMAND, MAKEWPARAM(RECORDVIDEO, BN_CLICKED), (LPARAM) hwndRecord);
  259. }
  260. if (a == IDYES)
  261. {
  262. capCaptureSequence(hwndVideo);
  263. isRecording = true;
  264. }
  265. break;
  266. }
  267. }
  268. }
  269.           break;
  270.          }
  271.       break;
  272. /**************************************************************
  273. *     WM_CREATE:                                               *
  274. **************************************************************/
  275.       case WM_CREATE:
  276.       
  277.        RECT helpRect, minRect, exitRect;
  278.        HRGN helpRgn, minRgn, exitRgn;
  279.       
  280.         // make the main region
  281.         hRegion1 = CreateRoundRectRgn(0,0,500,400, 200, 200);   
  282.       
  283.         // create video capture window
  284.    hwndVideo = capCreateCaptureWindow(
  285.    (LPSTR) "My Capture Window",
  286.    WS_CHILD | WS_VISIBLE,
  287.    160, 120, 200, 148,
  288.    (HWND) hwndMain,
  289.    (int) 1);
  290.   
  291.   // Create the main window's buttons
  292.      
  293.    // create the close button
  294. hwndExit = CreateWindow (
  295. "button", // Builtin button class 
  296. "x", // button text
  297. WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, // styles
  298. 275, 10, BUTTONSIZE, BUTTONSIZE, // position and size
  299. hwndMain, // Parent is main window
  300. (HMENU) EXIT,// Control ID: EXIT
  301. (HINSTANCE)ghInstance,
  302. (LPVOID)NULL);
  303.     
  304.    // create the minimize button
  305. hwndMin = CreateWindow (
  306. "button", // Builtin button class 
  307. "-", // button text
  308. WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, // styles
  309. 250, 10, BUTTONSIZE, BUTTONSIZE, // position and size
  310. hwndMain, // Parent is main window
  311. (HMENU) MINIMIZE,// Control ID: MINIMIZE
  312. (HINSTANCE)ghInstance,
  313. (LPVOID)NULL);  
  314.    // create the help button
  315. hwndHelp = CreateWindow (
  316. "button", // Builtin button class 
  317. "?", // button text
  318. WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, // styles
  319. 225, 10, BUTTONSIZE, BUTTONSIZE, // position and size
  320. hwndMain, // Parent is main window
  321. (HMENU) HELP,// Control ID: HELP
  322. (HINSTANCE)ghInstance,
  323. (LPVOID)NULL);
  324.    // create the record video button
  325. hwndRecord = CreateWindow (
  326. "button", // Builtin button class 
  327. "Record Video", // button text
  328. WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, // styles
  329. 200, 280, 90, 28, // position and size
  330. hwndMain, // Parent is main window
  331. (HMENU) RECORDVIDEO,// Control ID: RECORDVIDEO
  332. (HINSTANCE)ghInstance,
  333. (LPVOID)NULL);
  334.    // get the button rectangles
  335.    GetClientRect(hwndHelp, &helpRect);
  336.    GetClientRect(hwndMin, &minRect);
  337.    GetClientRect(hwndExit, &exitRect);
  338.         
  339.    // create the button regions
  340.    helpRgn = CreateEllipticRgnIndirect(&helpRect);
  341. minRgn = CreateEllipticRgnIndirect(&minRect);
  342. exitRgn = CreateEllipticRgnIndirect(&exitRect);
  343.      
  344.         //Set the window to the region
  345.     SetWindowRgn(hwndExit,exitRgn,1);
  346.     SetWindowRgn(hwndMin,minRgn,1);      
  347.     SetWindowRgn(hwndHelp,helpRgn,1);
  348.    // create the SelCapDrv dialog
  349. hwndSelCapDrvDlg = CreateDialog((HINSTANCE)ghInstance, 
  350. MAKEINTRESOURCE( SELCAPDRVDLG  ), 
  351. 0, (DLGPROC)SelCapDrvProc);
  352. // get the handle to the list box
  353. hwndSelCapDrvDlg_LBox = GetDlgItem(hwndSelCapDrvDlg, 
  354.        SELCAPDRVDLG_LSTBOX);
  355.     EnumCapDrv();
  356.       break;
  357. /****************************************************************
  358. *WM_DESTROY: PostQuitMessage() is called and get rid of vfw stuff*
  359. ****************************************************************/
  360.       case WM_DESTROY:
  361.         capPreview(hwndVideo, FALSE); // end preview
  362.         capDriverDisconnect(hwndVideo); // disconnect from driver
  363.          PostQuitMessage( 0 );
  364.          break;
  365. /**************************************************************
  366. *     Let the default window proc handle all other messages    *
  367. **************************************************************/
  368.       default:
  369.          return( DefWindowProc( hwndMain, msg, wParam, lParam ));
  370.    }
  371.    return 0;
  372. }
  373. LRESULT CALLBACK SelCapDrvProc( HWND hWnd, UINT msg, /*callback procedure */
  374. WPARAM wParam, LPARAM lParam )
  375. {
  376. switch(msg)
  377. {
  378. // dialog created
  379. case WM_INITDIALOG:
  380.     return TRUE;
  381. // command    
  382. case WM_COMMAND:
  383. switch ( wParam )
  384. {
  385. // user clicked the select driver button
  386. case SELCAPDRVDLG_BUTTON:
  387. int sel = 0;
  388. // get the selected driver
  389. SendMessage( hwndSelCapDrvDlg_LBox, LB_GETSELITEMS, 1, sel);
  390. // connect to the driver
  391. SendMessage( hwndVideo, WM_CAP_DRIVER_CONNECT, sel, 0L); 
  392. // then close this dialog
  393. SendMessage( hwndSelCapDrvDlg, WM_CLOSE, 0, 0);
  394. // update the driver capabilities
  395. SendMessage( hwndVideo, WM_CAP_DRIVER_GET_CAPS,
  396.  sizeof(CAPDRIVERCAPS), (LONG) (LPVOID) &CapDrvCaps);
  397. // set preview rate to 66 miliseconds
  398. capPreviewRate( hwndVideo, 66 );
  399. // start preview video
  400. capPreview( hwndVideo, TRUE );
  401. }
  402. return TRUE;
  403. // user wants to close dialog
  404. case WM_CLOSE:
  405. DestroyWindow(hwndSelCapDrvDlg);
  406. return TRUE;
  407. }
  408. return( 0L );
  409. }
  410. int EnumCapDrv() // enumerate the installed capture drivers
  411. {
  412. char szDeviceName[80]; // driver name
  413. char szDeviceVersion[80]; // driver version
  414. char item[161]; // concatinated string
  415. int i; // counter
  416. for (i=0; i<10; i++)
  417. {
  418. if ( capGetDriverDescription(i, szDeviceName, sizeof(szDeviceName),
  419. szDeviceVersion, sizeof(szDeviceVersion)) )
  420. {
  421. strcpy(item, szDeviceName);
  422. strcat(item, " ");
  423. strcat(item, szDeviceVersion);
  424. // add item to list box
  425. SendMessage(hwndSelCapDrvDlg_LBox, LB_ADDSTRING, 0, 
  426.                 (LPARAM) item);
  427.              SendMessage(hwndSelCapDrvDlg_LBox, LB_SETITEMDATA, i, (LPARAM) i);
  428.         }
  429.     }
  430.     
  431.     return 0;
  432. }
  433. /*int CreateWndButtons()
  434. {//why doesnt this work
  435. RECT rc; // window rectangle
  436. GetClientRect(hwndMain, &rc);
  437. // create the button
  438. hwndExit = CreateWindow (
  439. "button", // Builtin button class 
  440. "X", // button text
  441. WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, // styles
  442. 100, 100, BUTTONSIZE, BUTTONSIZE, // position and size
  443. hwndMain, // Parent is main window
  444. (HMENU) EXIT,// Control ID: EXIT
  445. (HINSTANCE)ghInstance,
  446. (LPVOID)NULL);
  447. return 0;
  448. }
  449. */
  450. VOID APIENTRY HandlePopupMenu(HWND hwnd, POINT pt) 
  451.     HMENU hmenu;            // menu template          
  452.     HMENU hmenuTrackPopup;  // shortcut menu   
  453.  
  454.     //  Load the menu template containing the shortcut menu from the 
  455.     // application's resources. 
  456.  
  457.     hmenu = LoadMenu((HINSTANCE)ghInstance, "PopupMenu"); 
  458.     if (hmenu == NULL) 
  459.         return; 
  460.  
  461.     // Get the first shortcut menu in the menu template. This is the 
  462.     // menu that TrackPopupMenu displays. 
  463.  
  464.     hmenuTrackPopup = GetSubMenu(hmenu, 0); 
  465.  
  466.     // TrackPopup uses screen coordinates, so convert the 
  467.     // coordinates of the mouse click to screen coordinates. 
  468.  
  469.     ClientToScreen(hwnd, (LPPOINT) &pt); 
  470.  
  471.     // Draw and track the shortcut menu.  
  472.  
  473.     TrackPopupMenu(hmenuTrackPopup, TPM_LEFTALIGN | TPM_LEFTBUTTON, 
  474.         pt.x, pt.y, 0, hwnd, NULL); 
  475.  
  476.     // Destroy the menu. 
  477.  
  478.     DestroyMenu(hmenu); 
  479. }
  480. DWORD WINAPI videoThreadProc(LPVOID lParam)
  481. {
  482. // make the record button say "Stop Recording"
  483. SetWindowText(hwndRecord, "Stop Recording");
  484. // capture the video
  485. capCaptureSequence(hwndVideo);
  486. isRecording = true;
  487. // don't exit the thread until the record button is pressed again
  488. while (!threadEnd)
  489. ;
  490. MessageBox(NULL, "Leaving Thread", "thread", NULL);
  491. return 0;
  492. }