Source code of Windows XP (NT5)
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.

1858 lines
56 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 - 1995 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. #define INC_OLE2
  19. #pragma warning(disable:4103)
  20. #include <windows.h>
  21. #include <windowsx.h>
  22. #include <win32.h>
  23. #include <mmsystem.h>
  24. #include <msvideo.h>
  25. #include <drawdib.h>
  26. #include <mmreg.h>
  27. #include <memory.h>
  28. #include "ivideo32.h"
  29. #include "avicap.h"
  30. #include "avicapi.h"
  31. #include "cappal.h"
  32. #include "capdib.h"
  33. #include "dibmap.h"
  34. #ifdef UNICODE
  35. #include <stdlib.h>
  36. #endif
  37. // GetWindowLong assignments
  38. #define GWL_CAPSTREAM 0
  39. #define GWL_CAPVBSTATUS 4 // Used by VB Status callback
  40. #define GWL_CAPVBERROR 8 // Used by VB Error callback
  41. #define GWL_CAP_SPARE1 12 // Room to grow
  42. #define GWL_CAP_SPARE2 16 // Room to grow
  43. #define ID_PREVIEWTIMER 9
  44. //#ifdef _DEBUG
  45. #ifdef PLASTIQUE
  46. #define MB(lpsz) MessageBoxA(NULL, lpsz, "", MB_OK);
  47. #else
  48. #define MB(lpsz)
  49. #endif
  50. // #if defined _WIN32 && defined CHICAGO
  51. #if defined NO_LONGER_USED
  52. #include <mmdevldr.h>
  53. #include <vmm.h>
  54. #include "mmdebug.h"
  55. #pragma message (SQUAWK "move these defines later")
  56. #define MMDEVLDR_IOCTL_PAGEALLOCATE 7
  57. #define MMDEVLDR_IOCTL_PAGEFREE 8
  58. #define PageContig 0x00000004
  59. #define PageFixed 0x00000008
  60. //end
  61. HANDLE hMMDevLdr = NULL;
  62. /*****************************************************************************
  63. @doc INTERNAL
  64. @function HANDLE | OpenMMDEVLDR | Open a file handle to the MMDEVLDR VxD
  65. in order to access the DeviceIoControl functions.
  66. @rdesc opens a shared handle to MMDEVLDR
  67. *****************************************************************************/
  68. VOID WINAPI OpenMMDEVLDR(
  69. void)
  70. {
  71. AuxDebugEx (5, DEBUGLINE "OpenMMDEVLDR()r\n");
  72. if (hMMDevLdr)
  73. return;
  74. hMMDevLdr = CreateFile(
  75. "\\\\.\\MMDEVLDR.VXD", // magic name to attach to an already loaded vxd
  76. GENERIC_WRITE,
  77. FILE_SHARE_WRITE,
  78. NULL,
  79. OPEN_ALWAYS,
  80. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_GLOBAL_HANDLE,
  81. NULL);
  82. AuxDebugEx (5, DEBUGLINE "OpenMMDEVLDR returns %08Xr\n", hMMDevLdr);
  83. return;
  84. }
  85. VOID WINAPI CloseMMDEVLDR(
  86. void)
  87. {
  88. if (! hMMDevLdr)
  89. return;
  90. CloseHandle (hMMDevLdr);
  91. hMMDevLdr = NULL;
  92. }
  93. /*****************************************************************************
  94. @doc INTERNAL
  95. @function DWORD | LinPageLock | Call the VMM service LinPageLock via
  96. DeviceIoControl through MMDEVLDR.
  97. @parm DWORD | dwStartPage | Starting page of the linear region to lock.
  98. @parm DWORD | dwPageCount | Number of 4K pages to lock.
  99. @parm DWORD | fdwLinPageLock | Flags expected by the VMM service.
  100. @flag PAGEMAPGLOBAL | Return an alias to the locked region which
  101. is valid in all process contexts.
  102. @rdesc Meaningless unless PAGEMAPGLOBAL specified. If it was, then the
  103. return value is the alias pointer to the start of the linear region
  104. (NOTE: A *POINTER*, NOT a page address). The pointer will be page
  105. aligned (i.e. the low 12 bits will be zero.)
  106. *****************************************************************************/
  107. DWORD WINAPI LinPageLock(
  108. DWORD dwStartPage,
  109. DWORD dwPageCount,
  110. DWORD fdwLinPageLock)
  111. {
  112. LOCKUNLOCKPARMS lup;
  113. DWORD dwRet;
  114. DWORD cbRet;
  115. AuxDebugEx (6, DEBUGLINE "LinPageLock(%08x,%08x,%08x)\r\n",
  116. dwStartPage, dwPageCount, fdwLinPageLock);
  117. assert (hMMDevLdr != NULL);
  118. if (INVALID_HANDLE_VALUE == hMMDevLdr)
  119. return 0;
  120. lup.dwStartPage = dwStartPage;
  121. lup.dwPageCount = dwPageCount;
  122. lup.fdwOperation= fdwLinPageLock;
  123. if ( ! DeviceIoControl (hMMDevLdr,
  124. MMDEVLDR_IOCTL_LINPAGELOCK,
  125. &lup,
  126. sizeof(lup),
  127. &dwRet,
  128. sizeof(dwRet),
  129. &cbRet,
  130. NULL))
  131. {
  132. AuxDebug("LinPageLock failed!!!");
  133. dwRet = 0;
  134. }
  135. return dwRet;
  136. }
  137. /*****************************************************************************
  138. @doc INTERNAL
  139. @function DWORD | LinPageUnLock | Call the VMM service LinPageUnLock via
  140. DeviceIoControl through MMDEVLDR.
  141. @parm DWORD | dwStartPage | Starting page of the linear region to unlock.
  142. @parm DWORD | dwPageCount | Number of 4K pages to lock.
  143. @parm DWORD | fdwLinPageLock | Flags expected by the VMM service.
  144. @flag PAGEMAPGLOBAL | Return an alias to the locked region which
  145. is valid in all process contexts.
  146. @comm
  147. If PAGEMAPGLOBAL was specified on the <f LinPageLock> call, it must
  148. also be specified here. In this case, <p dwStartPage> should be the
  149. page address of the returned alias pointer in global memory.
  150. *****************************************************************************/
  151. void WINAPI LinPageUnLock(
  152. DWORD dwStartPage,
  153. DWORD dwPageCount,
  154. DWORD fdwLinPageLock)
  155. {
  156. LOCKUNLOCKPARMS lup;
  157. AuxDebugEx (6, DEBUGLINE "LinPageUnLock (%08x,%08x,%08x)\r\n",
  158. dwStartPage, dwPageCount, fdwLinPageLock);
  159. assert (hMMDevLdr != NULL);
  160. assert (INVALID_HANDLE_VALUE != hMMDevLdr);
  161. if (INVALID_HANDLE_VALUE == hMMDevLdr)
  162. return;
  163. lup.dwStartPage = dwStartPage;
  164. lup.dwPageCount = dwPageCount;
  165. lup.fdwOperation = fdwLinPageLock;
  166. DeviceIoControl (hMMDevLdr,
  167. MMDEVLDR_IOCTL_LINPAGEUNLOCK,
  168. &lup,
  169. sizeof(lup),
  170. NULL,
  171. 0,
  172. NULL,
  173. NULL);
  174. }
  175. /*+ FreeContigMem
  176. *
  177. *-==================================================================*/
  178. VOID FreeContigMem (
  179. DWORD hMemContig)
  180. {
  181. DWORD dwRet;
  182. DWORD cbRet;
  183. assert (hMMDevLdr != NULL);
  184. assert (INVALID_HANDLE_VALUE != hMMDevLdr);
  185. if (INVALID_HANDLE_VALUE == hMMDevLdr)
  186. return;
  187. DeviceIoControl (hMMDevLdr,
  188. MMDEVLDR_IOCTL_PAGEFREE,
  189. &hMemContig,
  190. sizeof(hMemContig),
  191. &dwRet,
  192. sizeof(dwRet),
  193. &cbRet,
  194. NULL);
  195. }
  196. /*+ AllocContigMem
  197. *
  198. *-==================================================================*/
  199. LPVOID AllocContigMem (
  200. DWORD cbSize,
  201. LPDWORD phMemContig)
  202. {
  203. struct _memparms {
  204. DWORD flags;
  205. DWORD nPages;
  206. } mp;
  207. struct _memret {
  208. LPVOID lpv;
  209. DWORD hMem;
  210. DWORD nPages;
  211. DWORD dwPhys;
  212. } mr;
  213. DWORD cbRet;
  214. mr.lpv = NULL;
  215. *phMemContig = 0;
  216. mp.nPages = (cbSize + 4095) >> 12;
  217. mp.flags = PageContig+PageFixed;
  218. AuxDebugEx (2, DEBUGLINE "Contig allocate %08X pages\r\n", mp.nPages);
  219. assert (hMMDevLdr != NULL);
  220. assert (INVALID_HANDLE_VALUE != hMMDevLdr);
  221. if (INVALID_HANDLE_VALUE == hMMDevLdr)
  222. return NULL;
  223. if ( ! DeviceIoControl (hMMDevLdr,
  224. MMDEVLDR_IOCTL_PAGEALLOCATE,
  225. &mp,
  226. sizeof(mp),
  227. &mr,
  228. sizeof(mr),
  229. &cbRet,
  230. NULL))
  231. {
  232. AuxDebugEx(0, "Contig Allocate failed!!!\r\n");
  233. mr.lpv = NULL;
  234. mr.hMem = 0;
  235. mr.nPages = 0;
  236. mr.dwPhys = 0;
  237. }
  238. *phMemContig = mr.hMem;
  239. AuxDebugEx(2, "Contig Allocate returns %08X\r\n", mr.lpv);
  240. return mr.lpv;
  241. }
  242. /*+
  243. *
  244. *-================================================================*/
  245. PVOID WINAPI CreateGlobalAlias (
  246. PVOID pOriginal,
  247. DWORD cbOriginal,
  248. LPDWORD pnPages)
  249. {
  250. DWORD dwStartPage;
  251. DWORD dwPageCount;
  252. DWORD dwPageOffset;
  253. DWORD dwAliasBase;
  254. PVOID pAlias;
  255. AuxDebugEx (6, DEBUGLINE "CreateGlobalAlias(%08X,%08X,..)\r\n",
  256. pOriginal, cbOriginal);
  257. dwStartPage = ((DWORD)pOriginal) >> 12;
  258. dwPageOffset = ((DWORD)pOriginal) & ((1 << 12)-1);
  259. dwPageCount = ((((DWORD)pOriginal) + cbOriginal - 1) >> 12) - dwStartPage + 1;
  260. *pnPages = 0;
  261. dwAliasBase = LinPageLock (dwStartPage, dwPageCount, PAGEMAPGLOBAL);
  262. if ( ! dwAliasBase)
  263. return NULL;
  264. pAlias = (PVOID)(dwAliasBase + dwPageOffset);
  265. *pnPages = dwPageCount;
  266. AuxDebugEx (6, DEBUGLINE "CreateGlobalAlias returns %08X nPages %d\r\n", pAlias, dwPageCount);
  267. return pAlias;
  268. }
  269. /*+
  270. *
  271. *-================================================================*/
  272. VOID WINAPI FreeGlobalAlias(
  273. PVOID pAlias,
  274. DWORD nPages)
  275. {
  276. AuxDebugEx (6, DEBUGLINE "FreeGlobalAlias(%08X,%08X)\r\n", pAlias, nPages);
  277. LinPageUnLock (((DWORD)pAlias) >> 12, nPages, PAGEMAPGLOBAL);
  278. }
  279. #endif
  280. #if defined _WIN32 && defined CHICAGO
  281. /*+ videoFrame
  282. *
  283. *-================================================================*/
  284. DWORD WINAPI videoFrame (
  285. HVIDEO hVideo,
  286. LPVIDEOHDR lpVHdr)
  287. {
  288. return vidxFrame (hVideo, lpVHdr);
  289. }
  290. #endif
  291. //
  292. // Set the overlay rectangles on capture cards which support
  293. // overlay, and then enable/disable the key color.
  294. //
  295. static void SetOverlayRectangles (LPCAPSTREAM lpcs)
  296. {
  297. HDC hdc;
  298. BOOL fVisible;
  299. RECT rc;
  300. if (!lpcs->hVideoDisplay)
  301. return;
  302. hdc = GetDC (lpcs->hwnd);
  303. fVisible = (GetClipBox (hdc, &rc) != NULLREGION);
  304. ReleaseDC (lpcs->hwnd, hdc);
  305. if (!fVisible) // disable the overlay if iconic
  306. videoStreamFini (lpcs->hVideoDisplay);
  307. else {
  308. // Destination
  309. GetClientRect (lpcs->hwnd, &rc);
  310. ClientToScreen (lpcs->hwnd, (LPPOINT)&rc);
  311. ClientToScreen (lpcs->hwnd, (LPPOINT)&rc+1);
  312. videoSetRect (lpcs->hVideoDisplay, DVM_DST_RECT, rc);
  313. // Overlay channel Source rectangle
  314. SetRect (&rc, lpcs->ptScroll.x, lpcs->ptScroll.y,
  315. lpcs->ptScroll.x + rc.right - rc.left,
  316. lpcs->ptScroll.y + rc.bottom - rc.top);
  317. videoSetRect (lpcs->hVideoDisplay, DVM_SRC_RECT, rc);
  318. videoStreamInit (lpcs->hVideoDisplay, 0L, 0L, 0L, 0L);
  319. }
  320. }
  321. // WM_POSITIONCHANGED and WM_POSITIONCHANGING don't do enough to
  322. // handle clipping of the overlay window on the Intel board,
  323. // which keys on black. Do this routine on WM_PAINT and
  324. // WM_ENTERIDLE messages.
  325. void CheckWindowMove(LPCAPSTREAM lpcs, HDC hdcWnd, BOOL fForce)
  326. {
  327. UINT wRgn;
  328. RECT rc;
  329. #ifdef _WIN32
  330. POINT ptOrg;
  331. #else
  332. DWORD dwOrg;
  333. #endif
  334. HDC hdc;
  335. BOOL f;
  336. if (!lpcs->hwnd || !lpcs->hVideoDisplay || !lpcs->fOverlayWindow)
  337. return;
  338. //
  339. // when the screen is locked for update by a window move operation
  340. // we dont want to turn off the video.
  341. //
  342. // we can tell if the screen is locked by checking a DC to the screen.
  343. //
  344. hdc = GetDC(NULL);
  345. f = GetClipBox(hdc, &rc) == NULLREGION;
  346. ReleaseDC(NULL, hdc);
  347. if (f) {
  348. lpcs->uiRegion = (UINT) -1;
  349. return;
  350. }
  351. if (fForce)
  352. lpcs->uiRegion = (UINT) -1;
  353. hdc = GetDC (lpcs->hwnd);
  354. wRgn = GetClipBox(hdc, &rc);
  355. #ifdef _WIN32
  356. GetDCOrgEx(hdc, &ptOrg);
  357. #else
  358. dwOrg = GetDCOrg(hdc);
  359. #endif
  360. ReleaseDC(lpcs->hwnd, hdc);
  361. if (wRgn == lpcs->uiRegion &&
  362. #ifdef _WIN32
  363. ptOrg.x == lpcs->ptRegionOrigin.x &&
  364. ptOrg.y == lpcs->ptRegionOrigin.y &&
  365. #else
  366. dwOrg == lpcs->dwRegionOrigin &&
  367. #endif
  368. EqualRect(&rc, &lpcs->rcRegionRect))
  369. return;
  370. lpcs->uiRegion = wRgn;
  371. #ifdef _WIN32
  372. lpcs->ptRegionOrigin = ptOrg;
  373. #else
  374. lpcs->dwRegionOrigin = dwOrg;
  375. #endif
  376. lpcs->rcRegionRect = rc;
  377. SetOverlayRectangles (lpcs);
  378. if (hdcWnd)
  379. videoUpdate (lpcs->hVideoDisplay, lpcs->hwnd, hdcWnd);
  380. else
  381. InvalidateRect (lpcs->hwnd, NULL, TRUE);
  382. }
  383. //
  384. // Create our little world
  385. //
  386. LPCAPSTREAM CapWinCreate (HWND hwnd)
  387. {
  388. LPCAPSTREAM lpcs;
  389. WAVEFORMATEX wfex;
  390. if (!(lpcs = (LPCAPSTREAM) GlobalAllocPtr (GHND, sizeof (CAPSTREAM))))
  391. return NULL;
  392. SetWindowLong (hwnd, GWL_CAPSTREAM, (LONG)lpcs);
  393. lpcs->dwSize = sizeof (CAPSTREAM);
  394. lpcs->uiVersion = CAPSTREAM_VERSION;
  395. lpcs->hwnd = hwnd;
  396. lpcs->hInst = ghInstDll;
  397. lpcs->hWaitCursor = LoadCursor(NULL, IDC_WAIT);
  398. lpcs->hdd = DrawDibOpen();
  399. lpcs->fAudioHardware = !!waveOutGetNumDevs(); // force 1 or 0
  400. // Video defaults
  401. lpcs->sCapParms.dwRequestMicroSecPerFrame = 66667; // 15fps
  402. lpcs->sCapParms.vKeyAbort = VK_ESCAPE;
  403. lpcs->sCapParms.fAbortLeftMouse = TRUE;
  404. lpcs->sCapParms.fAbortRightMouse = TRUE;
  405. lpcs->sCapParms.wNumVideoRequested = MIN_VIDEO_BUFFERS;
  406. lpcs->sCapParms.wPercentDropForError = 10; // error msg if dropped > 10%
  407. lpcs->sCapParms.wChunkGranularity = 0;
  408. lpcs->fCaptureFlags |= CAP_fCapturingToDisk;
  409. // Audio defaults to 11K, 8bit, Mono
  410. lpcs->sCapParms.fCaptureAudio = lpcs->fAudioHardware;
  411. lpcs->sCapParms.wNumAudioRequested = DEF_WAVE_BUFFERS;
  412. wfex.wFormatTag = WAVE_FORMAT_PCM;
  413. wfex.nChannels = 1;
  414. wfex.nSamplesPerSec = 11025;
  415. wfex.nAvgBytesPerSec = 11025;
  416. wfex.nBlockAlign = 1;
  417. wfex.wBitsPerSample = 8;
  418. wfex.cbSize = 0;
  419. SendMessage (hwnd, WM_CAP_SET_AUDIOFORMAT, 0, (LONG)(LPVOID)&wfex);
  420. // Palette defaults
  421. lpcs->nPaletteColors = 256;
  422. // Capture defaults
  423. lpcs->sCapParms.fUsingDOSMemory = FALSE;
  424. lstrcpy (lpcs->achFile, TEXT("C:\\CAPTURE.AVI")); // Default capture file
  425. lpcs->fCapFileExists = fileCapFileIsAVI (lpcs->achFile);
  426. // Allocate index to 32K frames plus proportionate number of audio chunks
  427. lpcs->sCapParms.dwIndexSize = (32768ul + (32768ul / 15));
  428. lpcs->sCapParms.fDisableWriteCache = FALSE;
  429. #ifdef NEW_COMPMAN
  430. // Init the COMPVARS structure
  431. lpcs->CompVars.cbSize = sizeof (COMPVARS);
  432. lpcs->CompVars.dwFlags = 0;
  433. #endif
  434. return lpcs;
  435. }
  436. //
  437. // Destroy our little world
  438. //
  439. void CapWinDestroy (LPCAPSTREAM lpcs)
  440. {
  441. // Uh, oh. Somebodys trying to kill us while capturing
  442. if (lpcs->fCaptureFlags & CAP_fCapturingNow) {
  443. if (lpcs->fCaptureFlags & CAP_fFrameCapturingNow) {
  444. // Single frame capture in progress
  445. SingleFrameCaptureClose (lpcs);
  446. }
  447. else {
  448. // Streaming capture in progress, OR
  449. // MCI step capture in progress
  450. lpcs->fCaptureFlags |= CAP_fAbortCapture;
  451. #ifdef _WIN32
  452. // wait for capture thread to go away
  453. // we must have a capture thread
  454. WinAssert(lpcs->hThreadCapture != 0);
  455. while (MsgWaitForMultipleObjects(1, &lpcs->hThreadCapture, FALSE,
  456. INFINITE, QS_SENDMESSAGE) != WAIT_OBJECT_0) {
  457. MSG msg;
  458. // just a single peekmessage with NOREMOVE will
  459. // process the inter-thread send and not affect the queue
  460. PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
  461. }
  462. CloseHandle(lpcs->hThreadCapture);
  463. lpcs->hThreadCapture = 0;
  464. // it should have stopped capturing
  465. WinAssert(!(lpcs->fCaptureFlags & CAP_fCapturingNow));
  466. #else
  467. while (lpcs->fCapturingNow)
  468. Yield ();
  469. #endif
  470. }
  471. }
  472. if (lpcs->idTimer)
  473. KillTimer(lpcs->hwnd, lpcs->idTimer);
  474. PalFini (lpcs);
  475. DibFini (lpcs);
  476. CapWinDisconnectHardware (lpcs);
  477. DrawDibClose (lpcs->hdd);
  478. if (lpcs->lpWaveFormat)
  479. GlobalFreePtr (lpcs->lpWaveFormat);
  480. #ifdef NEW_COMPMAN
  481. if (lpcs->CompVars.hic)
  482. ICCompressorFree(&lpcs->CompVars);
  483. #endif
  484. if (lpcs->lpInfoChunks)
  485. GlobalFreePtr(lpcs->lpInfoChunks);
  486. WinAssert (!lpcs->pAsync);
  487. GlobalFreePtr (lpcs); // Free the instance memory
  488. }
  489. UINT GetSizeOfWaveFormat (LPWAVEFORMATEX lpwf)
  490. {
  491. UINT wSize;
  492. if ((lpwf == NULL) || (lpwf->wFormatTag == WAVE_FORMAT_PCM))
  493. wSize = sizeof (PCMWAVEFORMAT);
  494. else
  495. wSize = sizeof (WAVEFORMATEX) + lpwf->cbSize;
  496. return wSize;
  497. }
  498. // Returns TRUE if we got a new frame, else FALSE
  499. // if fForce, then always get a new frame
  500. BOOL GetAFrameThenCallback (LPCAPSTREAM lpcs, BOOL fForce)
  501. {
  502. BOOL fOK = FALSE;
  503. static BOOL fRecursion = FALSE;
  504. BOOL fVisible;
  505. RECT rc;
  506. HDC hdc;
  507. if (fRecursion)
  508. return FALSE;
  509. if (!lpcs->sCapDrvCaps.fCaptureInitialized)
  510. return fOK;
  511. fRecursion = TRUE;
  512. // Update the preview window if we got a timer and not saving to disk
  513. if (lpcs->fOverlayWindow)
  514. CheckWindowMove(lpcs, NULL, FALSE);
  515. if ((!(lpcs->fCaptureFlags & CAP_fCapturingNow))
  516. || (lpcs->fCaptureFlags & CAP_fStepCapturingNow)
  517. || (lpcs->fCaptureFlags & CAP_fFrameCapturingNow)) {
  518. hdc = GetDC (lpcs->hwnd);
  519. fVisible = (GetClipBox (hdc, &rc) != NULLREGION);
  520. ReleaseDC (lpcs->hwnd, hdc);
  521. if (fForce || (fVisible && (lpcs->fLiveWindow || lpcs->CallbackOnVideoFrame))) {
  522. videoFrame (lpcs->hVideoIn, &lpcs->VidHdr);
  523. fOK = TRUE;
  524. if (lpcs->CallbackOnVideoFrame)
  525. lpcs->CallbackOnVideoFrame(lpcs->hwnd, &lpcs->VidHdr);
  526. if (fForce || lpcs->fLiveWindow) {
  527. InvalidateRect (lpcs->hwnd, NULL, TRUE);
  528. UpdateWindow (lpcs->hwnd);
  529. }
  530. } // if visible
  531. } // if we're not streaming
  532. fRecursion = FALSE;
  533. return fOK;
  534. }
  535. // Clear the Status and Error strings via callback
  536. __inline void FAR PASCAL ClearStatusAndError (LPCAPSTREAM lpcs)
  537. {
  538. statusUpdateStatus(lpcs, 0); // Clear status
  539. errorUpdateError(lpcs, 0); // Clear error
  540. }
  541. // Process class specific commands >= WM_USER
  542. DWORD PASCAL ProcessCommandMessages (LPCAPSTREAM lpcs, UINT msg, UINT wParam, LPARAM lParam)
  543. {
  544. DWORD dwReturn = 0L;
  545. DWORD dwT;
  546. switch (msg) {
  547. // Don't clear status and error on the following innocuous msgs
  548. case WM_CAP_GET_CAPSTREAMPTR:
  549. case WM_CAP_GET_USER_DATA:
  550. case WM_CAP_DRIVER_GET_NAME:
  551. case WM_CAP_DRIVER_GET_VERSION:
  552. case WM_CAP_DRIVER_GET_CAPS:
  553. case WM_CAP_GET_AUDIOFORMAT:
  554. case WM_CAP_GET_VIDEOFORMAT:
  555. case WM_CAP_GET_STATUS:
  556. case WM_CAP_SET_SEQUENCE_SETUP:
  557. case WM_CAP_GET_SEQUENCE_SETUP:
  558. case WM_CAP_GET_MCI_DEVICE:
  559. case WM_CAP_SET_PREVIEWRATE:
  560. case WM_CAP_SET_SCROLL:
  561. #ifdef UNICODE
  562. // ...or on the ansi thunks for these messages
  563. case WM_CAP_DRIVER_GET_NAMEA:
  564. case WM_CAP_DRIVER_GET_VERSIONA:
  565. case WM_CAP_GET_MCI_DEVICEA:
  566. #endif
  567. break;
  568. default:
  569. ClearStatusAndError (lpcs);
  570. break;
  571. }
  572. switch (msg) {
  573. case WM_CAP_GET_CAPSTREAMPTR:
  574. // return a pointer to the CAPSTREAM
  575. return (DWORD) (LPVOID) lpcs;
  576. case WM_CAP_GET_USER_DATA:
  577. return lpcs->lUser;
  578. // unicode and win-16 version - see ansi thunk below
  579. case WM_CAP_DRIVER_GET_NAME:
  580. // Return the name of the capture driver in use
  581. // wParam is the length of the buffer pointed to by lParam
  582. if (!lpcs->fHardwareConnected)
  583. return FALSE;
  584. return (capInternalGetDriverDesc (lpcs->sCapDrvCaps.wDeviceIndex,
  585. (LPTSTR) lParam, (int) wParam, NULL, 0));
  586. // unicode and win-16 version - see ansi thunk below
  587. case WM_CAP_DRIVER_GET_VERSION:
  588. // Return the version of the capture driver in use as text
  589. // wParam is the length of the buffer pointed to by lParam
  590. if (!lpcs->fHardwareConnected)
  591. return FALSE;
  592. return (capInternalGetDriverDesc (lpcs->sCapDrvCaps.wDeviceIndex,
  593. NULL, 0, (LPTSTR) lParam, (int) wParam));
  594. #ifdef UNICODE
  595. // ansi/unicode thunk versions of the above entrypoint
  596. case WM_CAP_DRIVER_GET_NAMEA:
  597. if (!lpcs->fHardwareConnected)
  598. return FALSE;
  599. return capInternalGetDriverDescA(lpcs->sCapDrvCaps.wDeviceIndex,
  600. (LPSTR) lParam, (int) wParam, NULL, 0);
  601. // ansi/unicode thunk versions of the above entrypoint
  602. case WM_CAP_DRIVER_GET_VERSIONA:
  603. if (!lpcs->fHardwareConnected)
  604. return FALSE;
  605. return capInternalGetDriverDescA(lpcs->sCapDrvCaps.wDeviceIndex,
  606. NULL, 0, (LPSTR) lParam, (int) wParam);
  607. #endif
  608. case WM_CAP_DRIVER_GET_CAPS:
  609. // wParam is the size of the CAPDRIVERCAPS struct
  610. // lParam points to a CAPDRIVERCAPS struct
  611. if (!lpcs->fHardwareConnected)
  612. return FALSE;
  613. if (wParam <= sizeof (CAPDRIVERCAPS) &&
  614. !IsBadWritePtr ((LPVOID) lParam, (UINT) wParam)) {
  615. dwT = min (wParam, sizeof (CAPDRIVERCAPS));
  616. _fmemcpy ((LPVOID) lParam, (LPVOID) &lpcs->sCapDrvCaps, (UINT) dwT);
  617. dwReturn = TRUE;
  618. }
  619. break;
  620. // unicode and win-16 version - see ansi thunk below
  621. case WM_CAP_FILE_GET_CAPTURE_FILE:
  622. // wParam is the size (in characters)
  623. // lParam points to a buffer in which capture file name is copied
  624. if (lParam) {
  625. lstrcpyn ((LPTSTR) lParam, lpcs->achFile, wParam);
  626. dwReturn = TRUE;
  627. }
  628. break;
  629. #ifdef UNICODE
  630. // ansi/unicode thunk
  631. case WM_CAP_FILE_GET_CAPTURE_FILEA:
  632. if (lParam) {
  633. Iwcstombs((LPSTR) lParam, lpcs->achFile, (int) wParam);
  634. dwReturn = TRUE;
  635. }
  636. break;
  637. #endif
  638. case WM_CAP_GET_AUDIOFORMAT:
  639. // if lParam == NULL, return the size
  640. // if lParam != NULL, wParam is the size, return bytes copied
  641. if (lpcs->lpWaveFormat == NULL)
  642. return FALSE;
  643. dwT = GetSizeOfWaveFormat ((LPWAVEFORMATEX) lpcs->lpWaveFormat);
  644. if (lParam == 0)
  645. return (dwT);
  646. else {
  647. if (wParam < (UINT) dwT)
  648. return FALSE;
  649. else {
  650. hmemcpy ((LPVOID) lParam, (LPVOID) lpcs->lpWaveFormat, dwT);
  651. dwReturn = dwT;
  652. }
  653. }
  654. break;
  655. // unicode and win-16 version - see ansi thunk below
  656. case WM_CAP_GET_MCI_DEVICE:
  657. // wParam is the size in characters
  658. // lParam points to a buffer in which MCI device name is copied
  659. if (lParam) {
  660. lstrcpyn ((LPTSTR) lParam, lpcs->achMCIDevice, wParam);
  661. dwReturn = TRUE;
  662. }
  663. break;
  664. #ifdef UNICODE
  665. // ansi thunk of above
  666. case WM_CAP_GET_MCI_DEVICEA:
  667. if (lParam) {
  668. Iwcstombs( (LPSTR) lParam, lpcs->achMCIDevice, (int) wParam);
  669. dwReturn = TRUE;
  670. }
  671. break;
  672. #endif
  673. case WM_CAP_GET_STATUS:
  674. // wParam is the size of the CAPSTATUS struct pointed to by lParam
  675. if (!lpcs->fHardwareConnected)
  676. return FALSE;
  677. if (IsBadWritePtr ((LPVOID) lParam, (UINT) wParam))
  678. return FALSE;
  679. if (wParam >= sizeof (CAPSTATUS)) {
  680. LPCAPSTATUS lpcc = (LPCAPSTATUS) lParam;
  681. lpcc->fLiveWindow = lpcs->fLiveWindow;
  682. lpcc->fOverlayWindow = lpcs->fOverlayWindow;
  683. lpcc->fScale = lpcs->fScale;
  684. lpcc->ptScroll = lpcs->ptScroll;
  685. lpcc->fUsingDefaultPalette = lpcs->fUsingDefaultPalette;
  686. lpcc->fCapFileExists = lpcs->fCapFileExists;
  687. lpcc->fAudioHardware = lpcs->fAudioHardware;
  688. lpcc->uiImageWidth = lpcs->dxBits;
  689. lpcc->uiImageHeight = lpcs->dyBits;
  690. // The following are updated dynamically during capture
  691. lpcc->dwCurrentVideoFrame = lpcs->dwVideoChunkCount;
  692. lpcc->dwCurrentVideoFramesDropped = lpcs->dwFramesDropped;
  693. if (lpcs->lpWaveFormat != NULL) {
  694. lpcc->dwCurrentWaveSamples =
  695. MulDiv (lpcs->dwWaveBytes,
  696. lpcs->lpWaveFormat->nSamplesPerSec,
  697. lpcs->lpWaveFormat->nAvgBytesPerSec);
  698. }
  699. lpcc->dwCurrentTimeElapsedMS = lpcs->dwTimeElapsedMS;
  700. // Added post alpha release
  701. if (lpcs->fCaptureFlags & CAP_fCapturingNow) {
  702. lpcc->fCapturingNow = TRUE;
  703. } else {
  704. lpcc->fCapturingNow = FALSE;
  705. }
  706. lpcc->hPalCurrent = lpcs->hPalCurrent;
  707. lpcc->dwReturn = lpcs->dwReturn;
  708. lpcc->wNumVideoAllocated = lpcs->iNumVideo;
  709. lpcc->wNumAudioAllocated = lpcs->iNumAudio;
  710. dwReturn = TRUE;
  711. }
  712. break;
  713. case WM_CAP_GET_SEQUENCE_SETUP:
  714. // wParam is sizeof CAPTUREPARMS
  715. // lParam = LPCAPTUREPARMS
  716. if (wParam <= sizeof (CAPTUREPARMS) &&
  717. !IsBadWritePtr ((LPVOID) lParam, (UINT) wParam)) {
  718. dwT = min (wParam, sizeof (CAPTUREPARMS));
  719. _fmemcpy ((LPVOID) lParam, (LPVOID) &lpcs->sCapParms, (UINT) dwT);
  720. dwReturn = TRUE;
  721. }
  722. break;
  723. case WM_CAP_STOP:
  724. // Stop capturing a sequence
  725. if (lpcs->fCaptureFlags & CAP_fCapturingNow) {
  726. lpcs->fCaptureFlags |= CAP_fStopCapture;
  727. dwReturn = TRUE;
  728. }
  729. break;
  730. case WM_CAP_ABORT:
  731. // Stop capturing a sequence
  732. if (lpcs->fCaptureFlags & CAP_fCapturingNow) {
  733. lpcs->fCaptureFlags |= CAP_fAbortCapture;
  734. dwReturn = TRUE;
  735. }
  736. break;
  737. case WM_CAP_GET_VIDEOFORMAT:
  738. // if lParam == NULL, return the size
  739. // if lParam != NULL, wParam is the size, return bytes copied
  740. if (!lpcs->fHardwareConnected)
  741. return FALSE;
  742. dwT = ((LPBITMAPINFOHEADER)lpcs->lpBitsInfo)->biSize +
  743. ((LPBITMAPINFOHEADER)lpcs->lpBitsInfo)->biClrUsed * sizeof(RGBQUAD);
  744. if (lParam == 0)
  745. return dwT;
  746. else {
  747. if (wParam < (UINT) dwT)
  748. return FALSE;
  749. else {
  750. hmemcpy ((LPVOID) lParam, (LPVOID) lpcs->lpBitsInfo, dwT);
  751. dwReturn = dwT;
  752. }
  753. }
  754. break;
  755. case WM_CAP_SINGLE_FRAME_OPEN:
  756. // wParam is not used
  757. // lParam is not used
  758. if (!lpcs->fHardwareConnected)
  759. return FALSE;
  760. return SingleFrameCaptureOpen (lpcs);
  761. case WM_CAP_SINGLE_FRAME_CLOSE:
  762. // wParam is not used
  763. // lParam is not used
  764. if (!lpcs->fHardwareConnected)
  765. return FALSE;
  766. return SingleFrameCaptureClose (lpcs);
  767. case WM_CAP_SINGLE_FRAME:
  768. // wParam is not used
  769. // lParam is not used
  770. if (!lpcs->fHardwareConnected)
  771. return FALSE;
  772. return SingleFrameCapture (lpcs);
  773. // unicode and win-16 version - see ansi thunk below
  774. case WM_CAP_SET_CALLBACK_STATUS:
  775. // Set the status callback proc
  776. if (lParam != 0 && IsBadCodePtr ((FARPROC) lParam))
  777. return FALSE;
  778. lpcs->CallbackOnStatus = (CAPSTATUSCALLBACK) lParam;
  779. lpcs->fLastStatusWasNULL = TRUE;
  780. #ifdef UNICODE
  781. lpcs->fUnicode &= ~VUNICODE_STATUSISANSI;
  782. #endif
  783. return TRUE;
  784. #ifdef UNICODE
  785. // ansi thunk for above
  786. case WM_CAP_SET_CALLBACK_STATUSA:
  787. // Set the status callback proc
  788. if (lParam != 0 && IsBadCodePtr ((FARPROC) lParam))
  789. return FALSE;
  790. lpcs->CallbackOnStatus = (CAPSTATUSCALLBACK) lParam;
  791. lpcs->fLastStatusWasNULL = TRUE;
  792. lpcs->fUnicode |= VUNICODE_STATUSISANSI;
  793. return TRUE;
  794. #endif
  795. // unicode and win-16 version - see ansi version below
  796. case WM_CAP_SET_CALLBACK_ERROR:
  797. // Set the error callback proc
  798. if (lParam != 0 && IsBadCodePtr ((FARPROC) lParam))
  799. return FALSE;
  800. lpcs->CallbackOnError = (CAPERRORCALLBACK) lParam;
  801. lpcs->fLastErrorWasNULL = TRUE;
  802. #ifdef UNICODE
  803. lpcs->fUnicode &= ~VUNICODE_ERRORISANSI;
  804. #endif
  805. return TRUE;
  806. #ifdef UNICODE
  807. // ansi version of above
  808. case WM_CAP_SET_CALLBACK_ERRORA:
  809. // Set the error callback proc
  810. if (lParam != 0 && IsBadCodePtr ((FARPROC) lParam))
  811. return FALSE;
  812. lpcs->CallbackOnError = (CAPERRORCALLBACK) lParam;
  813. lpcs->fLastErrorWasNULL = TRUE;
  814. lpcs->fUnicode |= VUNICODE_ERRORISANSI;
  815. return TRUE;
  816. #endif
  817. case WM_CAP_SET_CALLBACK_FRAME:
  818. // Set the callback proc for single frame during preview
  819. if (lParam != 0 && IsBadCodePtr ((FARPROC) lParam))
  820. return FALSE;
  821. lpcs->CallbackOnVideoFrame = (CAPVIDEOCALLBACK) lParam;
  822. return TRUE;
  823. default:
  824. break;
  825. }
  826. // Once we start capturing, don't change anything
  827. if (lpcs->fCaptureFlags & CAP_fCapturingNow)
  828. return dwReturn;
  829. switch (msg) {
  830. case WM_CAP_SET_CALLBACK_YIELD:
  831. // Set the callback proc for wave buffer processing to net
  832. if (lParam != 0 && IsBadCodePtr ((FARPROC) lParam))
  833. return FALSE;
  834. lpcs->CallbackOnYield = (CAPYIELDCALLBACK) lParam;
  835. return TRUE;
  836. case WM_CAP_SET_CALLBACK_VIDEOSTREAM:
  837. // Set the callback proc for video buffer processing to net
  838. if (lParam != 0 && IsBadCodePtr ((FARPROC) lParam))
  839. return FALSE;
  840. lpcs->CallbackOnVideoStream = (CAPVIDEOCALLBACK) lParam;
  841. return TRUE;
  842. case WM_CAP_SET_CALLBACK_WAVESTREAM:
  843. // Set the callback proc for wave buffer processing to net
  844. if (lParam != 0 && IsBadCodePtr ((FARPROC) lParam))
  845. return FALSE;
  846. lpcs->CallbackOnWaveStream = (CAPWAVECALLBACK) lParam;
  847. return TRUE;
  848. case WM_CAP_SET_CALLBACK_CAPCONTROL:
  849. // Set the callback proc for frame accurate capture start/stop
  850. if (lParam != 0 && IsBadCodePtr ((FARPROC) lParam))
  851. return FALSE;
  852. lpcs->CallbackOnControl = (CAPCONTROLCALLBACK) lParam;
  853. return TRUE;
  854. case WM_CAP_SET_USER_DATA:
  855. lpcs->lUser = lParam;
  856. return TRUE;
  857. case WM_CAP_DRIVER_CONNECT:
  858. // Connect to a device
  859. // wParam contains the index of the driver
  860. // If the same driver ID is requested, skip the request
  861. // Prevents multiple Inits from VB apps
  862. if (lpcs->fHardwareConnected &&
  863. (lpcs->sCapDrvCaps.wDeviceIndex == wParam))
  864. return TRUE;
  865. // First disconnect from any (possibly) existing device
  866. SendMessage (lpcs->hwnd, WM_CAP_DRIVER_DISCONNECT, 0, 0l);
  867. // and then connect to the new device
  868. if (CapWinConnectHardware (lpcs, (UINT) wParam /*wDeviceIndex*/)) {
  869. if (!DibGetNewFormatFromDriver (lpcs)) { // Allocate our bitspace
  870. // Use the cached palette if available
  871. if (lpcs->hPalCurrent && lpcs->lpCacheXlateTable) {
  872. PalSendPaletteToDriver (lpcs, lpcs->hPalCurrent, lpcs->lpCacheXlateTable);
  873. }
  874. else
  875. PalGetPaletteFromDriver (lpcs);
  876. // Get a frame using the possibly cached palette
  877. videoFrame (lpcs->hVideoIn, &lpcs->VidHdr);
  878. InvalidateRect(lpcs->hwnd, NULL, TRUE);
  879. lpcs->sCapDrvCaps.fCaptureInitialized = TRUE; // everything AOK!
  880. dwReturn = TRUE;
  881. }
  882. }
  883. break;
  884. case WM_CAP_DRIVER_DISCONNECT:
  885. MB ("About to disconnect from driver");
  886. // Disconnect from a device
  887. // wParam and lParam unused
  888. if (!lpcs->fHardwareConnected)
  889. return FALSE;
  890. CapWinDisconnectHardware (lpcs);
  891. DibFini (lpcs);
  892. /* PalFini (lpcs); keep the palette cached for reconnections */
  893. InvalidateRect(lpcs->hwnd, NULL, TRUE);
  894. lpcs->sCapDrvCaps.fCaptureInitialized = FALSE;
  895. dwReturn = TRUE;
  896. break;
  897. // unicode and win-16 version - see ansi thunk below
  898. case WM_CAP_FILE_SET_CAPTURE_FILE:
  899. // lParam points to the name of the capture file
  900. if (lParam) {
  901. BOOL fAlreadyExists; // Don't create a file if new name
  902. #ifndef _WIN32
  903. OFSTRUCT of;
  904. #endif
  905. HANDLE hFile;
  906. // Check for valid file names...
  907. #ifdef _WIN32
  908. // can't use OpenFile for UNICODE names
  909. if ((hFile = CreateFile(
  910. (LPTSTR) lParam,
  911. GENERIC_WRITE,
  912. 0,
  913. NULL,
  914. OPEN_EXISTING,
  915. FILE_ATTRIBUTE_NORMAL,
  916. NULL)) == INVALID_HANDLE_VALUE) {
  917. if ((hFile = CreateFile(
  918. (LPTSTR) lParam,
  919. GENERIC_WRITE,
  920. 0,
  921. NULL,
  922. CREATE_NEW,
  923. FILE_ATTRIBUTE_NORMAL,
  924. NULL)) == INVALID_HANDLE_VALUE) {
  925. #else
  926. if ((hFile = OpenFile ((LPTSTR) lParam, &of, OF_WRITE)) == -1) {
  927. if ((hFile = OpenFile ((LPTSTR) lParam, &of, OF_CREATE | OF_WRITE)) == -1) {
  928. #endif
  929. return FALSE;
  930. }
  931. fAlreadyExists = FALSE;
  932. }
  933. else
  934. fAlreadyExists = TRUE;
  935. #ifdef _WIN32
  936. CloseHandle(hFile);
  937. #else
  938. _lclose (hFile);
  939. #endif
  940. lstrcpyn (lpcs->achFile, (LPTSTR) lParam, NUMELMS(lpcs->achFile));
  941. lpcs->fCapFileExists = fileCapFileIsAVI (lpcs->achFile);
  942. if (!fAlreadyExists) {
  943. // Delete the file created by CREATE_NEW (or OF_CREATE)
  944. // when verifying that we can write to this file location
  945. #ifdef _WIN32
  946. DeleteFile ((LPTSTR) lParam);
  947. #else
  948. OpenFile ((LPTSTR) lParam, &of, OF_DELETE);
  949. #endif
  950. }
  951. dwReturn = TRUE;
  952. }
  953. break;
  954. #ifdef UNICODE
  955. // Ansi thunk for above.
  956. case WM_CAP_FILE_SET_CAPTURE_FILEA:
  957. // lParam points to the name of the capture file
  958. if (lParam) {
  959. LPWSTR pw;
  960. int chsize;
  961. // remember the null
  962. chsize = lstrlenA( (LPSTR) lParam) + 1;
  963. pw = LocalAlloc(LPTR, chsize * sizeof(WCHAR));
  964. if (pw) {
  965. Imbstowcs(pw, (LPSTR) lParam, chsize);
  966. dwReturn = ProcessCommandMessages(lpcs, WM_CAP_FILE_SET_CAPTURE_FILEW,
  967. 0, (LPARAM)pw);
  968. LocalFree(pw);
  969. }
  970. }
  971. break;
  972. #endif
  973. case WM_CAP_FILE_ALLOCATE:
  974. // lParam contains the size to preallocate the capture file in bytes
  975. return fileAllocCapFile(lpcs, lParam);
  976. // unicode and win-16 version - see ansi thunk below
  977. case WM_CAP_FILE_SAVEAS:
  978. // lParam points to the name of the SaveAs file
  979. if (lParam) {
  980. lstrcpyn (lpcs->achSaveAsFile, (LPTSTR) lParam,
  981. NUMELMS(lpcs->achSaveAsFile));
  982. return (fileSaveCopy(lpcs));
  983. }
  984. break;
  985. #ifdef UNICODE
  986. // ansi thunk for above
  987. case WM_CAP_FILE_SAVEASA:
  988. // lParam points to the name of the SaveAs file
  989. if (lParam) {
  990. LPWSTR pw;
  991. int chsize;
  992. // remember the null
  993. chsize = lstrlenA( (LPSTR) lParam)+1;
  994. pw = LocalAlloc(LPTR, chsize * sizeof(WCHAR));
  995. if (pw) {
  996. Imbstowcs(pw, (LPSTR) lParam, chsize);
  997. dwReturn = ProcessCommandMessages(lpcs, WM_CAP_FILE_SAVEASW,
  998. 0, (LPARAM)pw);
  999. LocalFree(pw);
  1000. }
  1001. }
  1002. break;
  1003. #endif
  1004. case WM_CAP_FILE_SET_INFOCHUNK:
  1005. // wParam is not used
  1006. // lParam is an LPCAPINFOCHUNK
  1007. if (lParam) {
  1008. return (SetInfoChunk(lpcs, (LPCAPINFOCHUNK) lParam));
  1009. }
  1010. break;
  1011. // unicode and win-16 version - see ansi thunk below
  1012. case WM_CAP_FILE_SAVEDIB:
  1013. // lParam points to the name of the DIB file
  1014. if (lParam) {
  1015. if (lpcs->fOverlayWindow)
  1016. GetAFrameThenCallback (lpcs, TRUE /*fForce*/);
  1017. return (fileSaveDIB(lpcs, (LPTSTR)lParam));
  1018. }
  1019. break;
  1020. #ifdef UNICODE
  1021. // ansi thunk for above
  1022. case WM_CAP_FILE_SAVEDIBA:
  1023. if (lParam) {
  1024. LPWSTR pw;
  1025. int chsize;
  1026. if (lpcs->fOverlayWindow)
  1027. GetAFrameThenCallback (lpcs, TRUE /*fForce*/);
  1028. // remember the null
  1029. chsize = lstrlenA( (LPSTR) lParam)+1;
  1030. pw = LocalAlloc(LPTR, chsize * sizeof(WCHAR));
  1031. if (pw) {
  1032. Imbstowcs(pw, (LPSTR) lParam, chsize);
  1033. dwReturn = fileSaveDIB(lpcs, pw);
  1034. LocalFree(pw);
  1035. }
  1036. }
  1037. break;
  1038. #endif
  1039. case WM_CAP_EDIT_COPY:
  1040. // Copy the current image and palette to the clipboard
  1041. // wParam and lParam unused
  1042. if (!lpcs->fHardwareConnected)
  1043. return FALSE;
  1044. if (lpcs->fOverlayWindow)
  1045. GetAFrameThenCallback (lpcs, TRUE /*fForce*/);
  1046. if (lpcs->sCapDrvCaps.fCaptureInitialized && OpenClipboard (lpcs->hwnd)) {
  1047. EmptyClipboard();
  1048. // put a copy of the current palette in the clipboard
  1049. if (lpcs->hPalCurrent && lpcs->lpBitsInfo->bmiHeader.biBitCount <= 8)
  1050. SetClipboardData(CF_PALETTE, CopyPalette (lpcs->hPalCurrent));
  1051. // make a packed DIB out of the current image
  1052. if (lpcs->lpBits && lpcs->lpBitsInfo ) {
  1053. if (SetClipboardData (CF_DIB, CreatePackedDib (lpcs->lpBitsInfo,
  1054. lpcs->lpBits, lpcs->hPalCurrent)))
  1055. dwReturn = TRUE;
  1056. else
  1057. errorUpdateError (lpcs, IDS_CAP_OUTOFMEM);
  1058. }
  1059. CloseClipboard();
  1060. }
  1061. break;
  1062. case WM_CAP_SET_AUDIOFORMAT:
  1063. {
  1064. // wParam is unused
  1065. // lParam is LPWAVEFORMAT or LPWAVEFORMATEX
  1066. UINT wSize;
  1067. LPWAVEFORMATEX lpwf = (LPWAVEFORMATEX) lParam;
  1068. UINT uiError;
  1069. // Verify the waveformat is valid
  1070. uiError = waveInOpen(NULL, WAVE_MAPPER, lpwf, 0, 0L,WAVE_FORMAT_QUERY);
  1071. if (uiError) {
  1072. errorUpdateError (lpcs, IDS_CAP_WAVE_OPEN_ERROR);
  1073. return FALSE;
  1074. }
  1075. if (lpcs->lpWaveFormat)
  1076. GlobalFreePtr (lpcs->lpWaveFormat);
  1077. wSize = GetSizeOfWaveFormat (lpwf);
  1078. if (lpcs->lpWaveFormat = (LPWAVEFORMATEX)
  1079. GlobalAllocPtr (GHND, sizeof (CAPSTREAM))) {
  1080. hmemcpy (lpcs->lpWaveFormat, lpwf, (LONG) wSize);
  1081. }
  1082. dwReturn = TRUE;
  1083. }
  1084. break;
  1085. case WM_CAP_DLG_VIDEOSOURCE:
  1086. // Show the dialog which controls the video source
  1087. // NTSC vs PAL, input channel selection, etc.
  1088. // wParam and lParam are unused
  1089. if (!lpcs->fHardwareConnected)
  1090. return FALSE;
  1091. if (lpcs->dwDlgsActive & VDLG_VIDEOSOURCE)
  1092. return FALSE;
  1093. if (lpcs->sCapDrvCaps.fHasDlgVideoSource) {
  1094. lpcs->dwDlgsActive |= VDLG_VIDEOSOURCE;
  1095. videoDialog (lpcs->hVideoCapture, lpcs->hwnd, 0L );
  1096. // Changing from NTSC to PAL could affect image dimensions!!!
  1097. DibGetNewFormatFromDriver (lpcs);
  1098. PalGetPaletteFromDriver (lpcs);
  1099. // May need to inform parent of new layout here!
  1100. InvalidateRect(lpcs->hwnd, NULL, TRUE);
  1101. UpdateWindow(lpcs->hwnd);
  1102. lpcs->dwDlgsActive &= ~VDLG_VIDEOSOURCE;
  1103. }
  1104. return (lpcs->sCapDrvCaps.fHasDlgVideoSource);
  1105. case WM_CAP_DLG_VIDEOFORMAT:
  1106. // Show the format dialog, user selects dimensions, depth, compression
  1107. // wParam and lParam are unused
  1108. if (!lpcs->fHardwareConnected)
  1109. return FALSE;
  1110. if (lpcs->dwDlgsActive & VDLG_VIDEOFORMAT)
  1111. return FALSE;
  1112. if (lpcs->sCapDrvCaps.fHasDlgVideoFormat) {
  1113. lpcs->dwDlgsActive |= VDLG_VIDEOFORMAT;
  1114. videoDialog (lpcs->hVideoIn, lpcs->hwnd, 0L );
  1115. DibGetNewFormatFromDriver (lpcs);
  1116. PalGetPaletteFromDriver (lpcs);
  1117. // May need to inform parent of new layout here!
  1118. InvalidateRect(lpcs->hwnd, NULL, TRUE);
  1119. UpdateWindow(lpcs->hwnd);
  1120. lpcs->dwDlgsActive &= ~VDLG_VIDEOFORMAT;
  1121. }
  1122. return (lpcs->sCapDrvCaps.fHasDlgVideoFormat);
  1123. case WM_CAP_DLG_VIDEODISPLAY:
  1124. // Show the dialog which controls output.
  1125. // This dialog only affects the presentation, never the data format
  1126. // wParam and lParam are unused
  1127. if (!lpcs->fHardwareConnected)
  1128. return FALSE;
  1129. if (lpcs->dwDlgsActive & VDLG_VIDEODISPLAY)
  1130. return FALSE;
  1131. if (lpcs->sCapDrvCaps.fHasDlgVideoDisplay) {
  1132. lpcs->dwDlgsActive |= VDLG_VIDEODISPLAY;
  1133. videoDialog (lpcs->hVideoDisplay, lpcs->hwnd, 0L);
  1134. lpcs->dwDlgsActive &= ~VDLG_VIDEODISPLAY;
  1135. }
  1136. return (lpcs->sCapDrvCaps.fHasDlgVideoDisplay);
  1137. case WM_CAP_DLG_VIDEOCOMPRESSION:
  1138. #ifndef NEW_COMPMAN
  1139. return FALSE;
  1140. #else
  1141. // Show the dialog which selects video compression options.
  1142. // wParam and lParam are unused
  1143. if (!lpcs->fHardwareConnected)
  1144. return FALSE;
  1145. if (lpcs->dwDlgsActive & VDLG_COMPRESSION)
  1146. return FALSE;
  1147. lpcs->dwDlgsActive |= VDLG_COMPRESSION;
  1148. ICCompressorChoose(
  1149. lpcs->hwnd, // parent window for dialog
  1150. ICMF_CHOOSE_KEYFRAME, // want "key frame every" box
  1151. lpcs->lpBitsInfo, // input format (optional)
  1152. NULL, // input data (optional)
  1153. &lpcs->CompVars, // data about the compressor/dlg
  1154. NULL); // title bar (optional)
  1155. lpcs->dwDlgsActive &= ~VDLG_COMPRESSION;
  1156. return TRUE;
  1157. #endif
  1158. case WM_CAP_SET_VIDEOFORMAT:
  1159. // wParam is the size of the BITMAPINFO
  1160. // lParam is an LPBITMAPINFO
  1161. if (!lpcs->fHardwareConnected)
  1162. return FALSE;
  1163. if (IsBadReadPtr ((LPVOID) lParam, (UINT) wParam))
  1164. return FALSE;
  1165. return (DibNewFormatFromApp (lpcs, (LPBITMAPINFO) lParam, (UINT) wParam));
  1166. case WM_CAP_SET_PREVIEW:
  1167. // if wParam, enable preview via drawdib
  1168. if (!lpcs->fHardwareConnected)
  1169. return FALSE;
  1170. if (wParam) {
  1171. // turn off the overlay, if it is in use
  1172. if (lpcs->fOverlayWindow)
  1173. SendMessage(lpcs->hwnd, WM_CAP_SET_OVERLAY, 0, 0L);
  1174. lpcs->fLiveWindow = TRUE;
  1175. statusUpdateStatus(lpcs, IDS_CAP_STAT_LIVE_MODE);
  1176. } // endif enabling preview
  1177. else {
  1178. lpcs->fLiveWindow = FALSE;
  1179. }
  1180. InvalidateRect (lpcs->hwnd, NULL, TRUE);
  1181. return TRUE;
  1182. case WM_CAP_SET_OVERLAY:
  1183. // if wParam, enable overlay in hardware
  1184. if (!lpcs->fHardwareConnected)
  1185. return FALSE;
  1186. if (wParam && lpcs->sCapDrvCaps.fHasOverlay) {
  1187. if (lpcs->fLiveWindow) // turn off preview mode
  1188. SendMessage(lpcs->hwnd, WM_CAP_SET_PREVIEW, 0, 0L);
  1189. lpcs->fOverlayWindow = TRUE;
  1190. statusUpdateStatus(lpcs, IDS_CAP_STAT_OVERLAY_MODE);
  1191. }
  1192. else {
  1193. lpcs->fOverlayWindow = FALSE;
  1194. videoStreamFini (lpcs->hVideoDisplay); // disable overlay on hardware
  1195. }
  1196. InvalidateRect (lpcs->hwnd, NULL, TRUE);
  1197. return (lpcs->sCapDrvCaps.fHasOverlay);
  1198. case WM_CAP_SET_PREVIEWRATE:
  1199. // wParam contains preview update rate in mS.
  1200. // if wParam == 0 no timer is in use.
  1201. if (lpcs->idTimer) {
  1202. KillTimer(lpcs->hwnd, ID_PREVIEWTIMER);
  1203. lpcs->idTimer = 0;
  1204. }
  1205. if (wParam != 0) {
  1206. lpcs->idTimer = SetTimer (lpcs->hwnd, ID_PREVIEWTIMER,
  1207. (UINT) wParam, NULL);
  1208. }
  1209. lpcs->uTimeout = (UINT) wParam;
  1210. dwReturn = TRUE;
  1211. break;
  1212. case WM_CAP_GRAB_FRAME:
  1213. // grab a single frame
  1214. // wParam and lParam unused
  1215. if (!lpcs->fHardwareConnected)
  1216. return FALSE;
  1217. if (lpcs->sCapDrvCaps.fCaptureInitialized) {
  1218. dwReturn = (DWORD) GetAFrameThenCallback (lpcs, TRUE /*fForce*/);
  1219. // disable live and overlay mode when capturing a single frame
  1220. if (lpcs->fLiveWindow)
  1221. SendMessage(lpcs->hwnd, WM_CAP_SET_PREVIEW, 0, 0L);
  1222. else if (lpcs->fOverlayWindow)
  1223. SendMessage(lpcs->hwnd, WM_CAP_SET_OVERLAY, 0, 0L);
  1224. }
  1225. break;
  1226. case WM_CAP_GRAB_FRAME_NOSTOP:
  1227. // grab a single frame, but don't change state of overlay/preview
  1228. // wParam and lParam unused
  1229. if (!lpcs->fHardwareConnected)
  1230. return FALSE;
  1231. dwReturn = (LONG) GetAFrameThenCallback (lpcs, TRUE /*fForce*/);
  1232. break;
  1233. case WM_CAP_SEQUENCE:
  1234. // This is the main entry for streaming video capture
  1235. // wParam is unused
  1236. // lParam is unused
  1237. if (!lpcs->fHardwareConnected)
  1238. return FALSE;
  1239. if (lpcs->sCapDrvCaps.fCaptureInitialized) {
  1240. lpcs->fCaptureFlags |= CAP_fCapturingToDisk;
  1241. return (AVICapture(lpcs));
  1242. }
  1243. break;
  1244. case WM_CAP_SEQUENCE_NOFILE:
  1245. // wParam is unused
  1246. // lParam is unused
  1247. if (!lpcs->fHardwareConnected)
  1248. return FALSE;
  1249. if (lpcs->sCapDrvCaps.fCaptureInitialized) {
  1250. lpcs->fCaptureFlags &= ~CAP_fCapturingToDisk;
  1251. return (AVICapture(lpcs));
  1252. }
  1253. break;
  1254. case WM_CAP_SET_SEQUENCE_SETUP:
  1255. // wParam is sizeof CAPTUREPARMS
  1256. // lParam = LPCAPTUREPARMS
  1257. // The following were added after the Beta, init in case the client
  1258. // has a smaller structure and doesn't access them.
  1259. // WHICH BETA ?? (SteveDav) We should change the comment to include a date
  1260. lpcs->sCapParms.dwAudioBufferSize = 0;
  1261. lpcs->sCapParms.fDisableWriteCache = TRUE;
  1262. lpcs->sCapParms.AVStreamMaster = AVSTREAMMASTER_AUDIO;
  1263. if (wParam <= sizeof (CAPTUREPARMS)) {
  1264. dwT = min (sizeof (CAPTUREPARMS), wParam);
  1265. if (IsBadReadPtr ((LPVOID) lParam, (UINT) dwT))
  1266. break;
  1267. _fmemcpy ((LPVOID) &lpcs->sCapParms, (LPVOID) lParam, (UINT) dwT);
  1268. // Validate stuff that isn't handled elsewhere
  1269. if (lpcs->sCapParms.wChunkGranularity != 0 &&
  1270. lpcs->sCapParms.wChunkGranularity < 16)
  1271. lpcs->sCapParms.wChunkGranularity = 16;
  1272. if (lpcs->sCapParms.wChunkGranularity > 16384)
  1273. lpcs->sCapParms.wChunkGranularity = 16384;
  1274. if (lpcs->sCapParms.fLimitEnabled && (lpcs->sCapParms.wTimeLimit == 0))
  1275. lpcs->sCapParms.wTimeLimit = 1;
  1276. // Force Step MCI off if not using MCI control
  1277. if (lpcs->sCapParms.fStepMCIDevice && !lpcs->sCapParms.fMCIControl)
  1278. lpcs->sCapParms.fStepMCIDevice = FALSE;
  1279. // Prevent audio capture if no audio hardware
  1280. lpcs->sCapParms.fCaptureAudio =
  1281. lpcs->fAudioHardware && lpcs->sCapParms.fCaptureAudio;
  1282. // Limit audio buffers
  1283. lpcs->sCapParms.wNumAudioRequested =
  1284. min (MAX_WAVE_BUFFERS, lpcs->sCapParms.wNumAudioRequested);
  1285. // Limit video buffers
  1286. lpcs->sCapParms.wNumVideoRequested =
  1287. min (MAX_VIDEO_BUFFERS, lpcs->sCapParms.wNumVideoRequested);
  1288. dwReturn = TRUE;
  1289. }
  1290. break;
  1291. // unicode and win-16 version - see ansi thunk below
  1292. case WM_CAP_SET_MCI_DEVICE:
  1293. // lParam points to the name of the MCI Device
  1294. if (IsBadStringPtr ((LPVOID) lParam, 1))
  1295. return FALSE;
  1296. if (lParam) {
  1297. lstrcpyn (lpcs->achMCIDevice, (LPTSTR) lParam, NUMELMS(lpcs->achMCIDevice));
  1298. dwReturn = TRUE;
  1299. }
  1300. break;
  1301. #ifdef UNICODE
  1302. // ansi thunk for above
  1303. case WM_CAP_SET_MCI_DEVICEA:
  1304. // lParam points to Ansi name of MCI device
  1305. if (lParam) {
  1306. //remember the null
  1307. int chsize = lstrlenA( (LPSTR) lParam)+1;
  1308. Imbstowcs(lpcs->achMCIDevice, (LPSTR) lParam,
  1309. min(chsize, NUMELMS(lpcs->achMCIDevice)));
  1310. dwReturn = TRUE;
  1311. }
  1312. break;
  1313. #endif
  1314. case WM_CAP_SET_SCROLL:
  1315. // lParam is an LPPOINT which points to the new scroll position
  1316. if (!lpcs->fHardwareConnected)
  1317. return FALSE;
  1318. if (IsBadReadPtr ((LPVOID) lParam, sizeof (POINT)))
  1319. return FALSE;
  1320. {
  1321. LPPOINT lpP = (LPPOINT) lParam;
  1322. if (lpP->x < lpcs->dxBits && lpP->y < lpcs->dyBits) {
  1323. lpcs->ptScroll = *lpP;
  1324. InvalidateRect (lpcs->hwnd, NULL, TRUE);
  1325. dwReturn = TRUE;
  1326. }
  1327. }
  1328. break;
  1329. case WM_CAP_SET_SCALE:
  1330. // if wParam, Scale the window to the client region?
  1331. if (!lpcs->fHardwareConnected)
  1332. return FALSE;
  1333. lpcs->fScale = (BOOL) wParam;
  1334. return TRUE;
  1335. // unicode and win-16 version - see ansi thunk below
  1336. case WM_CAP_PAL_OPEN:
  1337. // Open a new palette
  1338. // wParam is unused
  1339. // lParam contains an LPTSTR to the file
  1340. if (!lpcs->fHardwareConnected)
  1341. return FALSE;
  1342. if (IsBadStringPtr ((LPVOID) lParam, 1))
  1343. return FALSE;
  1344. return fileOpenPalette(lpcs, (LPTSTR) lParam /*lpszFileName*/);
  1345. #ifdef UNICODE
  1346. // ansi thunk for above
  1347. case WM_CAP_PAL_OPENA:
  1348. // lParam contains (ANSI) lpstr for filename
  1349. if (lParam) {
  1350. // remember the null
  1351. int chsize = lstrlenA( (LPSTR) lParam)+1;
  1352. LPWSTR pw = LocalAlloc(LPTR, chsize * sizeof(WCHAR));
  1353. if (pw) {
  1354. Imbstowcs(pw, (LPSTR) lParam, chsize);
  1355. dwReturn = fileOpenPalette(lpcs, pw);
  1356. LocalFree(pw);
  1357. }
  1358. }
  1359. break;
  1360. #endif
  1361. // unicode and win-16 version - see ansi thunk below
  1362. case WM_CAP_PAL_SAVE:
  1363. // Save the current palette in a file
  1364. // wParam is unused
  1365. // lParam contains an LPTSTR to the file
  1366. if (!lpcs->fHardwareConnected)
  1367. return FALSE;
  1368. if (IsBadStringPtr ((LPVOID) lParam, 1))
  1369. return FALSE;
  1370. return fileSavePalette(lpcs, (LPTSTR) lParam /*lpszFileName*/);
  1371. #ifdef UNICODE
  1372. // ansi thunk for above
  1373. case WM_CAP_PAL_SAVEA:
  1374. // lParam contains (ANSI) lpstr for filename
  1375. if (lParam) {
  1376. // remember the null
  1377. int chsize = lstrlenA( (LPSTR) lParam)+1;
  1378. LPWSTR pw = LocalAlloc(LPTR, chsize * sizeof(WCHAR));
  1379. if (pw) {
  1380. Imbstowcs(pw, (LPSTR) lParam, chsize);
  1381. dwReturn = fileSavePalette(lpcs, pw);
  1382. LocalFree(pw);
  1383. }
  1384. }
  1385. break;
  1386. #endif
  1387. case WM_CAP_PAL_AUTOCREATE:
  1388. // Automatically capture a palette
  1389. // wParam contains a count of the number of frames to average
  1390. // lParam contains the number of colors desired in the palette
  1391. if (!lpcs->fHardwareConnected)
  1392. return FALSE;
  1393. return CapturePaletteAuto (lpcs, (int) wParam, (int) lParam);
  1394. case WM_CAP_PAL_MANUALCREATE:
  1395. // Manually capture a palette
  1396. // wParam contains TRUE for each frame to capture, FALSE when done
  1397. // lParam contains the number of colors desired in the palette
  1398. if (!lpcs->fHardwareConnected)
  1399. return FALSE;
  1400. return CapturePaletteManual (lpcs, (BOOL) wParam, (int) lParam);
  1401. case WM_CAP_PAL_PASTE:
  1402. // Paste a palette from the clipboard, send to the driver
  1403. if (!lpcs->fHardwareConnected)
  1404. return FALSE;
  1405. if (lpcs->sCapDrvCaps.fCaptureInitialized && OpenClipboard(lpcs->hwnd)) {
  1406. HANDLE hPal;
  1407. hPal = GetClipboardData(CF_PALETTE);
  1408. CloseClipboard();
  1409. if (hPal) {
  1410. PalSendPaletteToDriver (lpcs, CopyPalette(hPal), NULL /* XlateTable */);
  1411. InvalidateRect(lpcs->hwnd, NULL, TRUE);
  1412. dwReturn = TRUE;
  1413. }
  1414. }
  1415. break;
  1416. default:
  1417. break;
  1418. }
  1419. return dwReturn;
  1420. }
  1421. /*--------------------------------------------------------------+
  1422. | ****************** THE WINDOW PROCEDURE ********************* |
  1423. +--------------------------------------------------------------*/
  1424. LONG FAR PASCAL LOADDS EXPORT CapWndProc (HWND hwnd, UINT msg, UINT wParam, LONG lParam)
  1425. {
  1426. LPCAPSTREAM lpcs;
  1427. PAINTSTRUCT ps;
  1428. HDC hdc;
  1429. MSG PMsg;
  1430. int f;
  1431. lpcs = (LPCAPSTREAM) GetWindowLong (hwnd, GWL_CAPSTREAM);
  1432. if (msg >= WM_CAP_START && msg <= WM_CAP_END)
  1433. return (ProcessCommandMessages (lpcs, msg, wParam, lParam));
  1434. switch (msg) {
  1435. case WM_CREATE:
  1436. lpcs = CapWinCreate (hwnd);
  1437. break;
  1438. case WM_TIMER:
  1439. // Update the preview window if we got a timer and not saving to disk
  1440. GetAFrameThenCallback (lpcs, FALSE /*fForce*/);
  1441. // Added VFW 1.1b, Clear the queue of additional timer msgs!!!
  1442. // Even in Win32, processing frame timers can swamp all other
  1443. // activity in the app, so clear the queue after each frame is done.
  1444. // This successfully corrected a problem with the "Hit OK to continue"
  1445. // dialog not appearing bug due to app message queue
  1446. // swamping with timer messages at large
  1447. // image dimensions and preview rates.
  1448. PeekMessage (&PMsg, hwnd, WM_TIMER, WM_TIMER,PM_REMOVE|PM_NOYIELD);
  1449. break;
  1450. case WM_CLOSE:
  1451. break;
  1452. case WM_DESTROY:
  1453. CapWinDestroy (lpcs);
  1454. break;
  1455. case WM_PALETTECHANGED:
  1456. if (lpcs->hdd == NULL)
  1457. break;
  1458. hdc = GetDC(hwnd);
  1459. if (f = DrawDibRealize(lpcs->hdd, hdc, TRUE /*fBackground*/))
  1460. InvalidateRect(hwnd,NULL,TRUE);
  1461. ReleaseDC(hwnd,hdc);
  1462. return f;
  1463. case WM_QUERYNEWPALETTE:
  1464. if (lpcs->hdd == NULL)
  1465. break;
  1466. hdc = GetDC(hwnd);
  1467. f = DrawDibRealize(lpcs->hdd, hdc, FALSE);
  1468. ReleaseDC(hwnd, hdc);
  1469. if (f)
  1470. InvalidateRect(hwnd, NULL, TRUE);
  1471. return f;
  1472. case WM_SIZE:
  1473. case WM_MOVE:
  1474. if (lpcs->fOverlayWindow) // Make the driver paint the key color
  1475. InvalidateRect(hwnd, NULL, TRUE);
  1476. break;
  1477. case WM_WINDOWPOSCHANGED:
  1478. if (lpcs->fOverlayWindow) // Make the driver paint the key color
  1479. InvalidateRect(hwnd, NULL, TRUE);
  1480. return 0;
  1481. case WM_ERASEBKGND:
  1482. return 0; // don't bother to erase it
  1483. case WM_PAINT:
  1484. hdc = BeginPaint(hwnd, &ps);
  1485. if (lpcs->fOverlayWindow) {
  1486. CheckWindowMove(lpcs, ps.hdc, TRUE);
  1487. }
  1488. else {
  1489. #ifdef _WIN32
  1490. SetWindowOrgEx(hdc, lpcs->ptScroll.x, lpcs->ptScroll.y, NULL);
  1491. #else
  1492. SetWindowOrg(hdc, lpcs->ptScroll.x, lpcs->ptScroll.y);
  1493. #endif
  1494. DibPaint(lpcs, hdc);
  1495. }
  1496. EndPaint(hwnd, &ps);
  1497. break;
  1498. default:
  1499. break;
  1500. }
  1501. return DefWindowProc(hwnd, msg, wParam, lParam);
  1502. }
  1503. #if 0
  1504. void dummyTest ()
  1505. {
  1506. HWND hwnd;
  1507. FARPROC fpProc;
  1508. DWORD dwSize;
  1509. WORD wSize;
  1510. BOOL f;
  1511. int i;
  1512. char szName[80];
  1513. char szVer[80];
  1514. DWORD dwMS;
  1515. int iFrames, iColors;
  1516. char s;
  1517. LPPOINT lpP;
  1518. capSetCallbackOnError(hwnd, fpProc);
  1519. capSetCallbackOnStatus(hwnd, fpProc);
  1520. capSetCallbackOnYield(hwnd, fpProc);
  1521. capSetCallbackOnFrame(hwnd, fpProc);
  1522. capSetCallbackOnVideoStream(hwnd, fpProc);
  1523. capSetCallbackOnWaveStream(hwnd, fpProc);
  1524. capDriverConnect(hwnd, i);
  1525. capDriverDisconnect(hwnd);
  1526. capDriverGetName(hwnd, szName, wSize);
  1527. capDriverGetVersion(hwnd, szVer, wSize);
  1528. capDriverGetCaps(hwnd, s, wSize);
  1529. capFileSetCaptureFile(hwnd, szName);
  1530. capFileGetCaptureFile(hwnd, szName, wSize);
  1531. capFileAlloc(hwnd, dwSize);
  1532. capFileSaveAs(hwnd, szName);
  1533. capEditCopy(hwnd);
  1534. capSetAudioFormat(hwnd, s, wSize);
  1535. capGetAudioFormat(hwnd, s, wSize);
  1536. capGetAudioFormatSize(hwnd);
  1537. capDlgVideoFormat(hwnd);
  1538. capDlgVideoSource(hwnd);
  1539. capDlgVideoDisplay(hwnd);
  1540. capPreview(hwnd, f);
  1541. capPreviewRate(hwnd, dwMS);
  1542. capOverlay(hwnd, f);
  1543. capPreviewScale(hwnd, f);
  1544. capGetStatus(hwnd, s, wSize);
  1545. capSetScrollPos(hwnd, lpP);
  1546. capGrabFrame(hwnd);
  1547. capGrabFrameNoStop(hwnd);
  1548. capCaptureSequence(hwnd);
  1549. capCaptureSequenceNoFile(hwnd);
  1550. capCaptureGetSetup(hwnd, s, wSize);
  1551. capCaptureSetSetup(hwnd, s, wSize);
  1552. capCaptureSingleFrameOpen(hwnd);
  1553. capCaptureSingleFrameClose(hwnd);
  1554. capCaptureSingleFrame(hwnd);
  1555. capSetMCIDeviceName(hwnd, szName);
  1556. capGetMCIDeviceName(hwnd, szName, wSize);
  1557. capPalettePaste(hwnd);
  1558. capPaletteAuto(hwnd, iFrames, iColors);
  1559. }
  1560. #endif