/**************************************************************************** * * AVICLIP.C * * Clipboard support for AVIFile * * Copyright (c) 1992 - 1995 Microsoft Corporation. All Rights Reserved. * * You have a royalty-free right to use, modify, reproduce and * distribute the Sample Files (and/or any modified version) in * any way you find useful, provided that you agree that * Microsoft has no warranty obligations or liability for any * Sample Application Files which are modified. * ***************************************************************************/ #include #include #include #include "avimem.h" #include "enumfetc.h" #include "debug.h" //#define TRYLINKS #ifdef TRYLINKS static SZCODE aszLink[] = TEXT("OwnerLink"); #endif #ifndef _WIN32 #define AVIStreamInfoW AVIStreamInfo #endif /* From avifps.h.... */ BOOL FAR TaskHasExistingProxies(void); #define OWNER_DISPLAY 0 STDMETHODIMP AVIClipQueryInterface(LPDATAOBJECT lpd, REFIID riid, LPVOID FAR* ppvObj); STDMETHODIMP_(ULONG) AVIClipAddRef(LPDATAOBJECT lpd); STDMETHODIMP_(ULONG) AVIClipRelease(LPDATAOBJECT lpd); STDMETHODIMP AVIClipGetData(LPDATAOBJECT lpd, LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium ); STDMETHODIMP AVIClipGetDataHere(LPDATAOBJECT lpd, LPFORMATETC pformatetc, LPSTGMEDIUM pmedium ); STDMETHODIMP AVIClipQueryGetData(LPDATAOBJECT lpd, LPFORMATETC pformatetc ); STDMETHODIMP AVIClipGetCanonicalFormatEtc(LPDATAOBJECT lpd, LPFORMATETC pformatetc, LPFORMATETC pformatetcOut); STDMETHODIMP AVIClipSetData(LPDATAOBJECT lpd, LPFORMATETC pformatetc, STGMEDIUM FAR * pmedium, BOOL fRelease); STDMETHODIMP AVIClipEnumFormatEtc(LPDATAOBJECT lpd, DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc); STDMETHODIMP AVIClipDAdvise(LPDATAOBJECT lpd, FORMATETC FAR* pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD FAR* pdwConnection); STDMETHODIMP AVIClipDUnadvise(LPDATAOBJECT lpd, DWORD dwConnection); STDMETHODIMP AVIClipEnumDAdvise(LPDATAOBJECT lpd, LPENUMSTATDATA FAR* ppenumAdvise); IDataObjectVtbl AVIClipVtbl = { AVIClipQueryInterface, AVIClipAddRef, AVIClipRelease, AVIClipGetData, AVIClipGetDataHere, AVIClipQueryGetData, AVIClipGetCanonicalFormatEtc, AVIClipSetData, AVIClipEnumFormatEtc, AVIClipDAdvise, AVIClipDUnadvise, AVIClipEnumDAdvise }; #define N_FORMATS (sizeof(FormatList) / sizeof(FormatList[0])) FORMATETC FormatList[] = { // CF_WAVE must be first, see AVIPutFileOnClipboard {CF_WAVE, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}, {CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}, // CF_PALETTE must be last, see AVIPutFileOnClipboard {CF_PALETTE, NULL, DVASPECT_CONTENT, -1, TYMED_GDI} }; #define AVICLIP_MAGIC 0x42424242 typedef struct { IDataObjectVtbl FAR * lpVtbl; DWORD Magic; ULONG ulRefCount; PAVIFILE pf; WORD wFormats; LPFORMATETC lpFormats; //!!! what about IDataView //!!! what about a IGetFrame HWND hwndMci; PGETFRAME pgf; } AVICLIP, FAR * LPAVICLIP; #if OWNER_DISPLAY static LRESULT CALLBACK _loadds ClipboardWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LONG lParam); static WNDPROC OldClipboardWindowProc; static LPAVICLIP lpcClipboard; #endif #include "olehack.h" long glOleRefCount = 0; HRESULT FAR PASCAL InitOle(BOOL fForceLoad) { UINT w; ++glOleRefCount; if ( glOleRefCount == 1 ) { #ifdef DEBUG HRESULT hr = OleInitialize(NULL); if (hr != S_OK) { DPF("InitOle: OleInitialize returned %8x (%x)\n", hr, GetLastError()); } else { DPF2("InitOle: OleInitialize returned S_OK\n"); } return(hr); #else return OleInitialize(NULL); #endif } return S_OK; } void FAR PASCAL TermOle(void) { // Someone's calling us too many times... protect them from their selves // if (glOleRefCount == 0) { DPF("TermOle called too many times...\n"); return; } --glOleRefCount; if (glOleRefCount > 0) { DPF2("Not freeing OLE32.DLL, extra init count still %d\n", glOleRefCount); return; } OleUninitialize(); } STDAPI AVIGetDataObject(PAVIFILE pf, LPDATAOBJECT FAR *ppDataObj) { LPAVICLIP lpc; PAVISTREAM ps; *ppDataObj = NULL; if (pf == NULL) { return NOERROR; } AVIFileAddRef(pf); lpc = (LPAVICLIP) GlobalAllocPtr(GHND | GMEM_SHARE, sizeof(AVICLIP)); if (!lpc) return ResultFromScode(AVIERR_MEMORY); InitOle(TRUE); lpc->lpVtbl = &AVIClipVtbl; lpc->ulRefCount = 1; lpc->pf = pf; lpc->wFormats = N_FORMATS; lpc->lpFormats = FormatList; lpc->Magic = AVICLIP_MAGIC; // // if there is no video in the file, dont offer video // CF_WAVE must be first. // if (AVIFileGetStream(pf, &ps, streamtypeVIDEO, 0L) != NOERROR) { lpc->wFormats = 1; } else { // // if the video format is higher than 8bpp dont offer a palette // CF_PALETTE must be last. // AVISTREAMINFOW strhdr; BITMAPINFOHEADER bi; DWORD dwcbFormat; // get the stream header AVIStreamInfoW(ps, &strhdr, sizeof(strhdr)); // now read the format of this thing dwcbFormat = sizeof(bi); AVIStreamReadFormat(ps, strhdr.dwStart, (LPVOID)&bi, (LONG FAR *)&dwcbFormat); // if it is true color (i.e., > 8bpp) then don't use the palette if (bi.biBitCount > 8) { DPF("Turning off CF_PALETTE now\n"); lpc->wFormats--; // don't use CF_PALETTE } ps->lpVtbl->Release(ps); } // // if there is no audio in the file, dont offer audio // CF_WAVE must be first. // if (AVIFileGetStream(pf, &ps, streamtypeAUDIO, 0L) != NOERROR) { lpc->wFormats--; lpc->lpFormats++; } else { ps->lpVtbl->Release(ps); } *ppDataObj = (LPDATAOBJECT) lpc; return 0; } /************************************************************************** * @doc EXTERNAL AVIPutFileOnClipboard * * @api HRESULT | AVIPutFileOnClipboard | Puts a file described by the passed * in PAVIFILE onto the clipboard. * * @parm PAVIFILE | pfile | Handle representing the file to put on the clipboard. * * @comm * * @rdesc Returns zero on success or an error code. * * @xref AVIPutStreamOnClipboard AVIGetFromClipboard * *************************************************************************/ STDAPI AVIPutFileOnClipboard(PAVIFILE pf) { LPDATAOBJECT lpd; HRESULT hr; InitOle(TRUE); hr = AVIGetDataObject(pf, &lpd); hr = OleSetClipboard(lpd); if (lpd) { lpd->lpVtbl->Release(lpd); #if OWNER_DISPLAY lpcClipboard = lpc; // // hook the clipboard owner so we can do OWNER_DISPLAY formats // { HWND hwnd = GetClipboardOwner(); if (OldClipboardWindowProc == NULL) { if (hwnd) { OldClipboardWindowProc = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (LONG)ClipboardWindowProc); } } if (OpenClipboard(hwnd)) { SetClipboardData(CF_OWNERDISPLAY, NULL); CloseClipboard(); } } #endif } TermOle(); return hr; } /************************************************************************** * @doc EXTERNAL AVIGetFromClipboard * * @api HRESULT | AVIGetFromClipboard | Get a file or stream off of the * clipboard. * * @parm PAVIFILE FAR * | ppfile | Pointer to a variable that can * * @comm If

is not NULL, the function will first attempt to * retrieve a file from the clipboard. Then, if

is not * NULL, it will attempt to retrieve a stream. * * Any file or stream retrieved from the clipboard using this * function should eventually be released with * or . * * @rdesc Returns zero on success or an error code. If there is no suitable * data on the clipboard, no error code will be returned, but * the returned variables will be NULL. * * @xref AVIPutStreamOnClipboard AVIGetFromClipboard * *************************************************************************/ STDAPI AVIGetFromClipboard(PAVIFILE FAR * lppf) { LPDATAOBJECT lpd = NULL; HRESULT hr = NOERROR; FORMATETC fetc; STGMEDIUM stg; if (!lppf) return ResultFromScode(E_POINTER); *lppf = NULL; InitOle(TRUE); OleGetClipboard(&lpd); if (lpd) { #ifdef DEBUGXX // Print out lots of stuff about what's on the clipboard.... { LPENUMFORMATETC lpEnum = NULL; TCHAR achTemp[256]; lpd->lpVtbl->EnumFormatEtc(lpd, DATADIR_GET, &lpEnum); if (lpEnum) { DPF("Formats available:\n"); while(lpEnum->lpVtbl->Next(lpEnum, 1, (LPFORMATETC)&fetc, NULL) == NOERROR) { achTemp[0] = TEXT('\0'); GetClipboardFormatName(fetc.cfFormat, achTemp, sizeof(achTemp)/sizeof(achTemp[0])); DPF("\t%u\t%lu\t%ls\n", fetc.cfFormat, fetc.tymed, (LPTSTR)achTemp); if ((fetc.cfFormat == CF_WAVE) || (fetc.cfFormat == CF_DIB) || (fetc.cfFormat == CF_RIFF) || (fetc.cfFormat == CF_METAFILEPICT) || (fetc.cfFormat == CF_BITMAP) || (fetc.cfFormat == CF_PENDATA)) continue; if (fetc.tymed & TYMED_HGLOBAL) { fetc.tymed = TYMED_HGLOBAL; hr = lpd->lpVtbl->GetData(lpd, &fetc, &stg); if (hr == 0) { LPVOID lp = GlobalLock(stg.hGlobal); DPF("%s\n", (LPSTR) lp); GlobalUnlock(stg.hGlobal); ReleaseStgMedium(&stg); } } } } } #endif lpd->lpVtbl->QueryInterface(lpd, &IID_IAVIFile, lppf); // Try for IAVIStream here? #ifdef TRYLINKS // See if there's a link to a type of file we can open.... if (!*lppf) { UINT cfLink; cfLink = RegisterClipboardFormat(aszLink); fetc.cfFormat = cfLink; fetc.ptd = 0; fetc.dwAspect = DVASPECT_CONTENT; fetc.lindex = -1; fetc.tymed = TYMED_HGLOBAL; hr = lpd->lpVtbl->GetData(lpd, &fetc, &stg); if (hr == 0) { LPTSTR lp = GlobalLock(stg.hGlobal); LPTSTR lpName; lpName = lp + lstrlen(lp) + 1; DPF("Got CF_LINK (%s/%s) data from clipboard...\n", lp,lpName); hr = AVIFileOpen(lppf, lpName, OF_READ | OF_SHARE_DENY_WRITE, NULL); if (hr == 0) { DPF("Opened file from link!\n"); // !!! If the app name is "MPlayer", we could get // the selection out of the data.... } GlobalUnlock(stg.hGlobal); ReleaseStgMedium(&stg); } } #endif if (!*lppf) { PAVISTREAM aps[2]; int cps = 0; fetc.cfFormat = CF_DIB; fetc.ptd = 0; fetc.dwAspect = DVASPECT_CONTENT; fetc.lindex = -1; fetc.tymed = TYMED_HGLOBAL; // CF_BITMAP, CF_PALETTE? hr = lpd->lpVtbl->GetData(lpd, &fetc, &stg); if (hr == 0) { DPF("Got CF_DIB data from clipboard...\n"); hr = AVIMakeStreamFromClipboard(CF_DIB, stg.hGlobal, &aps[cps]); if (hr == 0) { cps++; } ReleaseStgMedium(&stg); } fetc.cfFormat = CF_WAVE; fetc.ptd = 0; fetc.dwAspect = DVASPECT_CONTENT; fetc.lindex = -1; fetc.tymed = TYMED_HGLOBAL; hr = lpd->lpVtbl->GetData(lpd, &fetc, &stg); if (hr == 0) { DPF("Got CF_WAVE data from clipboard...\n"); hr = AVIMakeStreamFromClipboard(CF_WAVE, stg.hGlobal, &aps[cps]); if (hr == 0) { cps++; } ReleaseStgMedium(&stg); } if (cps) { hr = AVIMakeFileFromStreams(lppf, cps, aps); while (cps-- > 0) AVIStreamClose(aps[cps]); } else hr = ResultFromScode(AVIERR_NODATA); } lpd->lpVtbl->Release(lpd); } TermOle(); return hr; } /************************************************************************** * @doc EXTERNAL AVIClearClipboard * * @api HRESULT | AVIClearClipboard | Releases any file or stream that * has been put on the Clipboard. * * @comm Applications should use this function before exiting if they use * other Clipboard routines. Do not use this function just to * clear the clipboard; it might not return until other * applications have finished using the data placed on the Clipboard. * Ideally, call this function after hiding your application's windows. * * @rdesc Returns zero on success or an error code. * * @xref AVIPutStreamOnClipboard AVIGetFromClipboard * *************************************************************************/ STDAPI AVIClearClipboard(void) { HRESULT hr; InitOle(TRUE); hr = OleFlushClipboard(); while (TaskHasExistingProxies()) { MSG msg; DPF("AVIClearClipboard: Waiting while streams in use....\n"); while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } } TermOle(); return hr; } typedef LPBITMAPINFOHEADER PDIB; #ifndef BI_BITFIELDS #define BI_BITFIELDS 3 #endif #ifndef HALFTONE #define HALFTONE COLORONCOLOR #endif #define DibCompression(lpbi) (DWORD)(((LPBITMAPINFOHEADER)(lpbi))->biCompression) #define DibColors(lpbi) ((RGBQUAD FAR *)((LPBYTE)(lpbi) + (int)(lpbi)->biSize)) #define DibNumColors(lpbi) ((lpbi)->biClrUsed == 0 && (lpbi)->biBitCount <= 8 \ ? (int)(1 << (int)(lpbi)->biBitCount) \ : (int)(lpbi)->biClrUsed) /* * CreateBIPalette() * * Given a Pointer to a BITMAPINFO struct will create a * a GDI palette object from the color table. * */ HPALETTE DibCreatePalette(PDIB pdib) { LOGPALETTE *pPal; HPALETTE hpal = NULL; int nNumColors; int i; RGBQUAD FAR * pRgb; if (!pdib) return NULL; nNumColors = DibNumColors(pdib); if (nNumColors == 3 && DibCompression(pdib) == BI_BITFIELDS) nNumColors = 0; if (nNumColors > 0) { pRgb = DibColors(pdib); pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY)); if (!pPal) goto exit; pPal->palNumEntries = (WORD) nNumColors; pPal->palVersion = 0x300; for (i = 0; i < nNumColors; i++) { pPal->palPalEntry[i].peRed = pRgb->rgbRed; pPal->palPalEntry[i].peGreen = pRgb->rgbGreen; pPal->palPalEntry[i].peBlue = pRgb->rgbBlue; pPal->palPalEntry[i].peFlags = (BYTE)0; pRgb++; } hpal = CreatePalette(pPal); LocalFree((HLOCAL)pPal); } else { #ifdef _WIN32 HDC hdc = GetDC(NULL); hpal = CreateHalftonePalette(hdc); ReleaseDC(NULL, hdc); #endif } exit: return hpal; } STDMETHODIMP AVIClipQueryInterface(LPDATAOBJECT lpd, REFIID riid, LPVOID FAR* ppvObj) { LPAVICLIP lpc = (LPAVICLIP) lpd; SCODE scode; if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown)) { DPF2("Clip %p: Usage++=%lx\n", lpd, lpc->ulRefCount + 1); ++lpc->ulRefCount; *ppvObj = lpd; scode = S_OK; } else if (lpc->pf && IsEqualIID(riid, &IID_IAVIFile)) { AVIFileAddRef(lpc->pf); *ppvObj = lpc->pf; scode = S_OK; } else { // unsupported interface *ppvObj = NULL; scode = E_NOINTERFACE; } return ResultFromScode(scode); } STDMETHODIMP_(ULONG) AVIClipAddRef(LPDATAOBJECT lpd) { LPAVICLIP lpc = (LPAVICLIP) lpd; DPF2("Clip %p: Usage++=%lx\n", lpd, lpc->ulRefCount + 1); return ++lpc->ulRefCount; } STDMETHODIMP_(ULONG) AVIClipRelease(LPDATAOBJECT lpd) { LPAVICLIP lpc = (LPAVICLIP) lpd; DPF2("Clip %p: Usage--=%lx\n", lpd, lpc->ulRefCount - 1); if (--lpc->ulRefCount) return lpc->ulRefCount; if (lpc->pf) AVIFileClose(lpc->pf); if (lpc->pgf) AVIStreamGetFrameClose(lpc->pgf); if (lpc->hwndMci) DestroyWindow(lpc->hwndMci); #if OWNER_DISPLAY if (lpc == lpcClipboard) lpcClipboard = NULL; #endif GlobalFreePtr(lpc); TermOle(); return 0; } // *** IDataObject METHODIMPs *** STDMETHODIMP AVIClipGetData(LPDATAOBJECT lpd, LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium ) { LPAVICLIP lpc = (LPAVICLIP) lpd; SCODE sc = S_OK; LPVOID lp; LPBITMAPINFOHEADER lpbi; DWORD cb; PGETFRAME pgf = NULL; PAVISTREAM ps = NULL; pmedium->pUnkForRelease = NULL; if (pformatetcIn->cfFormat == CF_DIB || pformatetcIn->cfFormat == CF_PALETTE) { AVIFileGetStream(lpc->pf, &ps, streamtypeVIDEO, 0L); if (!ps) { sc = E_FAIL; goto error; } pgf = AVIStreamGetFrameOpen(ps, NULL); if (!pgf) { DPF("AVIClipGetData: AVIStreamGetFrameOpen failed!\n"); sc = E_FAIL; goto error; } lpbi = AVIStreamGetFrame(pgf, 0); if (! lpbi) { DPF("AVIClipGetData: AVIStreamGetFrame failed!\n"); sc = E_OUTOFMEMORY; goto error; } if (pformatetcIn->cfFormat == CF_DIB) { DPF("Building CF_DIB data\n"); // Verify caller asked for correct medium if (!(pformatetcIn->tymed & TYMED_HGLOBAL)) { sc = DATA_E_FORMATETC; goto error; } cb = lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD) + lpbi->biSizeImage; pmedium->hGlobal = GlobalAlloc(GHND | GMEM_SHARE, cb); if (!pmedium->hGlobal) { sc = E_OUTOFMEMORY; goto error; } lp = GlobalLock(pmedium->hGlobal); hmemcpy(lp, lpbi, cb); GlobalUnlock(pmedium->hGlobal); pmedium->tymed = TYMED_HGLOBAL; } else /* if (pformatetcIn->cfFormat == CF_PALETTE) */ { HPALETTE hpal; // Verify caller asked for correct medium if (!(pformatetcIn->tymed & TYMED_GDI)) { sc = DATA_E_FORMATETC; goto error; } hpal = DibCreatePalette(lpbi); pmedium->hGlobal = hpal; pmedium->tymed = TYMED_GDI; DPF("Building CF_PALETTE data: hpal = %p\n", (UINT_PTR) hpal); } } else if (pformatetcIn->cfFormat == CF_WAVE) { LONG cbFormat; AVISTREAMINFOW strhdr; #define formtypeWAVE mmioFOURCC('W', 'A', 'V', 'E') #define ckidWAVEFORMAT mmioFOURCC('f', 'm', 't', ' ') #define ckidWAVEDATA mmioFOURCC('d', 'a', 't', 'a') DPF("Building CF_WAVE data\n"); AVIFileGetStream(lpc->pf, &ps, streamtypeAUDIO, 0L); if (!ps) { sc = E_FAIL; goto error; } AVIStreamInfoW(ps, &strhdr, sizeof(strhdr)); AVIStreamReadFormat(ps, strhdr.dwStart, NULL, &cbFormat); cb = strhdr.dwLength * strhdr.dwSampleSize + cbFormat + 5 * sizeof(DWORD) + 2 * sizeof(DWORD); pmedium->hGlobal = GlobalAlloc(GHND | GMEM_SHARE, cb); if (!pmedium->hGlobal) { sc = E_OUTOFMEMORY; goto error; } lp = GlobalLock(pmedium->hGlobal); *((DWORD _huge *)lp)++ = FOURCC_RIFF; *((DWORD _huge *)lp)++ = cb - 2 * sizeof(DWORD); *((DWORD _huge *)lp)++ = formtypeWAVE; *((DWORD _huge *)lp)++ = ckidWAVEFORMAT; *((DWORD _huge *)lp)++ = cbFormat; AVIStreamReadFormat(ps, strhdr.dwStart, lp, &cbFormat); lp = (BYTE _huge *) lp + cbFormat; cb = strhdr.dwLength * strhdr.dwSampleSize; *((DWORD UNALIGNED _huge *)lp)++ = ckidWAVEDATA; *((DWORD UNALIGNED _huge *)lp)++ = cb; AVIStreamRead(ps, strhdr.dwStart, strhdr.dwLength, lp, cb, NULL, NULL); GlobalUnlock(pmedium->hGlobal); pmedium->tymed = TYMED_HGLOBAL; } else { sc = DATA_E_FORMATETC; //goto error; } error: if (pgf) AVIStreamGetFrameClose(pgf); if (ps) AVIStreamClose(ps); DPF2("GetData returns %lx\n", (DWORD) sc); return ResultFromScode(sc); } STDMETHODIMP AVIClipGetDataHere(LPDATAOBJECT lpd, LPFORMATETC pformatetc, LPSTGMEDIUM pmedium ) { LPAVICLIP lpc = (LPAVICLIP) lpd; return ResultFromScode(DATA_E_FORMATETC); } STDMETHODIMP AVIClipQueryGetData(LPDATAOBJECT lpd, LPFORMATETC pformatetc ) { LPAVICLIP lpc = (LPAVICLIP) lpd; PAVISTREAM ps = NULL; // set defaults for passing to AVIFileGetStream UINT type = TYMED_HGLOBAL; // except for CF_PALETTE FOURCC streamtype = streamtypeVIDEO; // except for CF_WAVE switch (pformatetc->cfFormat) { case CF_PALETTE: type = TYMED_GDI; break; case CF_DIB: // everything is set up break; case CF_WAVE: streamtype = streamtypeAUDIO; break; default: return ResultFromScode(DATA_E_FORMATETC); } AVIFileGetStream(lpc->pf, &ps, streamtype, 0L); if (ps) { ps->lpVtbl->Release(ps); if (pformatetc->tymed & type) { return NOERROR; } } return ResultFromScode(DATA_E_FORMATETC); } STDMETHODIMP AVIClipGetCanonicalFormatEtc(LPDATAOBJECT lpd, LPFORMATETC pformatetc, LPFORMATETC pformatetcOut) { LPAVICLIP lpc = (LPAVICLIP) lpd; return ResultFromScode(E_NOTIMPL); } STDMETHODIMP AVIClipSetData(LPDATAOBJECT lpd, LPFORMATETC pformatetc, STGMEDIUM FAR * pmedium, BOOL fRelease) { LPAVICLIP lpc = (LPAVICLIP) lpd; return ResultFromScode(E_FAIL); } STDMETHODIMP AVIClipEnumFormatEtc(LPDATAOBJECT lpd, DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc) { LPAVICLIP lpc = (LPAVICLIP) lpd; SCODE sc = S_OK; if (dwDirection == DATADIR_GET) { // Build an enumerator.... *ppenumFormatEtc = OleStdEnumFmtEtc_Create( lpc->wFormats, lpc->lpFormats); if (*ppenumFormatEtc == NULL) sc = E_OUTOFMEMORY; } else if (dwDirection == DATADIR_SET) { /* OLE2NOTE: a document that is used to transfer data ** (either via the clipboard or drag/drop does NOT ** accept SetData on ANY format! */ sc = E_NOTIMPL; goto error; } else { sc = E_INVALIDARG; goto error; } error: return ResultFromScode(sc); } STDMETHODIMP AVIClipDAdvise(LPDATAOBJECT lpd, FORMATETC FAR* pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD FAR* pdwConnection) { LPAVICLIP lpc = (LPAVICLIP) lpd; return ResultFromScode(OLE_E_ADVISENOTSUPPORTED); } STDMETHODIMP AVIClipDUnadvise(LPDATAOBJECT lpd, DWORD dwConnection) { LPAVICLIP lpc = (LPAVICLIP) lpd; return ResultFromScode(OLE_E_ADVISENOTSUPPORTED); } STDMETHODIMP AVIClipEnumDAdvise(LPDATAOBJECT lpd, LPENUMSTATDATA FAR* ppenumAdvise) { LPAVICLIP lpc = (LPAVICLIP) lpd; return ResultFromScode(OLE_E_ADVISENOTSUPPORTED); } #if OWNER_DISPLAY /************************************************************************** * @doc INTERNAL AVIFILE * * @api ClipboardWindowProc * *************************************************************************/ static LRESULT CALLBACK _loadds ClipboardWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LONG lParam) { WNDPROC x; HWND hwndViewer; PAINTSTRUCT ps; RECT rc; LPAVICLIP lpc; switch (msg) { case WM_DESTROY: case WM_DESTROYCLIPBOARD: DPF("WM_DESTROYCLIPBOARD\n"); x = OldClipboardWindowProc; SetWindowLong(hwnd, GWL_WNDPROC, (LONG)x); OldClipboardWindowProc = NULL; return (*x)(hwnd, msg, wParam, lParam); case WM_RENDERFORMAT: DPF("WM_RENDERFORMAT cf=%d\n", (int)wParam); break; case WM_PAINTCLIPBOARD: DPF("WM_PAINTCLIPBOARD\n"); hwndViewer = (HWND)wParam; if (!lParam) break; lpc = lpcClipboard; if (lpc == NULL) break; ps = *(LPPAINTSTRUCT)GlobalLock((HGLOBAL)lParam); FillRect(ps.hdc, &ps.rcPaint, GetStockObject(DKGRAY_BRUSH)); GlobalUnlock((HGLOBAL) lParam); return 0; break; case WM_SIZECLIPBOARD: DPF("WM_SIZECLIPBOARD\n"); hwndViewer = (HWND)wParam; lpc = lpcClipboard; if (lpc == NULL) break; if (lParam) rc = *(LPRECT)GlobalLock((HGLOBAL)lParam); else SetRectEmpty(&rc); if (IsRectEmpty(&rc)) { } else { } break; case WM_VSCROLLCLIPBOARD: case WM_HSCROLLCLIPBOARD: DPF("WM_VHSCROLLCLIPBOARD\n"); hwndViewer = (HWND)wParam; break; case WM_ASKCBFORMATNAME: DPF("WM_ASKCBFORMATNAME\n"); break; } return OldClipboardWindowProc(hwnd, msg, wParam, lParam); } #endif