Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1213 lines
40 KiB

  1. /****************************************************************************
  2. *
  3. * capwin.c
  4. *
  5. * Main window proceedure.
  6. *
  7. * Microsoft Video for Windows Sample Capture Class
  8. *
  9. * Copyright (c) 1992, 1993 Microsoft Corporation. All Rights Reserved.
  10. *
  11. * You have a royalty-free right to use, modify, reproduce and
  12. * distribute the Sample Files (and/or any modified version) in
  13. * any way you find useful, provided that you agree that
  14. * Microsoft has no warranty obligations or liability for any
  15. * Sample Application Files which are modified.
  16. *
  17. ***************************************************************************/
  18. #include <windows.h>
  19. #include <windowsx.h>
  20. #include <mmsystem.h>
  21. #include <msvideo.h>
  22. #include <drawdib.h>
  23. #include <mmreg.h>
  24. #include <memory.h>
  25. #include "avicap.h"
  26. #include "avicapi.h"
  27. #include "cappal.h"
  28. #include "capdib.h"
  29. #include "dibmap.h"
  30. // GetWindowLong assignments
  31. #define GWL_CAPSTREAM 0
  32. #define GWL_CAPVBSTATUS 4 // Used by VB Status callback
  33. #define GWL_CAPVBERROR 8 // Used by VB Error callback
  34. #define GWL_CAP_SPARE1 12 // Room to grow
  35. #define GWL_CAP_SPARE2 16 // Room to grow
  36. #define ID_PREVIEWTIMER 9
  37. //#ifdef _DEBUG
  38. #ifdef PLASTIQUE
  39. #define MB(lpsz) MessageBox(NULL, lpsz, "", MB_OK);
  40. #else
  41. #define MB(lpsz)
  42. #endif
  43. //
  44. // Set the overlay rectangles on capture cards which support
  45. // overlay, and then enable/disable the key color.
  46. //
  47. static void SetOverlayRectangles (LPCAPSTREAM lpcs)
  48. {
  49. HDC hdc;
  50. BOOL fVisible;
  51. RECT rc;
  52. if (!lpcs->hVideoDisplay)
  53. return;
  54. hdc = GetDC (lpcs->hwnd);
  55. fVisible = (GetClipBox (hdc, &rc) != NULLREGION);
  56. ReleaseDC (lpcs->hwnd, hdc);
  57. if (!fVisible) // disable the overlay if iconic
  58. videoStreamFini (lpcs->hVideoDisplay);
  59. else {
  60. // Destination
  61. GetClientRect (lpcs->hwnd, &rc);
  62. ClientToScreen (lpcs->hwnd, (LPPOINT)&rc);
  63. ClientToScreen (lpcs->hwnd, (LPPOINT)&rc+1);
  64. videoMessage (lpcs->hVideoDisplay,
  65. DVM_DST_RECT,
  66. (DWORD) (LPVOID) &rc, VIDEO_CONFIGURE_SET);
  67. // Overlay channel Source rectangle
  68. SetRect (&rc, lpcs->ptScroll.x, lpcs->ptScroll.y,
  69. lpcs->ptScroll.x + rc.right - rc.left,
  70. lpcs->ptScroll.y + rc.bottom - rc.top);
  71. videoMessage (lpcs->hVideoDisplay,
  72. DVM_SRC_RECT,
  73. (DWORD) (LPVOID) &rc, VIDEO_CONFIGURE_SET);
  74. videoStreamInit (lpcs->hVideoDisplay, 0L, 0L, 0L, 0L);
  75. }
  76. }
  77. // WM_POSITIONCHANGED and WM_POSITIONCHANGING don't do enough to
  78. // handle clipping of the overlay window on the Intel board,
  79. // which keys on black. Do this routine on WM_PAINT and
  80. // WM_ENTERIDLE messages.
  81. void CheckWindowMove(LPCAPSTREAM lpcs, HDC hdcWnd, BOOL fForce)
  82. {
  83. UINT wRgn;
  84. RECT rc;
  85. DWORD dwOrg;
  86. HDC hdc;
  87. BOOL f;
  88. if (!lpcs->hwnd || !lpcs->hVideoDisplay || !lpcs->fOverlayWindow)
  89. return;
  90. //
  91. // when the screen is locked for update by a window move operation
  92. // we dont want to turn off the video.
  93. //
  94. // we can tell if the screen is locked by checking a DC to the screen.
  95. //
  96. hdc = GetDC(NULL);
  97. f = GetClipBox(hdc, &rc) == NULLREGION;
  98. ReleaseDC(NULL, hdc);
  99. if (f) {
  100. lpcs->uiRegion = (UINT) -1;
  101. return;
  102. }
  103. if (fForce)
  104. lpcs->uiRegion = (UINT) -1;
  105. hdc = GetDC (lpcs->hwnd);
  106. wRgn = GetClipBox(hdc, &rc);
  107. dwOrg = GetDCOrg(hdc);
  108. ReleaseDC(lpcs->hwnd, hdc);
  109. if (wRgn == lpcs->uiRegion &&
  110. dwOrg == lpcs->dwRegionOrigin &&
  111. EqualRect(&rc, &lpcs->rcRegionRect))
  112. return;
  113. lpcs->uiRegion = wRgn;
  114. lpcs->dwRegionOrigin = dwOrg;
  115. lpcs->rcRegionRect = rc;
  116. SetOverlayRectangles (lpcs);
  117. if (hdcWnd)
  118. videoUpdate (lpcs->hVideoDisplay, lpcs->hwnd, hdcWnd);
  119. else
  120. InvalidateRect (lpcs->hwnd, NULL, TRUE);
  121. }
  122. //
  123. // Create our little world
  124. //
  125. LPCAPSTREAM CapWinCreate (HWND hwnd)
  126. {
  127. LPCAPSTREAM lpcs;
  128. WAVEFORMATEX wfex;
  129. if (!(lpcs = (LPCAPSTREAM) GlobalAllocPtr (GHND, sizeof (CAPSTREAM))))
  130. return NULL;
  131. SetWindowLong (hwnd, GWL_CAPSTREAM, (LONG)lpcs);
  132. lpcs-> dwSize = sizeof (CAPSTREAM);
  133. lpcs-> uiVersion = CAPSTREAM_VERSION;
  134. lpcs-> hwnd = hwnd;
  135. lpcs-> hInst = ghInst;
  136. lpcs-> hWaitCursor = LoadCursor(NULL, IDC_WAIT);
  137. lpcs-> hdd = DrawDibOpen();
  138. lpcs-> fAudioHardware = !!waveOutGetNumDevs(); // force 1 or 0
  139. // Video defaults
  140. lpcs-> sCapParms.dwRequestMicroSecPerFrame = 66667; // 15fps
  141. lpcs-> sCapParms.vKeyAbort = VK_ESCAPE;
  142. lpcs-> sCapParms.fAbortLeftMouse = TRUE;
  143. lpcs-> sCapParms.fAbortRightMouse = TRUE;
  144. lpcs-> sCapParms.wNumVideoRequested = MIN_VIDEO_BUFFERS;
  145. lpcs-> fCapturingToDisk = TRUE;
  146. lpcs-> sCapParms.wPercentDropForError = 10; // error msg if dropped > 10%
  147. lpcs-> sCapParms.wChunkGranularity = 2048;
  148. // Audio defaults to 11K, 8bit, Mono
  149. lpcs-> sCapParms.fCaptureAudio = lpcs-> fAudioHardware;
  150. lpcs-> sCapParms.wNumAudioRequested = DEF_WAVE_BUFFERS;
  151. wfex.wFormatTag = WAVE_FORMAT_PCM;
  152. wfex.nChannels = 1;
  153. wfex.nSamplesPerSec = 11025;
  154. wfex.nAvgBytesPerSec = 11025;
  155. wfex.nBlockAlign = 1;
  156. wfex.wBitsPerSample = 8;
  157. wfex.cbSize = 0;
  158. SendMessage (hwnd, WM_CAP_SET_AUDIOFORMAT, 0, (LONG)(LPVOID)&wfex);
  159. // Palette defaults
  160. lpcs-> nPaletteColors = 256;
  161. // Capture defaults
  162. lpcs-> sCapParms.fUsingDOSMemory = FALSE;
  163. lstrcpy (lpcs-> achFile, "C:\\CAPTURE.AVI"); // Default capture file
  164. lpcs->fCapFileExists = fileCapFileIsAVI (lpcs->achFile);
  165. // Allocate index to 32K frames plus proportionate number of audio chunks
  166. lpcs->sCapParms.dwIndexSize = (32768ul + (32768ul / 15));
  167. lpcs->sCapParms.fDisableWriteCache = TRUE;
  168. // Init the COMPVARS structure
  169. lpcs->CompVars.cbSize = sizeof (COMPVARS);
  170. lpcs->CompVars.dwFlags = 0;
  171. return lpcs;
  172. }
  173. //
  174. // Destroy our little world
  175. //
  176. void CapWinDestroy (LPCAPSTREAM lpcs)
  177. {
  178. // Uh, oh. Somebodys trying to kill us while capturing
  179. if (lpcs->fCapturingNow && lpcs->fFrameCapturingNow) {
  180. // Single frame capture in progress
  181. SingleFrameCaptureClose (lpcs);
  182. }
  183. else if (lpcs->fCapturingNow) {
  184. // Streaming capture in progress, OR
  185. // MCI step capture in progress
  186. lpcs->fAbortCapture = TRUE;
  187. while (lpcs->fCapturingNow)
  188. Yield ();
  189. }
  190. if (lpcs->idTimer)
  191. KillTimer(lpcs->hwnd, lpcs->idTimer);
  192. PalFini (lpcs);
  193. DibFini (lpcs);
  194. CapWinDisconnectHardware (lpcs);
  195. DrawDibClose (lpcs->hdd);
  196. if (lpcs->lpWaveFormat)
  197. GlobalFreePtr (lpcs-> lpWaveFormat);
  198. if (lpcs->CompVars.hic)
  199. ICCompressorFree(&lpcs->CompVars);
  200. if (lpcs->lpInfoChunks)
  201. GlobalFreePtr(lpcs->lpInfoChunks);
  202. GlobalFreePtr (lpcs); // Free the instance memory
  203. }
  204. WORD GetSizeOfWaveFormat (LPWAVEFORMATEX lpwf)
  205. {
  206. WORD wSize;
  207. if (lpwf == NULL)
  208. return sizeof (PCMWAVEFORMAT);
  209. if (lpwf->wFormatTag == WAVE_FORMAT_PCM)
  210. wSize = sizeof (PCMWAVEFORMAT);
  211. else
  212. wSize = sizeof (WAVEFORMATEX) + lpwf -> cbSize;
  213. return wSize;
  214. }
  215. // Returns TRUE if we got a new frame, else FALSE
  216. // if fForce, then always get a new frame
  217. BOOL GetAFrameThenCallback (LPCAPSTREAM lpcs, BOOL fForce)
  218. {
  219. BOOL fOK = FALSE;
  220. static BOOL fRecursion = FALSE;
  221. BOOL fVisible;
  222. RECT rc;
  223. HDC hdc;
  224. if (fRecursion)
  225. return FALSE;
  226. if (!lpcs->sCapDrvCaps.fCaptureInitialized)
  227. return fOK;
  228. fRecursion = TRUE;
  229. // Update the preview window if we got a timer and not saving to disk
  230. if (lpcs->fOverlayWindow)
  231. CheckWindowMove(lpcs, NULL, FALSE);
  232. if ((!lpcs->fCapturingNow) || lpcs->fStepCapturingNow || lpcs->fFrameCapturingNow) {
  233. hdc = GetDC (lpcs->hwnd);
  234. fVisible = (GetClipBox (hdc, &rc) != NULLREGION);
  235. ReleaseDC (lpcs->hwnd, hdc);
  236. if (fForce || (fVisible && (lpcs->fLiveWindow || lpcs->CallbackOnVideoFrame))) {
  237. videoFrame (lpcs->hVideoIn, &lpcs->VidHdr );
  238. fOK = TRUE;
  239. if (lpcs->CallbackOnVideoFrame)
  240. (*(lpcs->CallbackOnVideoFrame)) (lpcs->hwnd, &lpcs->VidHdr);
  241. if (fForce || lpcs->fLiveWindow) {
  242. InvalidateRect (lpcs->hwnd, NULL, TRUE);
  243. UpdateWindow (lpcs->hwnd);
  244. }
  245. } // if visible
  246. } // if we're not streaming
  247. fRecursion = FALSE;
  248. return fOK;
  249. }
  250. // Clear the Status and Error strings via callback
  251. void FAR PASCAL ClearStatusAndError (LPCAPSTREAM lpcs)
  252. {
  253. statusUpdateStatus(lpcs, NULL); // Clear status
  254. errorUpdateError(lpcs, NULL); // Clear error
  255. }
  256. // Process class specific commands >= WM_USER
  257. DWORD PASCAL ProcessCommandMessages (LPCAPSTREAM lpcs, unsigned msg, WORD wParam, LPARAM lParam)
  258. {
  259. DWORD dwReturn = 0L;
  260. DWORD dwT;
  261. switch (msg) {
  262. // Don't clear status and error on the following innocuous msgs
  263. case WM_CAP_GET_CAPSTREAMPTR:
  264. case WM_CAP_GET_USER_DATA:
  265. case WM_CAP_DRIVER_GET_NAME:
  266. case WM_CAP_DRIVER_GET_VERSION:
  267. case WM_CAP_DRIVER_GET_CAPS:
  268. case WM_CAP_GET_AUDIOFORMAT:
  269. case WM_CAP_GET_VIDEOFORMAT:
  270. case WM_CAP_GET_STATUS:
  271. case WM_CAP_SET_SEQUENCE_SETUP:
  272. case WM_CAP_GET_SEQUENCE_SETUP:
  273. case WM_CAP_GET_MCI_DEVICE:
  274. break;
  275. default:
  276. ClearStatusAndError (lpcs);
  277. break;
  278. }
  279. switch (msg) {
  280. case WM_CAP_GET_CAPSTREAMPTR:
  281. // return a pointer to the CAPSTREAM
  282. return (DWORD) (LPVOID) lpcs;
  283. case WM_CAP_GET_USER_DATA:
  284. return lpcs->lUser;
  285. case WM_CAP_DRIVER_GET_NAME:
  286. // Return the name of the capture driver in use
  287. // wParam is the length of the buffer pointed to by lParam
  288. if (!lpcs->fHardwareConnected)
  289. return FALSE;
  290. return (capInternalGetDriverDesc (lpcs->sCapDrvCaps.wDeviceIndex,
  291. (LPSTR) lParam, (int) wParam, NULL, 0));
  292. case WM_CAP_DRIVER_GET_VERSION:
  293. // Return the version of the capture driver in use as text
  294. // wParam is the length of the buffer pointed to by lParam
  295. if (!lpcs->fHardwareConnected)
  296. return FALSE;
  297. return (capInternalGetDriverDesc (lpcs->sCapDrvCaps.wDeviceIndex,
  298. NULL, 0, (LPSTR) lParam, (int) wParam));
  299. case WM_CAP_DRIVER_GET_CAPS:
  300. // wParam is the size of the CAPDRIVERCAPS struct
  301. // lParam points to a CAPDRIVERCAPS struct
  302. if (!lpcs->fHardwareConnected)
  303. return FALSE;
  304. if (wParam <= sizeof (CAPDRIVERCAPS) &&
  305. !IsBadWritePtr ((LPVOID) lParam, (UINT) wParam)) {
  306. dwT = min (wParam, sizeof (CAPDRIVERCAPS));
  307. _fmemcpy ((LPVOID) lParam, (LPVOID) &lpcs-> sCapDrvCaps, (WORD) dwT);
  308. dwReturn = TRUE;
  309. }
  310. break;
  311. case WM_CAP_FILE_GET_CAPTURE_FILE:
  312. // wParam is the size
  313. // lParam points to a buffer in which capture file name is copied
  314. if (lParam) {
  315. lstrcpyn ((LPSTR) lParam, lpcs->achFile, wParam);
  316. dwReturn = TRUE;
  317. }
  318. break;
  319. case WM_CAP_GET_AUDIOFORMAT:
  320. // if lParam == NULL, return the size
  321. // if lParam != NULL, wParam is the size, return bytes copied
  322. if (lpcs->lpWaveFormat == NULL)
  323. return FALSE;
  324. dwT = GetSizeOfWaveFormat ((LPWAVEFORMATEX) lpcs->lpWaveFormat);
  325. if (lParam == NULL)
  326. return (dwT);
  327. else {
  328. if (wParam < (WORD) dwT)
  329. return FALSE;
  330. else {
  331. hmemcpy ((LPVOID) lParam, (LPVOID) lpcs->lpWaveFormat, dwT);
  332. dwReturn = dwT;
  333. }
  334. }
  335. break;
  336. case WM_CAP_GET_MCI_DEVICE:
  337. // wParam is the size
  338. // lParam points to a buffer in which capture file name is copied
  339. if (lParam) {
  340. lstrcpyn ((LPSTR) lParam, lpcs->achMCIDevice, wParam);
  341. dwReturn = TRUE;
  342. }
  343. break;
  344. case WM_CAP_GET_STATUS:
  345. // wParam is the size of the CAPSTATUS struct pointed to by lParam
  346. if (!lpcs->fHardwareConnected)
  347. return FALSE;
  348. if (IsBadWritePtr ((LPVOID) lParam, (UINT) wParam))
  349. return FALSE;
  350. if (wParam >= sizeof (CAPSTATUS)) {
  351. LPCAPSTATUS lpcc = (LPCAPSTATUS) lParam;
  352. lpcc-> fLiveWindow = lpcs-> fLiveWindow;
  353. lpcc-> fOverlayWindow = lpcs-> fOverlayWindow;
  354. lpcc-> fScale = lpcs-> fScale;
  355. lpcc-> ptScroll = lpcs-> ptScroll;
  356. lpcc-> fUsingDefaultPalette = lpcs-> fUsingDefaultPalette;
  357. lpcc-> fCapFileExists = lpcs-> fCapFileExists;
  358. lpcc-> fAudioHardware = lpcs-> fAudioHardware;
  359. lpcc-> uiImageWidth = lpcs-> dxBits;
  360. lpcc-> uiImageHeight = lpcs-> dyBits;
  361. // The following are updated dynamically during capture
  362. lpcc-> dwCurrentVideoFrame = lpcs-> dwVideoChunkCount;
  363. lpcc-> dwCurrentVideoFramesDropped = lpcs-> dwFramesDropped;
  364. if (lpcs->lpWaveFormat != NULL) {
  365. lpcc-> dwCurrentWaveSamples =
  366. muldiv32 (lpcs-> dwWaveBytes,
  367. lpcs-> lpWaveFormat-> nSamplesPerSec,
  368. lpcs-> lpWaveFormat-> nAvgBytesPerSec);
  369. }
  370. lpcc-> dwCurrentTimeElapsedMS = lpcs-> dwTimeElapsedMS;
  371. // Added post alpha release
  372. lpcc-> fCapturingNow = lpcs-> fCapturingNow;
  373. lpcc-> hPalCurrent = lpcs-> hPalCurrent;
  374. lpcc-> dwReturn = lpcs-> dwReturn;
  375. lpcc-> wNumVideoAllocated = lpcs-> iNumVideo;
  376. lpcc-> wNumAudioAllocated = lpcs-> iNumAudio;
  377. dwReturn = TRUE;
  378. }
  379. break;
  380. case WM_CAP_GET_SEQUENCE_SETUP:
  381. // wParam is sizeof CAPTUREPARMS
  382. // lParam = LPCAPTUREPARMS
  383. if (wParam <= sizeof (CAPTUREPARMS) &&
  384. !IsBadWritePtr ((LPVOID) lParam, (UINT) wParam)) {
  385. dwT = min (wParam, sizeof (CAPTUREPARMS));
  386. _fmemcpy ((LPVOID) lParam, (LPVOID) &lpcs->sCapParms, (WORD) dwT);
  387. dwReturn = TRUE;
  388. }
  389. break;
  390. case WM_CAP_STOP:
  391. // Stop capturing a sequence
  392. if (lpcs-> fCapturingNow) {
  393. lpcs-> fStopCapture = TRUE;
  394. dwReturn = TRUE;
  395. }
  396. break;
  397. case WM_CAP_ABORT:
  398. // Stop capturing a sequence
  399. if (lpcs-> fCapturingNow) {
  400. lpcs-> fAbortCapture = TRUE;
  401. dwReturn = TRUE;
  402. }
  403. break;
  404. case WM_CAP_GET_VIDEOFORMAT:
  405. // if lParam == NULL, return the size
  406. // if lParam != NULL, wParam is the size, return bytes copied
  407. if (!lpcs->fHardwareConnected)
  408. return FALSE;
  409. dwT = ((LPBITMAPINFOHEADER)lpcs->lpBitsInfo)-> biSize +
  410. ((LPBITMAPINFOHEADER)lpcs->lpBitsInfo)->biClrUsed * sizeof(RGBQUAD);
  411. if (lParam == NULL)
  412. return dwT;
  413. else {
  414. if (wParam < (WORD) dwT)
  415. return FALSE;
  416. else {
  417. hmemcpy ((LPVOID) lParam, (LPVOID) lpcs->lpBitsInfo, dwT);
  418. dwReturn = dwT;
  419. }
  420. }
  421. break;
  422. case WM_CAP_SINGLE_FRAME_OPEN:
  423. // wParam is not used
  424. // lParam is not used
  425. if (!lpcs->fHardwareConnected)
  426. return FALSE;
  427. return SingleFrameCaptureOpen (lpcs);
  428. case WM_CAP_SINGLE_FRAME_CLOSE:
  429. // wParam is not used
  430. // lParam is not used
  431. if (!lpcs->fHardwareConnected)
  432. return FALSE;
  433. return SingleFrameCaptureClose (lpcs);
  434. case WM_CAP_SINGLE_FRAME:
  435. // wParam is not used
  436. // lParam is not used
  437. if (!lpcs->fHardwareConnected)
  438. return FALSE;
  439. return SingleFrameCapture (lpcs);
  440. case WM_CAP_SET_CALLBACK_STATUS:
  441. // Set the status callback proc
  442. if (lParam != NULL && IsBadCodePtr ((FARPROC) lParam))
  443. return FALSE;
  444. lpcs->CallbackOnStatus = (CAPSTATUSCALLBACK) lParam;
  445. return TRUE;
  446. case WM_CAP_SET_CALLBACK_ERROR:
  447. // Set the error callback proc
  448. if (lParam != NULL && IsBadCodePtr ((FARPROC) lParam))
  449. return FALSE;
  450. lpcs->CallbackOnError = (CAPERRORCALLBACK) lParam;
  451. return TRUE;
  452. case WM_CAP_SET_CALLBACK_FRAME:
  453. // Set the callback proc for single frame during preview
  454. if (lParam != NULL && IsBadCodePtr ((FARPROC) lParam))
  455. return FALSE;
  456. lpcs->CallbackOnVideoFrame = (CAPVIDEOCALLBACK) lParam;
  457. return TRUE;
  458. default:
  459. break;
  460. }
  461. // Once we start capturing, don't change anything
  462. if (lpcs-> fCapturingNow)
  463. return dwReturn;
  464. switch (msg) {
  465. case WM_CAP_SET_CALLBACK_YIELD:
  466. // Set the callback proc for wave buffer processing to net
  467. if (lParam != NULL && IsBadCodePtr ((FARPROC) lParam))
  468. return FALSE;
  469. lpcs->CallbackOnYield = (CAPYIELDCALLBACK) lParam;
  470. return TRUE;
  471. case WM_CAP_SET_CALLBACK_VIDEOSTREAM:
  472. // Set the callback proc for video buffer processing to net
  473. if (lParam != NULL && IsBadCodePtr ((FARPROC) lParam))
  474. return FALSE;
  475. lpcs->CallbackOnVideoStream = (CAPVIDEOCALLBACK) lParam;
  476. return TRUE;
  477. case WM_CAP_SET_CALLBACK_WAVESTREAM:
  478. // Set the callback proc for wave buffer processing to net
  479. if (lParam != NULL && IsBadCodePtr ((FARPROC) lParam))
  480. return FALSE;
  481. lpcs->CallbackOnWaveStream = (CAPWAVECALLBACK) lParam;
  482. return TRUE;
  483. case WM_CAP_SET_CALLBACK_CAPCONTROL:
  484. // Set the callback proc for frame accurate capture start/stop
  485. if (lParam != NULL && IsBadCodePtr ((FARPROC) lParam))
  486. return FALSE;
  487. lpcs->CallbackOnControl = (CAPCONTROLCALLBACK) lParam;
  488. return TRUE;
  489. case WM_CAP_SET_USER_DATA:
  490. lpcs->lUser = lParam;
  491. return TRUE;
  492. case WM_CAP_DRIVER_CONNECT:
  493. // Connect to a device
  494. // wParam contains the index of the driver in system.ini
  495. // If the same driver ID is requested, skip the request
  496. // Prevents multiple Inits from VB apps
  497. if (lpcs->fHardwareConnected &&
  498. (lpcs->sCapDrvCaps.wDeviceIndex == wParam))
  499. return TRUE;
  500. // First disconnect from any (possibly) existing device
  501. SendMessage (lpcs->hwnd, WM_CAP_DRIVER_DISCONNECT, 0, 0l);
  502. // and then connect to the new device
  503. if (CapWinConnectHardware (lpcs, (WORD) wParam /*wDeviceIndex*/)) {
  504. if (!DibGetNewFormatFromDriver (lpcs)) { // Allocate our bitspace
  505. PalGetPaletteFromDriver (lpcs);
  506. InvalidateRect(lpcs->hwnd, NULL, TRUE);
  507. lpcs->sCapDrvCaps.fCaptureInitialized = TRUE; // everything AOK!
  508. dwReturn = TRUE;
  509. }
  510. }
  511. break;
  512. case WM_CAP_DRIVER_DISCONNECT:
  513. MB ("About to disconnect from driver");
  514. // Disconnect from a device
  515. // wParam and lParam unused
  516. if (!lpcs->fHardwareConnected)
  517. return FALSE;
  518. CapWinDisconnectHardware (lpcs);
  519. DibFini (lpcs);
  520. PalFini (lpcs);
  521. InvalidateRect(lpcs->hwnd, NULL, TRUE);
  522. lpcs->sCapDrvCaps.fCaptureInitialized = FALSE;
  523. dwReturn = TRUE;
  524. break;
  525. case WM_CAP_FILE_SET_CAPTURE_FILE:
  526. // lParam points to the name of the capture file
  527. if (lParam) {
  528. BOOL fAlreadyExists; // Don't create a file if new name
  529. OFSTRUCT of;
  530. HANDLE hFile;
  531. // Check for valid file names...
  532. if ((hFile = OpenFile ((LPSTR) lParam, &of, OF_WRITE)) == -1) {
  533. if ((hFile = OpenFile ((LPSTR) lParam, &of, OF_CREATE | OF_WRITE)) == -1)
  534. return FALSE;
  535. fAlreadyExists = FALSE;
  536. }
  537. else
  538. fAlreadyExists = TRUE;
  539. _lclose (hFile);
  540. lstrcpyn (lpcs->achFile, (LPSTR) lParam, sizeof (lpcs->achFile));
  541. lpcs->fCapFileExists = fileCapFileIsAVI (lpcs->achFile);
  542. if (!fAlreadyExists)
  543. OpenFile ((LPSTR) lParam, &of, OF_DELETE);
  544. dwReturn = TRUE;
  545. }
  546. break;
  547. case WM_CAP_FILE_ALLOCATE:
  548. // lParam contains the size to preallocate the capture file in bytes
  549. return fileAllocCapFile(lpcs, lParam);
  550. case WM_CAP_FILE_SAVEAS:
  551. // lParam points to the name of the SaveAs file
  552. if (lParam) {
  553. lstrcpyn (lpcs->achSaveAsFile, (LPSTR) lParam,
  554. sizeof (lpcs->achSaveAsFile));
  555. return (fileSaveCopy(lpcs));
  556. }
  557. break;
  558. case WM_CAP_FILE_SET_INFOCHUNK:
  559. // wParam is not used
  560. // lParam is an LPCAPINFOCHUNK
  561. if (lParam) {
  562. return (SetInfoChunk(lpcs, (LPCAPINFOCHUNK) lParam));
  563. }
  564. break;
  565. case WM_CAP_FILE_SAVEDIB:
  566. // lParam points to the name of the DIB file
  567. if (lParam) {
  568. if (lpcs-> fOverlayWindow)
  569. GetAFrameThenCallback (lpcs, TRUE /*fForce*/);
  570. return (fileSaveDIB(lpcs, (LPSTR)lParam));
  571. }
  572. break;
  573. case WM_CAP_EDIT_COPY:
  574. // Copy the current image and palette to the clipboard
  575. // wParam and lParam unused
  576. if (!lpcs->fHardwareConnected)
  577. return FALSE;
  578. if (lpcs-> fOverlayWindow)
  579. GetAFrameThenCallback (lpcs, TRUE /*fForce*/);
  580. if (lpcs->sCapDrvCaps.fCaptureInitialized && OpenClipboard (lpcs->hwnd)) {
  581. EmptyClipboard();
  582. // put a copy of the current palette in the clipboard
  583. if (lpcs->hPalCurrent && lpcs->lpBitsInfo->bmiHeader.biBitCount <= 8)
  584. SetClipboardData(CF_PALETTE, CopyPalette (lpcs->hPalCurrent));
  585. // make a packed DIB out of the current image
  586. if (lpcs-> lpBits && lpcs->lpBitsInfo ) {
  587. if (SetClipboardData (CF_DIB, CreatePackedDib (lpcs->lpBitsInfo,
  588. lpcs-> lpBits, lpcs-> hPalCurrent)))
  589. dwReturn = TRUE;
  590. else
  591. errorUpdateError (lpcs, IDS_CAP_OUTOFMEM);
  592. }
  593. CloseClipboard();
  594. }
  595. break;
  596. case WM_CAP_SET_AUDIOFORMAT:
  597. {
  598. // wParam is unused
  599. // lParam is LPWAVEFORMAT or LPWAVEFORMATEX
  600. WORD wSize;
  601. LPWAVEFORMATEX lpwf = (LPWAVEFORMATEX) lParam;
  602. UINT uiError;
  603. // Verify the waveformat is valid
  604. uiError = waveInOpen((LPHWAVEIN)NULL,
  605. (UINT)WAVE_MAPPER, lpwf,
  606. NULL /*hWndCallback */, 0L,
  607. WAVE_FORMAT_QUERY);
  608. if (uiError) {
  609. errorUpdateError (lpcs, IDS_CAP_WAVE_OPEN_ERROR);
  610. return FALSE;
  611. }
  612. if (lpcs->lpWaveFormat)
  613. GlobalFreePtr (lpcs-> lpWaveFormat);
  614. wSize = GetSizeOfWaveFormat (lpwf);
  615. if (lpcs-> lpWaveFormat = (LPWAVEFORMATEX)
  616. GlobalAllocPtr (GHND, sizeof (CAPSTREAM))) {
  617. hmemcpy (lpcs->lpWaveFormat, lpwf, (LONG) wSize);
  618. }
  619. dwReturn = TRUE;
  620. }
  621. break;
  622. case WM_CAP_DLG_VIDEOSOURCE:
  623. // Show the dialog which controls the video source
  624. // NTSC vs PAL, input channel selection, etc.
  625. // wParam and lParam are unused
  626. if (!lpcs->fHardwareConnected)
  627. return FALSE;
  628. if (lpcs-> sCapDrvCaps.fHasDlgVideoSource) {
  629. videoDialog (lpcs->hVideoCapture, lpcs->hwnd, 0L );
  630. // Changing from NTSC to PAL could affect image dimensions!!!
  631. DibGetNewFormatFromDriver (lpcs);
  632. PalGetPaletteFromDriver (lpcs);
  633. // May need to inform parent of new layout here!
  634. InvalidateRect(lpcs->hwnd, NULL, TRUE);
  635. UpdateWindow(lpcs->hwnd);
  636. }
  637. return (lpcs-> sCapDrvCaps.fHasDlgVideoSource);
  638. case WM_CAP_DLG_VIDEOFORMAT:
  639. // Show the format dialog, user selects dimensions, depth, compression
  640. // wParam and lParam are unused
  641. if (!lpcs->fHardwareConnected)
  642. return FALSE;
  643. if (lpcs->sCapDrvCaps.fHasDlgVideoFormat) {
  644. videoDialog (lpcs->hVideoIn, lpcs->hwnd, 0L );
  645. DibGetNewFormatFromDriver (lpcs);
  646. PalGetPaletteFromDriver (lpcs);
  647. // May need to inform parent of new layout here!
  648. InvalidateRect(lpcs->hwnd, NULL, TRUE);
  649. UpdateWindow(lpcs->hwnd);
  650. }
  651. return (lpcs-> sCapDrvCaps.fHasDlgVideoFormat);
  652. case WM_CAP_DLG_VIDEODISPLAY:
  653. // Show the dialog which controls output.
  654. // This dialog only affects the presentation, never the data format
  655. // wParam and lParam are unused
  656. if (!lpcs->fHardwareConnected)
  657. return FALSE;
  658. if (lpcs->sCapDrvCaps.fHasDlgVideoDisplay)
  659. videoDialog (lpcs->hVideoDisplay, lpcs->hwnd, 0L);
  660. return (lpcs->sCapDrvCaps.fHasDlgVideoDisplay);
  661. case WM_CAP_DLG_VIDEOCOMPRESSION:
  662. // Show the dialog which selects video compression options.
  663. // wParam and lParam are unused
  664. if (!lpcs->fHardwareConnected)
  665. return FALSE;
  666. ICCompressorChoose(
  667. lpcs->hwnd, // parent window for dialog
  668. ICMF_CHOOSE_KEYFRAME, // want "key frame every" box
  669. lpcs->lpBitsInfo, // input format (optional)
  670. NULL, // input data (optional)
  671. &lpcs->CompVars, // data about the compressor/dlg
  672. NULL); // title bar (optional)
  673. return TRUE;
  674. case WM_CAP_SET_VIDEOFORMAT:
  675. // wParam is the size of the BITMAPINFO
  676. // lParam is an LPBITMAPINFO
  677. if (!lpcs->fHardwareConnected)
  678. return FALSE;
  679. if (IsBadReadPtr ((LPVOID) lParam, (UINT) wParam))
  680. return FALSE;
  681. return (DibNewFormatFromApp (lpcs, (LPBITMAPINFO) lParam, (WORD) wParam));
  682. case WM_CAP_SET_PREVIEW:
  683. // if wParam, enable preview via drawdib
  684. if (!lpcs->fHardwareConnected)
  685. return FALSE;
  686. if (wParam) {
  687. // turn off the overlay, if it is in use
  688. if (lpcs-> fOverlayWindow)
  689. SendMessage(lpcs->hwnd, WM_CAP_SET_OVERLAY, 0, 0L);
  690. lpcs->fLiveWindow = TRUE;
  691. statusUpdateStatus(lpcs, IDS_CAP_STAT_LIVE_MODE);
  692. } // endif enabling preview
  693. else {
  694. lpcs->fLiveWindow = FALSE;
  695. }
  696. InvalidateRect (lpcs->hwnd, NULL, TRUE);
  697. return TRUE;
  698. case WM_CAP_SET_OVERLAY:
  699. // if wParam, enable overlay in hardware
  700. if (!lpcs->fHardwareConnected)
  701. return FALSE;
  702. if (wParam && lpcs->sCapDrvCaps.fHasOverlay) {
  703. if (lpcs-> fLiveWindow) // turn off preview mode
  704. SendMessage(lpcs->hwnd, WM_CAP_SET_PREVIEW, 0, 0L);
  705. lpcs->fOverlayWindow = TRUE;
  706. statusUpdateStatus(lpcs, IDS_CAP_STAT_OVERLAY_MODE);
  707. }
  708. else {
  709. lpcs->fOverlayWindow = FALSE;
  710. videoStreamFini (lpcs->hVideoDisplay); // disable overlay on hardware
  711. }
  712. InvalidateRect (lpcs->hwnd, NULL, TRUE);
  713. return (lpcs->sCapDrvCaps.fHasOverlay);
  714. case WM_CAP_SET_PREVIEWRATE:
  715. // wParam contains preview update rate in mS.
  716. // if wParam == 0 no timer is in use.
  717. if (lpcs->idTimer) {
  718. KillTimer(lpcs->hwnd, ID_PREVIEWTIMER);
  719. lpcs->idTimer = NULL;
  720. }
  721. if (wParam != 0) {
  722. lpcs->idTimer = SetTimer (lpcs->hwnd, ID_PREVIEWTIMER,
  723. (UINT) wParam, NULL);
  724. }
  725. lpcs->uTimeout = (UINT) wParam;
  726. dwReturn = TRUE;
  727. break;
  728. case WM_CAP_GRAB_FRAME:
  729. // grab a single frame
  730. // wParam and lParam unused
  731. if (!lpcs->fHardwareConnected)
  732. return FALSE;
  733. if (lpcs->sCapDrvCaps.fCaptureInitialized) {
  734. dwReturn = (DWORD) GetAFrameThenCallback (lpcs, TRUE /*fForce*/);
  735. // disable live and overlay mode when capturing a single frame
  736. if (lpcs->fLiveWindow)
  737. SendMessage(lpcs->hwnd, WM_CAP_SET_PREVIEW, 0, 0L);
  738. else if (lpcs->fOverlayWindow)
  739. SendMessage(lpcs->hwnd, WM_CAP_SET_OVERLAY, 0, 0L);
  740. }
  741. break;
  742. case WM_CAP_GRAB_FRAME_NOSTOP:
  743. // grab a single frame, but don't change state of overlay/preview
  744. // wParam and lParam unused
  745. if (!lpcs->fHardwareConnected)
  746. return FALSE;
  747. dwReturn = (LONG) GetAFrameThenCallback (lpcs, TRUE /*fForce*/);
  748. break;
  749. case WM_CAP_SEQUENCE:
  750. // This is the main entry for streaming video capture
  751. // wParam is unused
  752. // lParam is unused
  753. if (!lpcs->fHardwareConnected)
  754. return FALSE;
  755. if (lpcs->sCapDrvCaps.fCaptureInitialized) {
  756. lpcs-> fCapturingToDisk = TRUE;
  757. return (AVICapture(lpcs));
  758. }
  759. break;
  760. case WM_CAP_SEQUENCE_NOFILE:
  761. // wParam is unused
  762. // lParam is unused
  763. if (!lpcs->fHardwareConnected)
  764. return FALSE;
  765. if (lpcs->sCapDrvCaps.fCaptureInitialized) {
  766. lpcs-> fCapturingToDisk = FALSE;
  767. return (AVICapture(lpcs));
  768. }
  769. break;
  770. case WM_CAP_SET_SEQUENCE_SETUP:
  771. // wParam is sizeof CAPTUREPARMS
  772. // lParam = LPCAPTUREPARMS
  773. // The following were added after the Beta, init in case the client
  774. // has a smaller structure and doesn't access them.
  775. lpcs->sCapParms.dwAudioBufferSize = 0;
  776. lpcs->sCapParms.fDisableWriteCache = TRUE;
  777. if (wParam <= sizeof (CAPTUREPARMS)) {
  778. dwT = min (sizeof (CAPTUREPARMS), wParam);
  779. if (IsBadReadPtr ((LPVOID) lParam, (UINT) dwT))
  780. break;
  781. _fmemcpy ((LPVOID) &lpcs->sCapParms, (LPVOID) lParam, (WORD) dwT);
  782. // Validate stuff that isn't handled elsewhere
  783. if (lpcs->sCapParms.wChunkGranularity < 16)
  784. lpcs->sCapParms.wChunkGranularity = 16;
  785. if (lpcs->sCapParms.wChunkGranularity > 16384)
  786. lpcs->sCapParms.wChunkGranularity = 16384;
  787. if (lpcs->sCapParms.fLimitEnabled && (lpcs->sCapParms.wTimeLimit == 0))
  788. lpcs->sCapParms.wTimeLimit = 1;
  789. // Force Step MCI off if not using MCI control
  790. if (lpcs->sCapParms.fStepMCIDevice && !lpcs->sCapParms.fMCIControl)
  791. lpcs->sCapParms.fStepMCIDevice = FALSE;
  792. // Prevent audio capture if no audio hardware
  793. lpcs-> sCapParms.fCaptureAudio =
  794. lpcs-> fAudioHardware && lpcs-> sCapParms.fCaptureAudio;
  795. // Limit audio buffers
  796. lpcs-> sCapParms.wNumAudioRequested =
  797. min (MAX_WAVE_BUFFERS, lpcs->sCapParms.wNumAudioRequested);
  798. // Limit video buffers
  799. lpcs-> sCapParms.wNumVideoRequested =
  800. min (MAX_VIDEO_BUFFERS, lpcs->sCapParms.wNumVideoRequested);
  801. dwReturn = TRUE;
  802. }
  803. break;
  804. case WM_CAP_SET_MCI_DEVICE:
  805. // lParam points to the name of the capture file
  806. if (IsBadReadPtr ((LPVOID) lParam, 1))
  807. return FALSE;
  808. if (lParam) {
  809. lstrcpyn (lpcs->achMCIDevice, (LPSTR) lParam, sizeof (lpcs->achMCIDevice));
  810. dwReturn = TRUE;
  811. }
  812. break;
  813. case WM_CAP_SET_SCROLL:
  814. // lParam is an LPPOINT which contains the new scroll position
  815. if (!lpcs->fHardwareConnected)
  816. return FALSE;
  817. if (IsBadReadPtr ((LPVOID) lParam, sizeof (POINT)))
  818. return FALSE;
  819. {
  820. LPPOINT lpP = (LPPOINT) lParam;
  821. if (lpP->x < lpcs-> dxBits && lpP->y < lpcs-> dyBits) {
  822. lpcs->ptScroll = *lpP;
  823. InvalidateRect (lpcs->hwnd, NULL, TRUE);
  824. dwReturn = TRUE;
  825. }
  826. }
  827. break;
  828. case WM_CAP_SET_SCALE:
  829. // if wParam, Scale the window to the client region?
  830. if (!lpcs->fHardwareConnected)
  831. return FALSE;
  832. lpcs->fScale = (BOOL) wParam;
  833. return TRUE;
  834. case WM_CAP_PAL_OPEN:
  835. // Open a new palette
  836. // wParam is unused
  837. // lParam contains an LPSTR to the file
  838. if (!lpcs->fHardwareConnected)
  839. return FALSE;
  840. if (IsBadReadPtr ((LPVOID) lParam, 1))
  841. return FALSE;
  842. return fileOpenPalette(lpcs, (LPSTR) lParam /*lpszFileName*/);
  843. case WM_CAP_PAL_SAVE:
  844. // Save the current palette in a file
  845. // wParam is unused
  846. // lParam contains an LPSTR to the file
  847. if (!lpcs->fHardwareConnected)
  848. return FALSE;
  849. if (IsBadReadPtr ((LPVOID) lParam, 1))
  850. return FALSE;
  851. return fileSavePalette(lpcs, (LPSTR) lParam /*lpszFileName*/);
  852. case WM_CAP_PAL_AUTOCREATE:
  853. // Automatically capture a palette
  854. // wParam contains a count of the number of frames to average
  855. // lParam contains the number of colors desired in the palette
  856. if (!lpcs->fHardwareConnected)
  857. return FALSE;
  858. return CapturePaletteAuto (lpcs, (int) wParam, (int) lParam);
  859. case WM_CAP_PAL_MANUALCREATE:
  860. // Manually capture a palette
  861. // wParam contains TRUE for each frame to capture, FALSE when done
  862. // lParam contains the number of colors desired in the palette
  863. if (!lpcs->fHardwareConnected)
  864. return FALSE;
  865. return CapturePaletteManual (lpcs, (BOOL) wParam, (int) lParam);
  866. case WM_CAP_PAL_PASTE:
  867. // Paste a palette from the clipboard, send to the driver
  868. if (!lpcs->fHardwareConnected)
  869. return FALSE;
  870. if (lpcs->sCapDrvCaps.fCaptureInitialized && OpenClipboard(lpcs->hwnd)) {
  871. HANDLE hPal;
  872. hPal = GetClipboardData(CF_PALETTE);
  873. CloseClipboard();
  874. if (hPal) {
  875. PalSendPaletteToDriver (lpcs, CopyPalette(hPal), NULL /* XlateTable */);
  876. InvalidateRect(lpcs->hwnd, NULL, TRUE);
  877. dwReturn = TRUE;
  878. }
  879. }
  880. break;
  881. default:
  882. break;
  883. }
  884. return dwReturn;
  885. }
  886. /*--------------------------------------------------------------+
  887. | ****************** THE WINDOW PROCEDURE ********************* |
  888. +--------------------------------------------------------------*/
  889. LONG FAR PASCAL _export _loadds CapWndProc (HWND hwnd, unsigned msg, WORD wParam, LONG lParam)
  890. {
  891. LPCAPSTREAM lpcs;
  892. PAINTSTRUCT ps;
  893. HDC hdc;
  894. int f;
  895. MSG PMsg;
  896. lpcs = (LPCAPSTREAM) GetWindowLong (hwnd, GWL_CAPSTREAM);
  897. if (msg >= WM_CAP_START && msg <= WM_CAP_END)
  898. return (ProcessCommandMessages (lpcs, msg, wParam, lParam));
  899. switch (msg) {
  900. case WM_CREATE:
  901. lpcs = CapWinCreate (hwnd);
  902. break;
  903. case WM_TIMER:
  904. // Update the preview window if we got a timer and not saving to disk
  905. GetAFrameThenCallback (lpcs, FALSE /*fForce*/);
  906. // Added VFW 1.1b, Clear the queue of additional timer msgs???
  907. // Trying to correct "Hit OK to continue" dialog not appearing bug
  908. // due to app message queue continuously being full at large
  909. // image dimensions.
  910. PeekMessage (&PMsg, hwnd, WM_TIMER, WM_TIMER,PM_REMOVE|PM_NOYIELD);
  911. break;
  912. case WM_CLOSE:
  913. break;
  914. case WM_DESTROY:
  915. CapWinDestroy (lpcs);
  916. break;
  917. case WM_PALETTECHANGED:
  918. if (lpcs->hdd == NULL)
  919. break;
  920. hdc = GetDC(hwnd);
  921. if (f = DrawDibRealize(lpcs->hdd, hdc, TRUE /*fBackground*/))
  922. InvalidateRect(hwnd,NULL,TRUE);
  923. ReleaseDC(hwnd,hdc);
  924. return f;
  925. case WM_QUERYNEWPALETTE:
  926. if (lpcs->hdd == NULL)
  927. break;
  928. hdc = GetDC(hwnd);
  929. f = DrawDibRealize(lpcs->hdd, hdc, FALSE);
  930. ReleaseDC(hwnd, hdc);
  931. if (f)
  932. InvalidateRect(hwnd, NULL, TRUE);
  933. return f;
  934. case WM_SIZE:
  935. case WM_MOVE:
  936. if (lpcs->fOverlayWindow) // Make the driver paint the key color
  937. InvalidateRect(hwnd, NULL, TRUE);
  938. break;
  939. case WM_WINDOWPOSCHANGED:
  940. if (lpcs->fOverlayWindow) // Make the driver paint the key color
  941. InvalidateRect(hwnd, NULL, TRUE);
  942. return 0;
  943. case WM_ERASEBKGND:
  944. return 0; // don't bother to erase it
  945. case WM_PAINT:
  946. hdc = BeginPaint(hwnd, &ps);
  947. if (lpcs->fOverlayWindow) {
  948. CheckWindowMove(lpcs, ps.hdc, TRUE);
  949. }
  950. else {
  951. SetWindowOrg(hdc, lpcs->ptScroll.x, lpcs->ptScroll.y);
  952. DibPaint(lpcs, hdc);
  953. }
  954. EndPaint(hwnd, &ps);
  955. break;
  956. default:
  957. break;
  958. }
  959. return DefWindowProc(hwnd, msg, wParam, lParam);
  960. }
  961. #if 0
  962. void dummyTest ()
  963. {
  964. HWND hwnd;
  965. FARPROC fpProc;
  966. DWORD dwSize;
  967. WORD wSize;
  968. BOOL f;
  969. int i;
  970. char szName[80];
  971. char szVer[80];
  972. DWORD dwMS;
  973. int iFrames, iColors;
  974. char s;
  975. LPPOINT lpP;
  976. capSetCallbackOnError(hwnd, fpProc);
  977. capSetCallbackOnStatus(hwnd, fpProc);
  978. capSetCallbackOnYield(hwnd, fpProc);
  979. capSetCallbackOnFrame(hwnd, fpProc);
  980. capSetCallbackOnVideoStream(hwnd, fpProc);
  981. capSetCallbackOnWaveStream(hwnd, fpProc);
  982. capDriverConnect(hwnd, i);
  983. capDriverDisconnect(hwnd);
  984. capDriverGetName(hwnd, szName, wSize);
  985. capDriverGetVersion(hwnd, szVer, wSize);
  986. capDriverGetCaps(hwnd, s, wSize);
  987. capFileSetCaptureFile(hwnd, szName);
  988. capFileGetCaptureFile(hwnd, szName, wSize);
  989. capFileAlloc(hwnd, dwSize);
  990. capFileSaveAs(hwnd, szName);
  991. capEditCopy(hwnd);
  992. capSetAudioFormat(hwnd, s, wSize);
  993. capGetAudioFormat(hwnd, s, wSize);
  994. capGetAudioFormatSize(hwnd);
  995. capDlgVideoFormat(hwnd);
  996. capDlgVideoSource(hwnd);
  997. capDlgVideoDisplay(hwnd);
  998. capPreview(hwnd, f);
  999. capPreviewRate(hwnd, dwMS);
  1000. capOverlay(hwnd, f);
  1001. capPreviewScale(hwnd, f);
  1002. capGetStatus(hwnd, s, wSize);
  1003. capSetScrollPos(hwnd, lpP);
  1004. capGrabFrame(hwnd);
  1005. capGrabFrameNoStop(hwnd);
  1006. capCaptureSequence(hwnd);
  1007. capCaptureSequenceNoFile(hwnd);
  1008. capCaptureGetSetup(hwnd, s, wSize);
  1009. capCaptureSetSetup(hwnd, s, wSize);
  1010. capCaptureSingleFrameOpen(hwnd);
  1011. capCaptureSingleFrameClose(hwnd);
  1012. capCaptureSingleFrame(hwnd);
  1013. capSetMCIDeviceName(hwnd, szName);
  1014. capGetMCIDeviceName(hwnd, szName, wSize);
  1015. capPalettePaste(hwnd);
  1016. capPaletteAuto(hwnd, iFrames, iColors);
  1017. }
  1018. #endif
  1019. 
  1020. 
  1021.