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.
541 lines
11 KiB
541 lines
11 KiB
|
|
/*****************************************************************************
|
|
|
|
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 <windows.h>
|
|
|
|
#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;
|
|
}
|