VFW基础细节

VFW基础细节


一. 视频捕获快速入门 


视频捕捉将一个视频流和音频流数字化, 然后存储在硬盘或其他存储介质上. 


一个AVICap视窗口句柄描述了声频与视频流的细节, 这样就使你的应用程序从AVI文件格式, 声频视频缓冲管理, 低层声频视频驱动访问等等解脱出来, AVICap为应用程序提供了一个灵活的介面, 你可以仅仅使用如下几行代码就可以将视频捕捉加入你的程序: 


hWndC = capCreateCaptureWindow ( "My Own Capture Window", 


WS_CHILD | WS_VISIBLE , 0, 0, 160, 120, hwndParent, nID); 


 


SendMessage (hWndC, WM_CAP_DRIVER_CONNECT, 0 /* wIndex */, 0L); 


SendMessage (hWndC, WM_CAP_SEQUENCE, 0, 0L); 


 


一个宏其实也是使用SendMessage, 只不过提供给程序一个更易读的代码而已, 下面的这些示例就是使用宏的方法将视频捕捉加入程序: 


hWndC = capCreateCaptureWindow ( "My Own Capture Window", 


WS_CHILD | WS_VISIBLE , 0, 0, 160, 120, hwndParent, nID); 


capDriverConnect (hWndC, 0); 


capCaptureSequence (hWndC); 




当你创建了一个AVICap类的捕捉窗口并将它连接到一个视频驱动时, 此捕捉窗口即可以开始捕捉数据, 你的程序可以简单的发送WM_CAP_SEQUENCE消息(或者使用capCaptureSequence宏)来开始捕捉. 


如果是缺省的设置, WM_CAP_SEQUENCE会开始捕捉视频音频流到CAPTURE.AVI文件中, 直到下面的某一事件发生为止: 


用户按下了ESC键或者一个鼠标键 


你的应用程序终止或异常中断捕捉操作 


磁盘已满 




在一个应用程序里, 你可以发送WM_CAP_STOP消息来终止捕捉数据(或者使用capCaptureStop宏), 你也可以发送WM_CAP_ABORT消息(或者使用capCaptureAbort宏)来终止. 




二.基本的捕获设置 


基 本的捕获设置包括:设置捕获速度(每秒捕获多少帧),是否同时捕获声频,捕获缓冲,允许最大丢失多少帧,是否使用DOS内存,以及用键盘的哪个键或鼠标的哪个键来终止捕获等等。这些基本的设置都可以使用CAPTUREPARAMS结构来描述,你可以使用capCaptureGetSetup宏来得到当前的设置,然后改变此结构的成员变量,再使用capCaptureSetSetup宏设置新的设置。 


例如: 


1.设置捕获速度: 


捕 捉速度是指捕捉任务每秒钟捕获的帧数, 你可以发送WM_CAP_GET_SEQUENCE_SETUP消息(或者使用capCaptureGetSetup宏)来得到当前的捕捉速度, 当前的捕捉速度保存在CAPTUREPARAMS结构的dwRequestMicroSecPerFrame成员变量中, 你可以通过设置此变量来改变当前设置, 单位是每毫秒连续的帧数, 你可以发送WM_CAP_SET_SEQUENCE_SETUP消息(或者使用capCaptureSetSetup宏), dwRequestMicroSecPerFrame的值是66667, 相当于每秒15帧. 




2.设置终止捕获 


你可以允许用户按下某键或某组合键或者鼠标的左右键来终止一个捕获任务, 如果是实时的捕获, 则捕获的文件将会被丢弃; 如果是单步捕获, 在终止之前所捕获的内容将会被保存. 


你 可以通过发送WM_CAP_GETQUENCE_SETUP消息(或者使用capCaptureGetSetup宏)来得到当前的设置, 当前的按键设置保存在CAPTUREPARAMS的vKeyAbort成员中, 当前的鼠标设置保存在fAbortLeftMouse和fAbortRightMouse成员中. 你可以设置新的按键或按键组合, 或者鼠标左右键, 当你修改的CAPTUREPARAMS后,应该发送WM_CAP_SET_SEQUENCE_SETUP消息来进行更新(或者使用 capCaptureSetSetup宏). 缺省的按键是VK_ESCAPE. 你必须在指定按键之前使用RegisterHotKey函数, 鼠标缺省的值是fAbortLeftMouse和fAbortRightMouse都为TRUE. 




3.捕获的时间限制 


CAPTUREPARAMS结构中的fLimitEnabled指示是否有时间限度, wTimeLimit指示最大的持续时间, 单位为秒. 


得 到fLimitEnabled和wTimeLimit的值可以发送WM_CAP_GET_SEQUENCE_SETUP消息(或使用 capCatureGetSetup宏), 当设置了这些成员变量后, 应该发送消息WM_CAP_SET_SEQUENCE_SETUP消息(或capCaptureSetSetup宏)来更新CAPTUREPARAMS结 构. 




三.关于捕获窗口 


在捕获之前必须创建一个捕获窗口(capture window),在发送消息或使用宏的过程中都需要使用此窗口。 


1.创建一个AVICap捕获窗口 


你可以使用capCreateCaptureWindow函数来创建一个AVICap捕获窗口, 此函数将会返回一个句柄, 此句柄以后在发送消息时要用. 


你可以在一个程序里创建一个或多个捕获窗口, 然后给每一个窗口连接不同的捕获设置. 




2.将一个捕获窗口连接至捕获设备 


你可以动态的在一个捕获窗口与一个捕获设备之前连接或断接, 你可以发送WM_CAP_DRIVER_CONNECT消息来使一个捕获窗口与一个捕获设备连接或关联. 当连接上以后, 你就可以通过捕获窗口向捕获设备发送各种消息. 


如果你的系统里装有多个捕获设备, 你可以在发送WM_CAP_DRIVER_CONNECT消息时用wParam参数指定使用哪一个, 此参数是登记在SYSTEM.INI文件的[drivers]一节里的列表中的某一项, 0为第一个. 


你可以使用capGetDriverDescription函数来得到已安装的捕获设备的名称及版本, 这样你的程序就可以列举所有已安装的捕获设备和驱动, 这样用户就可以选择其中的一个来与你的捕获窗口连接. 


你可以发送WM_CAP_DRIVER_GET_NAME消息(或capDriverGetName宏)来得到连接到捕获窗口的捕获设备的名称, 得到版本发送WM_CAP_DRIVER_GET_VERSION消息(或capDriverGetVersion宏) 


你可以发送WM_CAP_DRIVER_DISCONNECT消息(或capDriverDisconnect宏)来断接. 




3. 父窗口与子窗口的交互 


一些象WM_PALETTECHANGED和WM_QUERYNEWPALETTE的系统级消息只能发送到顶级窗口或OVERLAPPED窗口, 如果一个捕获窗口是子窗口,就必须通过父窗口转送. 


同样的, 如果父窗口的尺寸改变了, 它就需要通知捕获窗口, 相反地, 如果捕获窗口的尺寸改变了, 捕获窗口就需要发送消息给父窗口, 一个简单的方法就是始终保持捕获窗口的尺寸与视频流的尺寸一致, 并随时将尺寸的改变通知父窗口. 




4.捕获窗口的状态 


你可以发送WM_CAP_GET_STATUS消息(或capGetStatus宏)来得到当前捕获窗口的状态, 得到的是一个CAPSTATUS结构的拷贝, 它包含图片的尺寸, 卷轴的当前位置, overlay和preview是否已设置. 


因为CAPSTATUS信息是动态的, 你的程序应该只要捕获的视频流的尺寸或格式可能发生了改变就应该进行刷新(例如: 显示了捕获设备的视频格式以后). 


改变捕获窗口的尺寸并不影响实际的捕获的视频流的尺寸, 视频捕获设备的格式对话框捕获频流的尺寸. 




四.视频捕获驱动和音频驱动 


1.视频捕获驱动的性能: 


你可以通过发送WM_CAP_DRIVER_GET_CAPS消息(或者capDriverGetCaps宏)来得到当前连接的视频驱动的硬件性能. 得到的信息保存在CAPDRIVERCAPS结构中. 




2.视频对话框: 


每一个视频驱动能够提供四个对话框来控制视频捕获和数字化处理, 定义压缩品质等, 这些对话框都定义在视频捕获驱动中. 


Video Source对话框用于控制选择视频来源, 此对话框列举了此视频捕获卡连接的所有视频源(典型的例如:SVHS和合成输入), 并提供了改变色调, 对比度, 饱和度. 如果视频驱动支持此对话框, 你就可以显示并更新它, 使用WM_CAP_DLG_VIDEOSOURCE消息(或capDlgVideoSource宏). 


Video Format对话框定义视频帧的尺寸以及精度, 视频捕获卡的压缩设置. 如果卡支持的话, 可以发送消息WM_CAP_DLG_VIDEOFORMAT消息或(capDlgVideoFormat宏). 


Video Display对话框控制在视频捕获期间在显示器上的显示, 此控制不会影响视频数字数据, 但是他们可能会影响数字信号的表现形式, 例如: 如果捕获设备支持overlay, 可能允许改变色调和饱和度, 关键色彩 或者overlay队列. 如果卡支持, 你可以发送WM_CAP_DLG_VIDEODISPLAY消息(或者使用capDlgVideoDisplay宏). 


Video Compression对话框控制压缩品质, 如果卡支持, 发送消息WM_CAP_DLG_VIDEOCOMPRESSION(或capDlgVideoCompression宏). 




3.Preview 和 Overlay模式: 


一个视频捕获驱动对进入的视频流有两种工作模式: Preview模式和overlay模式, 如果一个捕获驱动能够执行两种方法, 用户可以在其中选择一种. 


Preview模式把从捕获硬件传来的数据送入系统内存并使用图形设备介面(GDI)将数字化帧显示在捕获窗口内. 应用程序可以在父窗口失去焦点时减缓显示速度, 当重新又得到焦点后加快显示速度, 此种模式要占用大量CPU时间. 


有三种消息控制Preview操作: 


WM_CAP_SET_PREIVEW消息(capPreview宏)允许或禁止preview模式 


WM_CAP_SET_PREVIEWRATE(capPreviewRate宏)当帧在preview模式显示时设置速度. 


WM_CAP_SET_SCALE(capPreviewScale宏)允许或禁止preview视频的缩放比例. 


当preview和scaling同时使用, 捕获的视频帧将会根据捕获窗口的尺寸自动缩放, 允许preview模式会自动关闭overlay模式. 


overlay模式是一个硬件函数它将数据送入捕获缓冲区中因而不占用CPU资源. 你可以发送消息WM_CAP_SET_OVERLAY(或capOverlay宏)给捕获窗口来启用或终止overlay模式, 允许overlay模式会自动禁止preview模式. 


你同时也可以在preview模式或overlay模式里发送WM_CAP_SET_SCROLL消息(或capSetScrollPos宏)来设置视频帧的客户区卷轴位置. 




4.视频格式 


你 可以通过发送WM_CAP_GET_VIDEOFORMAT消息(或capGetVideoFormat和capGetVideoFormatSize 宏)来得到视频格式的结构或结构的尺寸. 你可以通过发送CAP_SET_VIDEOFORMAT消息(或capSetVideoFormat宏)来设置视频格式. 




5.视频捕获设置 


CAPTUREPARMS结构包含了对视频捕获流的控制参数, 你可以完成以下这些任务: 


指定帧数 


指定分配多少视频缓冲 


允许或禁止声频捕获 


指定捕获的时间间隔 


指定在捕获的过程中是否使用MCI设置(VCR或者videodisc) 


指定终止流的键盘或鼠标 


specify the type of video averaging applied during capture. 




得到:WM_CAP_GET_SEQUENCE_SETUP消息(或capCaptureGetSetup宏) 


设置:WM_CAP_SET_SEQUENCE_SETUP消息(或capCaptureSetSetup宏) 




6.声频格式 


你 可以通过发送WM_CAP_GET_AUDIOFORMAT消息(或capGetAudioFormat宏和capGetAudioFormatSize 宏)来得到当前捕获音频数据的格式或尺寸格式。缺省的声频格式是:单声道、8位、11kHz PCM。 当你使用WM_CAP_GET_AUDIOFORMAT时,总是使用WAVEFORMATEX结构。 


设置发送消息WM_CAP_SET_AUDIOFORMAT消息(或capSetAudioFormat宏),可以传送WAVEFORMAT,WAVEFORMATEX,PCMWAVEFORMAT结构指针。 


五.使用视频捕获 


1.创建捕获窗口(Creating a Capture Window) 


hWndC = capCreateCaptureWindow ( 


(LPSTR) "My Capture Window", // window name if pop-up 


WS_CHILD | WS_VISIBLE, // window style 


0, 0, 160, 120, // window position and dimensions 


(HWND) hwndParent, 


(int) nID /* child ID */); 




2.连接到捕获驱动(Connecting to a Capture Driver) 


下面的例子是将MSVIDEO驱动连接到句柄为hWndC的捕获窗口, 然后调用capDriverDisconnect宏来断接. 


fOK = SendMessage (hWndC, WM_CAP_DRIVER_CONNECT, 0, 0L); 


// 


// Or, use the macro to connect to the MSVIDEO driver: 


// fOK = capDriverConnect(hWndC, 0); 


// 


// Place code to set up and capture video here. 


// 


capDriverDisconnect (hWndC); 




3.列举所有已安装的捕获驱动(Enumerating Installed Capture Drivers) 


下面的例子使用capGetDriverDescription函数得到已安装的捕获驱动的名称及版本: 


char szDeviceName[80]; 


char szDeviceVersion[80]; 




for (wIndex = 0; wIndex < 10; wIndex++) 





if (capGetDriverDescription (wIndex, szDeviceName, 


sizeof (szDeviceName), szDeviceVersion, 


sizeof (szDeviceVersion)) 





// Append name to list of installed capture drivers 


// and then let the user select a driver to use. 










4.得到捕获驱动的性能(Obtaining the Capabilities of a Capture Driver) 


发 送WM_CAP_DRIVER_GET_CAPS消息可以得到捕获驱动的性能,并保存入一个CAPDRIVERCAPS结构.每当程序连接一个新的捕获驱 动到一个捕获窗口时, 就应该更新CAPDRIVERCAPS结构. 下面的程序举例说明了如何使用capDriverGetCaps宏来得到捕获驱动的性能: 




CAPDRIVERCAPS CapDrvCaps; 


SendMessage (hWndC, WM_CAP_DRIVER_GET_CAPS, 


sizeof (CAPDRIVERCAPS), (LONG) (LPVOID) &CapDrvCaps); 


// Or, use the macro to retrieve the driver capabilities. 


// capDriverGetCaps(hWndC, &CapDrvCaps, sizeof (CAPDRIVERCAPS)); 




5.得到捕获窗口的状态(Obtaining the Status of a Capture Window) 


下面的例子使用SetWindowPos函数使捕获窗口与进来的视频流尺寸保持一致, 视频流的基本信息是使用capGetStatus宏得到的, 保存在CAPSTATUS结构中. 




CAPSTATUS CapStatus; 


capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS)); 


SetWindowPos(hWndC, NULL, 0, 0, CapStatus.uiImageWidth, 


CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE); 




6.显示对话框设置视频特征(Displaying Dialog Boxes to Set Video Characteristics) 


每个视频捕获卡一般能提供三个不同的对话框用于控制视频捕获及数字化处理. 下面的例子说明如何显示这些对话框, 在显示这些对话框之前,使用了capDriverGetCaps宏来检查CAPDRIVERCAPS结构, 以检测该卡是否有显示这些对话框: 




CAPDRIVERCAPS CapDrvCaps; 


capDriverGetCaps(hWndC, &CapDrvCaps, sizeof (CAPDRIVERCAPS)); 




// Video source dialog box. 


if (CapDriverCaps.fHasDlgVideoSource) 


capDlgVideoSource(hWndC); 




// Video format dialog box. 


if (CapDriverCaps.fHasDlgVideoFormat) 





capDlgVideoFormat(hWndC); 


// Are there new image dimensions? 


capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS)); 


// If so, notify the parent of a size change. 







// Video display dialog box. 


if (CapDriverCaps.fHasDlgVideoDisplay) 


capDlgVideoDisplay(hWndC); 




7.得到和设置视频格式(Obtaining and Setting the Video Format) 


BITMAPINFO 结构的长度既适应于标准的也适应于压缩的数据格式, 所有程序必须总是询问此结构的尺寸以便在得到当前的视频格式之前分配内存. 下面的例子就是使用capGetVideoFormatSize宏来得到缓冲区尺寸并调用capGetVideoFormat宏来得到当前的视频格式. 




LPBITMAPINFO lpbi; 


DWORD dwSize; 


dwSize = capGetVideoFormatSize(hWndC); 


lpbi = GlobalAllocPtr (GHND, dwSize); 


capGetVideoFormat(hWndC, lpbi, dwSize); 




// Access the video format and then free the allocated memory. 




程序可以使用capSetVideoFormat宏(或WM_CAP_SET_VIDEOFORMAT消息)发送一个BITMAPINFO头结构给捕获窗口, 因为视频格式是设备细节, 你的程序应该检查返回值以便确定此格式是否已被接受. 




8. 预览视频(Previewing Video) 


下面的例子使用capPreviewRate宏来设置每66毫秒显示一帧, 并使用capPreview宏将它放置在捕获窗口里. 




capPreviewRate(hWndC, 66); // rate, in milliseconds 


capPreview(hWndC, TRUE); // starts preview 


// Preview 


capPreview(hWnd, FALSE); // disables preview 




9.将视频设置为overlay模式(Enabling Video Overlay) 


下面的例子: capDriverGetCaps宏确定此捕获卡是否有overlay功能, 如果有就使用宏来设置它 




CAPDRIVERCAPS CapDrvCaps; 


capDriverGetCaps(hWndC, &CapDrvCaps, sizeof (CAPDRIVERCAPS)); 




if (CapDrvCaps.fHasOverlay) 


capOverlay(hWndC, TRUE); 




10.命名捕获文件(Naming the Capture File) 


下面的例子: 使用capFileSetCaptureFile宏来指定预备文件名为:MYCAP.AVI, capFileAlloc宏预先指定它的大小为5M. 




char szCaptureFile[] = "MYCAP.AVI"; 


capFileSetCaptureFile( hWndC, szCaptureFile); 


capFileAlloc( hWndC, (1024L * 1024L * 5)); 




11.格式化声频捕获(Formatting Audio Capture) 


下面的例子使用capSetAudioFormat来设置声频格式为:11kHz, PCM 8位, 立体声 




WAVEFORMATEX wfex; 


wfex.wFormatTag = WAVE_FORMAT_PCM; 


wfex.nChannels = 2; // Use stereo 


wfex.nSamplesPerSec = 11025; 


wfex.nAvgBytesPerSec = 22050; 


wfex.nBlockAlign = 2; 


wfex.wBitsPerSample = 8; 


wfex.cbSize = 0; 




capSetAudioFormat(hWndC, &wfex, sizeof(WAVEFORMATEX)); 




12.改变视频捕获设置(Changing a Video Capture Setting) 


下面的例子使用capCaptureGetSetup和capCaptureSetSetup宏得将捕获帧数从缺省的15帧改成每秒10帧. 




CAPTUREPARMS CaptureParms; 


float FramesPerSec = 10.0; 




capCaptureGetSetup(hWndC, &CaptureParms, sizeof(CAPTUREPARMS)); 




CaptureParms.dwRequestMicroSecPerFrame = (DWORD) (1.0e6 /FramesPerSec); 


capCaptureSetSetup(hWndC, &CaptureParms, sizeof (CAPTUREPARMS)); 




13.捕获数据(Capturing Data) 


下面的例子使用capCaptureSequence宏来开始捕获视频并使用capFileSaveAs宏来将捕获的数据拷贝至NEWFILE.AVI文件中. 




char szNewName[] = "NEWFILE.AVI"; 


// Set up the capture operation. 


capCaptureSequence(hWndC); 


// Capture. 


capFileSaveAs(hWndC, szNewName); 




14.增加一个信息块(Adding an Information Chunk) 


如 果你需要在你的程序捕获的声频和视频数据中加入你的其他信息, 你可以创建一个信息块并将它们插入捕获文件中, 信息块可以包含一些典型的信息, 例如:版权信息,视频来源, 外部定位信息等. 下面的例子使用capFileSetInfoChunk宏来插入一个信息块, 里面包含了一个SMPTE的时间代码. 




// This example assumes the application controls 


// the video source for preroll and postroll. 


CAPINFOCHUNK cic; 


// . 


// . 


// . 


cic.fccInfoID = infotypeSMPTE_TIME; 


cic.lpData = "00:20:30:12"; 


cic.cbData = strlen (cic.lpData) + 1; 


capFileSetInfoChunk (hwndC, &cic); 




15.在程序中加入一个回调函数(Adding Callback Functions to an Application) 


一个程序可以为捕获窗口登记一个回调函数以便在以下的这些情况下通知程序. 




状态改变 


错误发生 


视频框架和声频缓冲区变得可用 


程序应用在捕获视频流的过程中接收 




下面的例子创建一个捕获窗口并登记状态,错误,视频流和框架回调函数在消息处理对列中, 也包括了一个终止回调函数的说明. 




case WM_CREATE: 





char achDeviceName[80] 


char achDeviceVersion[100] 


char achBuffer[100] 


WORD wDriverCount = 0 


WORD wIndex 


WORD wError 


HMENU hMenu 




// Create a capture window using the capCreateCaptureWindow macro. 


ghWndCap = capCreateCaptureWindow((LPSTR)"Capture Window", 


WS_CHILD | WS_VISIBLE, 0, 0, 160, 120, (HWND) hWnd, (int) 0); 




// Register the error callback function using the 


// capSetCallbackOnError macro. 


capSetCallbackOnError(ghWndCap, fpErrorCallback); 




// Register the status callback function using the 


// capSetCallbackOnStatus macro. 


capSetCallbackOnStatus(ghWndCap, fpStatusCallback); 




// Register the video-stream callback function using the 


// capSetCallbackOnVideoStream macro. 


capSetCallbackOnVideoStream(ghWndCap, fpVideoCallback); 




// Register the frame callback function using the 


// capSetCallbackOnFrame macro. 


capSetCallbackOnFrame(ghWndCap, fpFrameCallback); 




// Connect to a capture driver 




break; 





case WM_CLOSE: 





// Use the capSetCallbackOnFrame macro to 


// disable the frame callback. Similar calls exist for the other 


// callback functions. 




capSetCallbackOnFrame(hWndC, NULL); 




break; 







16.创建一个状态回调函数(Creating a Status Callback Function) 


下面的例子是创建一个简单的状态回调函数,登记此回调函数使用capSetCallbackOnStatus宏. 




// StatusCallbackProc: status callback function 


// hWnd: capture window handle 


// nID: status code for the current status 


// lpStatusText: status text string for the current status 


// 


LRESULT PASCAL StatusCallbackProc(HWND hWnd, int nID, 


LPSTR lpStatusText) 





if (!ghWndMain) 


return FALSE; 




if (nID == 0) { // Clear old status messages. 


SetWindowText(ghWndMain, (LPSTR) gachAppName); 


return (LRESULT) TRUE; 





// Show the status ID and status text... 


wsprintf(gachBuffer, "Status# %d: %s", nID, lpStatusText); 




SetWindowText(ghWndMain, (LPSTR)gachBuffer); 


return (LRESULT) TRUE; 







17.创建一个错误回调函数( Creating an Error Callback Function) 


下面的例子是创建一个简单的错误回调函数,登记此回调函数使用capsetCallbackOnError宏: 




// ErrorCallbackProc: error callback function 


// hWnd: capture window handle 


// nErrID: error code for the encountered error 


// lpErrorText: error text string for the encountered error 


// 


LRESULT PASCAL ErrorCallbackProc(HWND hWnd, int nErrID, 


LPSTR lpErrorText) 





if (!ghWndMain) 


return FALSE; 




if (nErrID == 0) // Starting a new major function. 


return TRUE; // Clear out old errors. 




// Show the error identifier and text. 


wsprintf(gachBuffer, "Error# %d", nErrID); 




MessageBox(hWnd, lpErrorText, gachBuffer, 


MB_OK | MB_ICONEXCLAMATION); 




return (LRESULT) TRUE; 







18.创建一个框架回调函数(Creating a Frame Callback Function) 


登记此回调函数使用capSetCallbackOnFrame宏: 




// FrameCallbackProc: frame callback function 


// hWnd: capture window handle 


// lpVHdr: pointer to struct containing captured 


// frame information 


// 


LRESULT PASCAL FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr) 





if (!ghWndMain) 


return FALSE; 




wsprintf(gachBuffer, "Preview frame# %ld ", gdwFrameNum++); 


SetWindowText(ghWndMain, (LPSTR)gachBuffer); 


return (LRESULT) TRUE 


你可能感兴趣的:(windows,window,video,for,vfw)