首页 > 代码库 > win32 摄像头捕获系统vfw

win32 摄像头捕获系统vfw

[html] view plaincopy
 
  1. //win32 摄像头捕获系统vfw  
[html] view plaincopy
 
  1. //  VideoRecord.h  
  2. ///  用于定义一些资源ID  
[html] view plaincopy
 
  1. #include "resource.h"  
  2.   
  3. //#define EXIT  104  
  4. #define HELP  105  
  5. #define MINIMIZE 106  
  6. //#define DISPLAY  107  
  7. #define BUTTONSIZE  15  
  8. #define PHOTO   108  
  9. #define RECORDVIDEO 109  
  10. // #define RESOURCE 110  
  11. // #define FORMAT   111  
  12. #define CONNECT 112  
  13.    
[html] view plaincopy
 
  1.   
[html] view plaincopy
 
  1.   
[html] view plaincopy
 
  1.   

 

[cpp] view plaincopy
 
  1. #include <Windows.h>  
  2. #include <STRING>  
  3. #include <vfw.h>  
  4. #include "VideoRecord.h"  
  5.   
  6. #pragma comment(lib, "vfw32.lib")  
  7.   
  8. LRESULT WINAPI MainWndProc( HWNDUINTWPARAMLPARAM );  
  9. LRESULT WINAPI SelCapDrcProc( HWNDUINTWPARAMLPARAM );  
  10. int EnumCapDrv();  
  11. VOID APIENTRY HandlePopupMenu(HWND, POINT);  // 右键弹出菜单回调函数  
  12. WORD WINAPI VideoThreadProc( LPVOID lParam); // 视频捕捉线程函数  
  13.   
  14. ////////////////全局变量  
  15.   
  16. HANDLE ghInstance;  // 应用程序实例  
  17. HWND hwndMain;  // 主窗口句柄  
  18. HWND hwndVideo;  // 视频捕捉窗口句柄  
  19. HWND hwndSelCapDrvDlg; // 选择捕捉驱动对话框句柄  
  20. HWND hwndSelCapDrvLBox; // 选择驱动对话框列举驱动名称列表框句柄  
  21. HWND hwndExit;  
  22. HWND hwndMin;  
  23. HWND hwndHelp;  
  24. HWND hwndPhoto;  
  25. HWND hwndRecord;  
  26. HWND hwndBtnExit;  
  27. HWND hwndSource;  
  28. HWND hwndFormat;  
  29. HWND hwndConnect;  
  30. HANDLE hVideoTread; // 视频采集线程  
  31. HRGN hRoundRgn; // 窗口修正区域  
  32. CAPDRIVERCAPS capDrvCaps; // 驱动性能  
  33. bool bRecordFileOpen = false;  // 录像开始标志  
  34. bool bPhotoFileOpen = false;  // 照相开始标志  
  35. bool bRecording = false;  // 判断是否正在录像  
  36. bool bThreadEnd = false// 判断视频线程是否终止  
  37. char recordFile[260]; //保持录像标志  
  38. char photoFile[260]; // 保持照相标志  
  39. char gachBuffer[260]; // 保存错误信息  
  40.   
  41. //////////////////////////////////////////////////////////////////////////////  
  42. // ErrorCallbackProc:    错误回调函数,过capSetCallbackOnError宏来注册回调   
  43. // hWnd:              捕获窗口句柄   
  44. // nErrID:              错误代码   
  45. // lpErrorText:          关于错误的文本信息   
  46. ///////////////////////////////////////////////////////////////////////////////   
  47. LRESULT CALLBACK ErrorCallbackProc(HWND hWnd,int nErrID,LPSTR lpErrorText)  
  48. {  
  49.     if(!hwndMain)  
  50.         return FALSE;  
  51.     if(nErrID==0)  
  52.         return TRUE;//清除旧的错误  
  53.     wsprintf(gachBuffer,"Error# %d",nErrID);//显示错误标识和文本  
  54.     MessageBox(hWnd, lpErrorText, gachBuffer,MB_OK | MB_ICONEXCLAMATION);   
  55.     return (LRESULT) TRUE;  
  56. }  
  57.   
  58. /////////////////////////////////////  
  59. int PASCAL WinMain( IN HINSTANCE hInstance,   
  60.                    IN HINSTANCE hPrevInstance,   
  61.                    IN LPSTR lpCmdLine,   
  62.                    IN int nShowCmd )  
  63. {  
  64.     WNDCLASS wndClass;  
  65.     MSG msg;  
  66.     char className[] = "VideoClass";  
  67.     // 如果不是前实例  
  68.     if (!hPrevInstance)  
  69.     {  
  70.         wndClass.lpszClassName = className;  
  71.         wndClass.lpfnWndProc = MainWndProc;  
  72.         wndClass.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;  
  73.         wndClass.hInstance = hInstance;  
  74.         wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);  
  75.         wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);  
  76.         wndClass.hbrBackground = CreateSolidBrush( RGB(200,200,100) );  
  77.         wndClass.lpszMenuName = NULL;  
  78.         wndClass.cbClsExtra = 0;  
  79.         wndClass.cbWndExtra = 0;  
  80.         RegisterClass( &wndClass );  
  81.     }  
  82.     ghInstance = hInstance;  
  83.     // 创建主窗口  
  84.     hwndMain = CreateWindow(className,  
  85.         "视频监控系统",  
  86.         WS_POPUP|WS_OVERLAPPED,  
  87.         GetSystemMetrics(SM_CXFULLSCREEN)/2 - 600/2,  
  88.         GetSystemMetrics(SM_CYFULLSCREEN)/2-600/2,  
  89.         600, 600,  
  90.         NULL,  
  91.         NULL,  
  92.         hInstance,  
  93.         NULL);  
  94.   
  95.     ShowWindow(hwndMain, nShowCmd);  
  96.   
  97.     // 设定主窗口主要区域  
  98.     SetWindowRgn(hwndMain, hRoundRgn, 1);  
  99.       
  100.     while( GetMessage(&msg, NULL, 0, 0))  
  101.     {  
  102.         TranslateMessage(&msg);//该函数将虚拟键消息转换为字符消息。  
  103.         //字符消息被寄送到调用线程的消息队列里,当下一次线程调用函数GetMessage或PeekMessage时被读出  
  104.         DispatchMessage(&msg);//该函数调度一个消息给窗口程序。  
  105.         //通常调度从GetMessage取得的消息。消息被调度到的窗口程序即是MainProc()函数  
  106.     }  
  107.     return msg.wParam;  
  108. }  
  109.   
  110. LRESULT CALLBACK MainWndProc( HWND hMain, UINT msg, WPARAM wParam, LPARAM lParam )  
  111. {  
  112.     HDC hdc = GetDC(hMain);  
  113.     RECT rc;   // 客户区  
  114.     POINT pt;  // 鼠标位置  
  115.     HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);  
  116.     switch(msg)  
  117.     {  
  118.     case WM_LBUTTONDBLCLK:  
  119.         SetFocus(hMain);  
  120.         break;  
  121.     case WM_RBUTTONDOWN:  
  122.         GetClientRect(hMain, (LPRECT)&rc);  
  123.         pt.y = HIWORD(lParam);  
  124.         pt.x = LOWORD(lParam);  
  125.         if ( PtInRect(&rc, pt) )  
  126.         {  
  127.             HandlePopupMenu(hMain, pt);  
  128.         }  
  129.         break;  
  130.     case WM_PAINT:  
  131.         RECT helpRect, minRect, exitRect;  
  132.         HRGN helpRgn, minRgn, exitRgn;  
  133.         FrameRgn(hdc, hRoundRgn, CreateSolidBrush(RGB(0,0,0)), 2, 2);  
  134.         BringWindowToTop(hwndSelCapDrvDlg);  
  135.         return DefWindowProc(hMain, msg, wParam, lParam);  
  136.     case WM_CREATE:  
  137.         // 注册错误提示回调函数  
  138.         capSetCallbackOnError(hwndVideo, (FARPROC)ErrorCallbackProc);  
  139.         // 主窗口主要圆角矩形区域  
  140.         hRoundRgn = CreateRoundRectRgn(100, 70, 500, 460, 20, 20);  
  141.         // 捕捉视频区域s  
  142.         hwndVideo = capCreateCaptureWindow((LPSTR)"My Capture Window",  
  143.             WS_CHILD|WS_VISIBLE,  
  144.             140, 100, 320, 280,  
  145.             (HWND)hMain,  
  146.             (int)1);  
  147.         hwndExit = CreateWindow("button",    // 建立一个按钮,更多如BUTTON,COMBOBOX,LISTBOX  
  148.             "x",    // button text  
  149.             WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_CENTER|BS_VCENTER,  
  150.             470, 75, BUTTONSIZE, BUTTONSIZE,  
  151.             hMain,  
  152.             (HMENU)EXIT,  
  153.             (HINSTANCE)ghInstance,  
  154.             (LPVOID)NULL );  
  155.         hwndMin = CreateWindow("button",    // 建立一个按钮,更多如BUTTON,COMBOBOX,LISTBOX  
  156.             "-",    // button text  
  157.             WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_CENTER|BS_VCENTER,  
  158.             450, 75, BUTTONSIZE, BUTTONSIZE,  
  159.             hMain,  
  160.             (HMENU)MINIMIZE,  
  161.             (HINSTANCE)ghInstance,  
  162.             (LPVOID)NULL );  
  163.         hwndHelp = CreateWindow("button",    // 建立一个按钮,更多如BUTTON,COMBOBOX,LISTBOX  
  164.             "?",    // button text  
  165.             WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON/*|BS_CENTER|BS_VCENTER*/,  
  166.             430, 75, BUTTONSIZE, BUTTONSIZE,  
  167.             hMain,  
  168.             (HMENU)HELP,  
  169.             (HINSTANCE)ghInstance,  
  170.             (LPVOID)NULL );  
  171.         hwndPhoto = CreateWindow("button",  
  172.             "照 相",  
  173.             WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,  
  174.             150, 410, 50, 20,  
  175.             hMain,  
  176.             (HMENU)PHOTO,  
  177.             (HINSTANCE)ghInstance,  
  178.             (LPVOID)NULL );  
  179.         SendMessage(hwndPhoto, WM_SETFONT, (WPARAM)hFont, 1);  // 设置按钮字体为系统默认字体  
  180.         hwndRecord = CreateWindow("button",  
  181.             "录 像",  
  182.             WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_VCENTER|BS_CENTER,  
  183.             220, 410, 50, 20,  
  184.             hMain,  
  185.             (HMENU)RECORDVIDEO,  
  186.             (HINSTANCE)ghInstance,  
  187.             (LPVOID)NULL );  
  188.         SendMessage(hwndRecord, WM_SETFONT, (WPARAM)hFont, 1);// 设置按钮字体为系统默认字体  
  189.         hwndBtnExit = CreateWindow("button",   // 退出按钮  
  190.             "退 出",  
  191.             WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_VCENTER|BS_CENTER,  
  192.             400, 410, 50, 20,  
  193.             hMain,  
  194.             (HMENU)EXIT,  
  195.             (HINSTANCE)ghInstance,  
  196.             (LPVOID)NULL );  
  197.         SendMessage(hwndBtnExit, WM_SETFONT, (WPARAM)hFont, 1);  
  198.         // 设置按钮区域  
  199.         GetClientRect(hwndHelp, &helpRect);  
  200.         GetClientRect(hwndMin, &minRect);  
  201.         GetClientRect(hwndExit, &exitRect);  
  202.           
  203.         helpRgn = CreateEllipticRgnIndirect(&helpRect);  
  204.         minRgn = CreateEllipticRgnIndirect(&minRect);  
  205.         exitRgn = CreateEllipticRgnIndirect(&exitRect);  
  206.           
  207.         SetWindowRgn(hwndExit,exitRgn,1);  
  208.         SetWindowRgn(hwndMin,minRgn,1);                               
  209.         SetWindowRgn(hwndHelp,helpRgn,1);  
  210.   
  211.         // 创建选择驱动对话框  
  212.         hwndSelCapDrvDlg = CreateDialog((HINSTANCE)ghInstance,  
  213.             MAKEINTRESOURCE(DLG_SELCAPDRIVER),  
  214.             0, (DLGPROC)SelCapDrcProc);  
  215.         hwndSelCapDrvLBox = GetDlgItem(hwndSelCapDrvDlg, LISTBOX_SELCAPDRIVER);  
  216.           
  217.         EnumCapDrv();  
  218.         break;  
  219.     case WM_COMMAND:  
  220.         CAPSTATUS capStatus;  
  221.         switch(wParam)  
  222.         {  
  223.         case EXIT:  // 退出系统  
  224.             SendMessage(hMain, WM_SYSCOMMAND, SC_CLOSE, 0);  
  225.             break;  
  226.         case MINIMIZE: // 最小化  
  227.             SendMessage(hMain, WM_SYSCOMMAND, SC_MINIMIZE, 0);  
  228.             break;  
  229.         case HELP:  // 帮助按钮  
  230.             SendMessage(hMain, WM_SYSCOMMAND, SC_CONTEXTHELP, 0);  
  231.             break;  
  232.         case RESOURCE: // 视频源选项  
  233.             if (capDrvCaps.fHasDlgVideoSource)  
  234.             {  
  235.                 capDlgVideoSource(hwndVideo);  
  236.             }  
  237.             break;  
  238.         case FORMAT:  // 视频格式选项  
  239.             if (capDrvCaps.fHasDlgVideoFormat)  
  240.             {  
  241.                 capDlgVideoFormat(hwndVideo);  
  242.             }  
  243.             break;  
  244.         case CONNECT:  
  245.             break;  
  246.         case DISPLAY: // 视频显示选项  
  247.             if (capDrvCaps.fHasDlgVideoDisplay)  
  248.             {  
  249.                 capDlgVideoDisplay(hMain);  
  250.                 capGetStatus(hwndVideo, &capStatus, sizeof(CAPSTATUS));// 得到当前捕获窗口的状态  
  251.                 SetWindowPos(hwndVideo, NULL, 0, 0, capStatus.uiImageWidth, capStatus.uiImageHeight, SWP_NOZORDER|SWP_NOMOVE);  
  252.             }  
  253.             break;  
  254.         case PHOTO:  // 抓取图片  
  255.             if ( capFileSaveDIB(hwndVideo, "test.bmp") ){  
  256.                 MessageBox(hMain, "Save Bmp File Succeeded!""photo save", MB_OK|MB_ICONINFORMATION);  
  257.             }  
  258.             else break;  
  259.             if (!bPhotoFileOpen)  
  260.             {  
  261.                 OPENFILENAME ofnp;  // open file name structure  
  262.                 ZeroMemory(&ofnp, sizeof(OPENFILENAME));  
  263.                 ofnp.lStructSize = sizeof(OPENFILENAME);  
  264.                 ofnp.hwndOwner = hMain;  
  265.                 ofnp.lpstrFile = photoFile;  
  266.                 ofnp.lpstrFilter = "*.bmp";  
  267.                 ofnp.nMaxFile = sizeof(photoFile);  
  268.                 ofnp.nFilterIndex = 1;  
  269.                 ofnp.nMaxFileTitle = 0;  
  270.                 ofnp.lpstrInitialDir = NULL;  
  271.                 ofnp.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST;  
  272.                 // 显示保存文件对话框  
  273.                 if (GetSaveFileName(&ofnp) == TRUE)  
  274.                 {  
  275.                     bPhotoFileOpen = TRUE;  
  276.                     strcpy(photoFile, ofnp.lpstrFile);  
  277.                     strcat(photoFile, ".bmp");  
  278.                     capDriverConnect(hwndPhoto, 0);  // 与驱动连接  
  279.                     capOverlay(hwndPhoto, TRUE); // //使用 hardware overlay   
  280.                     //使 video input directlyinto framebuffer,使不用 CPU  
  281.                     capPreview(hwndVideo, TRUE);  // 抓取图像显示在视窗  
  282.                     capPreviewScale(hwndVideo, TRUE); // 使图像延伸到所设定的视窗大小  
  283.                     capPreviewRate(hwndVideo, 1000/30); // 每秒图像变化张数  
  284.                     capPreview(hwndVideo, TRUE); // 预览图像显示  
  285.                     capGrabFrameNoStop(hwndVideo);  
  286.                     capEditCopy(hwndVideo);  
  287.                     if (capFileSaveDIB(hwndVideo, photoFile)){  
  288.                         MessageBox(hMain, "Save Bmp File Succeeded!""photo save", MB_OK|MB_ICONINFORMATION);  
  289.                     }  
  290.                     break;  
  291.                 }  
  292.             }  
  293.             break;  
  294.         case RECORDVIDEO:  // 录制视频  
  295.             if (HIWORD(wParam) == BN_CLICKED && (HWND)lParam == hwndRecord)  
  296.             {  
  297.                 OPENFILENAME ofnp;  
  298.                 if (!bRecordFileOpen)  
  299.                 {  
  300.                     ZeroMemory(&ofnp, sizeof(OPENFILENAME));  
  301.                     ofnp.lStructSize = sizeof(OPENFILENAME);  
  302.                     ofnp.nMaxFile = sizeof(recordFile);  
  303.                     ofnp.hwndOwner = hMain;  
  304.                     ofnp.lpstrFile = recordFile;  
  305.                     ofnp.lpstrFilter = "*.avi";  
  306.                     ofnp.lpstrInitialDir = NULL;  
  307.                     ofnp.nFilterIndex = 1;  
  308.                     ofnp.lpstrFileTitle = NULL;  
  309.                     ofnp.nMaxFileTitle = 0;  
  310.                     ofnp.Flags = OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;  
  311.                     // 显示保存文件对话框  
  312.                     if (GetSaveFileName(&ofnp) == TRUE)  
  313.                     {  
  314.                         strcpy(recordFile, ofnp.lpstrFile);  
  315.                         strcat(recordFile, ".avi");  
  316.                         bRecordFileOpen = TRUE;  
  317.                         // 创建视频采集线程  
  318.                         DWORD id;  
  319.                         SECURITY_ATTRIBUTES sa;  
  320.                         sa.nLength = sizeof(SECURITY_ATTRIBUTES);  
  321.                         sa.lpSecurityDescriptor = NULL;  
  322.                         sa.bInheritHandle = TRUE;  
  323.                         hVideoTread = CreateThread(&sa,  
  324.                             (ULONG)0,  
  325.                             (LPTHREAD_START_ROUTINE)VideoThreadProc,  
  326.                             (LPVOID)(ULONG)0,  
  327.                             0,  
  328.                             &id);  
  329.                         // 如果创建线程失败,弹出提示对话框  
  330.                         if (hVideoTread == NULL)  
  331.                         {  
  332.                             MessageBox(NULL, "Video Thread Create Failure!""Thread", MB_OK|MB_ICONINFORMATION);     
  333.                         }  
  334.                     }  
  335.                     break;  
  336.                 }  
  337.                 if (bRecordFileOpen)  // 已经打开一个选择对话框  
  338.                 {  
  339.                     if (bRecording)  // 已经在录制视频中  
  340.                     {  
  341.                         bThreadEnd = true;  
  342.                         // 结束录制,并保存  
  343.                         if ( capFileSaveAs(hwndVideo, recordFile) ){  
  344.                             MessageBox(NULL, "Save Avi File Succeeded!""RecordVideo", MB_OK|MB_ICONINFORMATION);  
  345.                         }  
  346.                         SetWindowText(hwndRecord, "录 像");  
  347.                         bRecording = false;  
  348.                         break;  
  349.                     }  
  350.                     else  // 没有录像但是选择了一个文件  
  351.                     {  
  352.                         int rt = 0;  
  353.                         rt = MessageBox(hMain, "Do you want write over that file?""系统提示", MB_YESNO|MB_ICONINFORMATION);  
  354.                         if (rt == IDYES)  // 继续录制,覆盖当前文件  
  355.                         {     
  356.                             if (capCaptureSequence(hwndRecord))  
  357.                             {  
  358.                                 bRecording = true;  
  359.                                 SetWindowText(hwndRecord, "停 止");  
  360.                             }     
  361.                         }  
  362.                         else  
  363.                         {  
  364.                             bRecordFileOpen = false;  
  365.                             SendMessage(hMain, WM_COMMAND, MAKEWPARAM(RECORDVIDEO, BN_CLICKED), (LPARAM)hwndRecord);  
  366.                         }  
  367.                         break;  
  368.                     }  
  369.                     break;  
  370.                 }     
  371.             }  
  372.         }  
  373.         break;  
  374.     case WM_DESTROY:  
  375.         capSetCallbackOnError(hwndVideo, NULL);  
  376.         capPreview(hwndVideo, FALSE); // 停止预览  
  377.         capCaptureAbort(hwndVideo);  // 停止捕获  
  378.         capDriverDisconnect(hwndVideo); // 断开驱动连接  
  379.         PostQuitMessage(0);  
  380.         break;  
  381.     default:  
  382.         return DefWindowProc(hMain, msg, wParam, lParam);  
  383.     }  
  384.     return 0;  
  385. }  
  386.   
  387. LRESULT WINAPI SelCapDrcProc( HWND hMian, UINT msg, WPARAM wParam, LPARAM lParam )  
  388. {  
  389. //  ShowWindow(hwndSelCapDrvDlg, SW_SHOW);  
  390.     switch(msg)  
  391.     {  
  392.     case WM_INITDIALOG:  
  393.         return TRUE;  
  394.     case WM_COMMAND:  
  395.         switch(wParam)  
  396.         {  
  397.         case BTN_SEL:  
  398.             int sel = 0;  
  399.             SendMessage(hwndSelCapDrvLBox, LB_GETSELITEMS, 1, sel );  // 获取选择的驱动  
  400.             SendMessage(hwndVideo, WM_CAP_DRIVER_CONNECT, sel, 0L);   // 连接驱动  
  401.             SendMessage(hwndSelCapDrvDlg, WM_CLOSE, 0, 0);   // 关闭对话框  
  402.             SendMessage(hwndVideo, WM_CAP_DRIVER_GET_CAPS, sizeof(CAPDRIVERCAPS), (long)(LPVOID)&capDrvCaps); // 更新驱动的能力  
  403.             if (capDrvCaps.fHasOverlay)  
  404.             {  
  405.                 capOverlay(hwndVideo, TRUE);  
  406.             }  
  407.             capPreviewRate(hwndVideo, 66);   //设置视频捕获速率提高到66 miliseconds  
  408.             if ( !capPreview(hwndVideo, TRUE))   //用CapPreview启动预览功能  
  409.             {  
  410.                 MessageBox(NULL, "预览启动失败""提示", MB_OK|MB_ICONINFORMATION);  
  411.                 SendMessage(hMian, WM_COMMAND, EXIT, 0);  
  412.                 return FALSE;  
  413.   
  414.             }  
  415.         }  
  416.         return TRUE;  
  417.     case WM_CLOSE:  
  418.         DestroyWindow(hwndSelCapDrvDlg);  
  419.         return TRUE;  
  420.     }  
  421.     return (0L);  
  422. }  
  423.   
  424. int EnumCapDrv()  
  425. {  
  426.     char drvName[100];  
  427.     char drvVesion[100];  
  428.     char drvStr[200];  
  429.     for (int i = 0; i < 5; i++)  // 扫面获取驱动信息  
  430.     {  
  431.         if ( capGetDriverDescription(i, drvName, sizeof(drvName), drvVesion, sizeof(drvVesion)) )  
  432.         {  
  433.             strcpy(drvStr, drvName);  
  434.             strcat(drvStr, "  ");  
  435.             strcat(drvStr, drvVesion);  
  436.             SendMessage(hwndSelCapDrvLBox, LB_ADDSTRING, 0, (LPARAM)drvStr); // 向列表框增加字符串  
  437.             SendMessage(hwndSelCapDrvLBox, LB_SETITEMDATA, i, (LPARAM)i);  
  438.         }  
  439.     }  
  440.     return 0;  
  441. }  
  442.   
  443. VOID APIENTRY HandlePopupMenu( HWND hwnd, POINT pt )  
  444. {  
  445.     HMENU hmenu;  
  446.     HMENU hPopupMenu;  
  447.     hmenu = LoadMenu((HINSTANCE)ghInstance, MAKEINTRESOURCE(IDR_POPUPMENU));  
  448.     if(hmenu == NULL) return;  
  449.     // 获取子菜单  
  450.     hPopupMenu = GetSubMenu(hmenu, 0);  
  451.     // 弹出菜单使用屏幕坐标,所以转换鼠标点击坐标到屏幕坐标  
  452.     ClientToScreen(hwnd, &pt);  
  453.     TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, hwnd, NULL);  
  454.     DestroyMenu(hmenu); // 销毁指定菜单,并释放此菜单占用的内存  
  455. }  
  456.   
  457. WORD WINAPI VideoThreadProc( LPVOID lParam )  
  458. {  
  459.     // 捕获视频  
  460.     if( capCaptureSequence(hwndVideo) ) //该函数调控启动流视频和音频捕获到一个文件,你能使用这个功能发送消息  
  461.     {  
  462.         SetWindowText(hwndRecord, "停 止");  
  463.         MessageBox(NULL, "Start to capture video.""提示", MB_OK|MB_ICONINFORMATION);  
  464.         bRecording = true;  
  465.     }  
  466.     while(!bThreadEnd);  
  467.     MessageBox(NULL, "Leaving Record Thread""Thread",NULL);  
  468.     return 0;  
  469. }