/***************************************************************************** V I R T U A L C L I P B O A R D Name: vclpbrd.c Date: 21-Jan-1994 Creator: Unknown Description: This file contains the virtual clipboard routines. History: 21-Jan-1994 John Fu Reformat and cleanup 19-Apr-1994 John Fu Add code for DIB to BITMAP conversion. 13-Mar-1995 John Fu Fix code to delete clipboard formats. *****************************************************************************/ #define WIN31 #include #include "common.h" #include "clipbook.h" #include "clipbrd.h" #include "vclpbrd.h" #include "clipdsp.h" #include "ddeml.h" #include "debugout.h" #include "cvutil.h" /* * CreateVClipboard */ PVCLPBRD CreateVClipboard ( HWND hwnd) { PVCLPBRD p; if ( !( p = (PVCLPBRD)GlobalAlloc ( GPTR, sizeof(VCLPBRD) ))) { PERROR(TEXT("CreateVClipboard returning 0\n\r")); return NULL; } p->NumFormats = 0; p->Head = (PVCLPENTRY)NULL; p->Tail = (PVCLPENTRY)NULL; p->fOpen = FALSE; p->Hwnd = hwnd; // PINFO(TEXT("CreateVClipboard OK\n\r")); return p; } /* * DestroyVClipboard */ BOOL DestroyVClipboard ( PVCLPBRD p) { if (!p) { PERROR(TEXT("DestroyVClipboard on NULL Vclipboard\n\r")); return FALSE; } if (VEmptyClipboard ( p ) == FALSE) { PERROR(TEXT("DestroyVClipboard: couldn't empty Vclipboard\n\r")); return FALSE; } if (GlobalFree ( (HGLOBAL)p )) { PERROR(TEXT("DestroyVClipboard: GlobalFree failure\n\r")); return FALSE; } // PINFO(TEXT("DestroyVClipboard OK\n\r")); return TRUE; } /* * VCountClipboardFormats */ int VCountClipboardFormats ( PVCLPBRD p) { if ( !p ) return CountClipboardFormats(); return p->NumFormats; } /* * VEmptyClipboard */ BOOL VEmptyClipboard ( PVCLPBRD p) { PVCLPENTRY q, tmp; if ( !p ) return EmptyClipboard(); for ( q = p->Head; q; ) { tmp = q->Next; if ( q->Data ) switch ( q->Fmt ) { case CF_BITMAP: case CF_DIB: case CF_PALETTE: DeleteObject ( q->Data ); break; case CF_METAFILEPICT: case CF_ENHMETAFILE: DeleteEnhMetaFile (q->Data); break; default: GlobalFree ( q->Data ); } GlobalFree ( (HGLOBAL)q ); q = tmp; } p->NumFormats = 0; return TRUE; } /* * VEnumClipboardFormats */ UINT VEnumClipboardFormats( PVCLPBRD p, UINT Fmt) { PVCLPENTRY q; if ( !p ) return EnumClipboardFormats ( Fmt ); if ( !p->fOpen ) return 0; if ( Fmt == 0 ) return (p->Head)->Fmt; for (q = p->Head; q; q = q->Next) if ( q->Fmt == Fmt ) { if ( q->Next ) return q->Next->Fmt; else return 0; } return 0; } /* * VGetClipboardData */ HANDLE VGetClipboardData ( PVCLPBRD pvclp, UINT Fmt ) { PVCLPENTRY pEntry; HSZ hszFmt; TCHAR szFmt[CCHMAXCLPFORMAT]; HDDEDATA hFmtData; HANDLE hClipData; DWORD dwR; PINFO(TEXT("VGetClpData: %ld %d, "), pvclp, Fmt); if ( !pvclp ) { if (IsClipboardFormatAvailable( Fmt )) { hClipData = GetClipboardData ( Fmt ); if (!hClipData) dwR = GetLastError(); return hClipData; } else { PINFO(TEXT("No data on clp\r\n")); return NULL; } } if ( !pvclp->fOpen ) { PERROR(TEXT("!pvclp->fOpen\r\n")); return NULL; } for ( pEntry = pvclp->Head; pEntry; pEntry = pEntry->Next ) { if ( pEntry->Fmt == Fmt ) { if ( pEntry->Data ) { // PINFO(TEXT("pEntry->Data\r\n")); } else { // if (LockApp(TRUE, szGettingData )) // { // this is the biggie... GetClipboardName (Fmt, szFmt, sizeof (szFmt)); PINFO(TEXT("Asking for %s.\r\n"),szFmt); if (hszFmt = DdeCreateStringHandle(idInst, szFmt, 0)) { hFmtData = MySyncXact (NULL, 0L, GETMDIINFO(pvclp->Hwnd)->hVClpConv, hszFmt, MyGetFormat (szFmt, GETFORMAT_LIE), XTYP_REQUEST, LONG_SYNC_TIMEOUT, NULL); if ( hFmtData ) { PINFO(TEXT("Got it\r\n")); SetClipboardFormatFromDDE(pvclp->Hwnd, Fmt, hFmtData); } else { PERROR(TEXT("REQUEST for %s failed %x\n\r"), szFmt, DdeGetLastError(idInst)); VSetClipboardData(pvclp, Fmt, INVALID_HANDLE_VALUE); // LockApp ( FALSE, szNull ); // MessageBoxID ( hInst, hwndApp, IDS_DATAUNAVAIL, // IDS_APPNAME, MB_OK | MB_ICONEXCLAMATION ); } DdeFreeStringHandle(idInst, hszFmt); // can't find bitmap, see if we can get it from dib if (!hFmtData && Fmt == CF_BITMAP) { GetClipboardName (CF_DIB, szFmt, sizeof(szFmt)); if (hszFmt = DdeCreateStringHandle (idInst, szFmt, 0)) { hFmtData = MySyncXact (NULL, 0L, GETMDIINFO(pvclp->Hwnd)->hVClpConv, hszFmt, MyGetFormat (szFmt, GETFORMAT_LIE), XTYP_REQUEST, LONG_SYNC_TIMEOUT, NULL); if (hFmtData) SetClipboardFormatFromDDE(pvclp->Hwnd, DDE_DIB2BITMAP, hFmtData); DdeFreeStringHandle(idInst, hszFmt); } } // } // LockApp ( FALSE, szNull ); } else { PERROR(TEXT("app locked in vgetclipboarddata\n\r")); } } break; } } return (pEntry ? (INVALID_HANDLE_VALUE == pEntry->Data? NULL: pEntry->Data): NULL); } /* * VIsClipboardFormatAvailable */ BOOL VIsClipboardFormatAvailable ( PVCLPBRD p, UINT Fmt ) { PVCLPENTRY q; if ( !p ) { return IsClipboardFormatAvailable ( Fmt ); } else { for ( q = p->Head; q; q = q->Next ) { if ( q->Fmt == Fmt ) { return TRUE; } } } return FALSE; } /* * VSetClipboardData */ HANDLE VSetClipboardData( PVCLPBRD p, UINT Fmt, HANDLE Data) { PVCLPENTRY q; if ( !p ) { PINFO(TEXT("Setting real clipboard data \r\n")); return SetClipboardData ( Fmt, Data ); } if ( !p->fOpen ) { PERROR(TEXT("VSetClipboardData on non-open Vclipboard\n\r")); return NULL; } // existing format? for ( q = p->Head; q; q = q->Next ) { if (q->Fmt == Fmt) { if (q->Data) { switch (Fmt) { case CF_BITMAP: case CF_DIB: case CF_PALETTE: DeleteObject ( q->Data ); break; case CF_METAFILEPICT: case CF_ENHMETAFILE: DeleteEnhMetaFile (q->Data); break; default: GlobalFree ( q->Data ); } } q->Data = Data; PINFO(TEXT("VSetClipboardData: set same as existing format\n\r")); return Data; } } if (!(q = (PVCLPENTRY)GlobalAlloc (GPTR, sizeof (VCLPENTRY)))) { PERROR(TEXT("VSetClipboardData: GlobalAlloc failed\n\r")); return NULL; } q->Next = NULL; q->Data = Data; q->Fmt = Fmt; if ( p->Tail ) { p->Tail->Next = q; } p->Tail = q; if ( !p->Head ) p->Head = q; p->NumFormats++; PINFO(TEXT("VSetClipboardData: set new format w/%ldn\r"), Data); return Data; } /* * VOpenClipboard */ BOOL VOpenClipboard( PVCLPBRD p, HWND hwnd) { if ( !p ) { return SyncOpenClipboard ( hwnd ); } else if ( p->fOpen ) { return FALSE; } else { p->fOpen = TRUE; p->Hwnd = hwnd; return TRUE; } } /* * VCloseClipboard */ BOOL VCloseClipboard( PVCLPBRD p) { if ( !p ) return SyncCloseClipboard(); if ( !p->fOpen ) return FALSE; p->fOpen = FALSE; p->Hwnd = (HWND)0; return TRUE; }