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.

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