typedef struct _CLPBRDDATA // INFORMATION ABOUT A CLIPBOARD FORMAT
{
ULONG ulFormat; // The format type
PVOID pvData; // Pointer to the data for this format
} CLPBRDDATA, *PCLPBRDDATA;
//***************
// Save formats
//***************
INT SaveClipboardData( HAB hab, PCLPBRDDATA *ppcd )
{
INT iFmtCount = 0;
if( WinOpenClipbrd( hab ) )
{
ULONG ulNextFmt, ulPrevFmt = 0;
ulNextFmt = WinEnumClipbrdFmts( hab, ulPrevFmt );
while( ulNextFmt )
{
iFmtCount++;
ulPrevFmt = ulNextFmt;
ulNextFmt = WinEnumClipbrdFmts( hab, ulPrevFmt );
}
if( iFmtCount )
{
*ppcd = (PCLPBRDDATA) malloc( sizeof( CLPBRDDATA ) * iFmtCount );
if( *ppcd )
{
memset( *ppcd, 0, sizeof( CLPBRDDATA ) * iFmtCount );
if( !GetClipboardFmts( hab, *ppcd ) )
iFmtCount = 0;
}
else
{
iFmtCount = 0;
Msg( "Out of memory in SaveClipboardData" );
}
}
WinCloseClipbrd( hab );
}
else
Msg( "SaveClipboardData could not open the clipboard" );
return iFmtCount;
}
BOOL GetClipboardFmts( HAB hab, PCLPBRDDATA pcd )
{
BOOL fSuccess = TRUE;
ULONG ulNextFmt, ulPrevFmt = 0;
ulNextFmt = WinEnumClipbrdFmts( hab, ulPrevFmt );
while( ulNextFmt )
{
pcd->ulFormat = ulNextFmt;
switch( ulNextFmt )
{
case CF_TEXT:
StoreClipboardText( hab, pcd );
break;
case CF_BITMAP:
StoreClipboardBmp( hab, pcd );
break;
case CF_METAFILE:
StoreClipboardMeta( hab, pcd );
break;
default:
break;
}
pcd++;
ulPrevFmt = ulNextFmt;
ulNextFmt = WinEnumClipbrdFmts( hab, ulPrevFmt );
}
return fSuccess;
}
VOID StoreClipboardText( HAB hab, PCLPBRDDATA pcd )
{
PSZ szClipText = (PSZ) WinQueryClipbrdData( hab, CF_TEXT );
if( szClipText )
{
pcd->pvData = malloc( strlen( szClipText ) + 1 );
if( pcd->pvData )
strcpy( pcd->pvData, szClipText );
else
Msg( "Out of memory in StoreClipboardText" );
}
else
Msg( "StoreClipboardText found no TEXT in the clipboard" );
}
VOID StoreClipboardBmp( HAB hab, PCLPBRDDATA pcd )
{
HBITMAP hbmClip = WinQueryClipbrdData( hab, CF_BITMAP );
if( hbmClip )
pcd->pvData = (PVOID) CopyBitmap( hab, hbmClip );
else
Msg( "StoreClipboardBmp found no BITMAP in the clipboard" );
}
VOID StoreClipboardMeta( HAB hab, PCLPBRDDATA pcd )
{
HMF hmfClip = WinQueryClipbrdData( hab, CF_METAFILE );
if( hmfClip )
{
HMF hmfNew = GpiCopyMetaFile( hmfClip );
if( hmfNew == GPI_ERROR )
Msg( "StoreClipboardMeta GpiCopyMetaFile RC = %x",
(USHORT) WinGetLastError( hab ) );
else
pcd->pvData = (PVOID) hmfNew;
}
else
Msg( "StoreClipboardMeta found no METAFILE in the clipboard" );
}
//******************
// Restore formats
//******************
VOID RestClipboardData( HAB hab, INT iFmtCount, PCLPBRDDATA pcd )
{
PCLPBRDDATA pcdSave = pcd;
INT i;
BOOL fFormatsExist = FALSE;
for( i = 0; i < iFmtCount; i++, pcd++ )
{
if( pcd->ulFormat && pcd->pvData )
{
fFormatsExist = TRUE;
break;
}
}
pcd = pcdSave;
if( fFormatsExist )
if( WinOpenClipbrd( hab ) )
{
WinEmptyClipbrd( hab );
for( i = 0; i < iFmtCount; i++, pcd++ )
{
switch( pcd->ulFormat )
{
case 0:
break;
case CF_TEXT:
if( pcd->pvData )
{
RestClipboardText( hab, pcd->pvData );
free( pcd->pvData );
}
break;
case CF_BITMAP:
if( pcd->pvData )
RestClipboardBmp( hab, (HBITMAP) pcd->pvData );
break;
case CF_METAFILE:
if( pcd->pvData )
RestClipboardMeta( hab, (HMF) pcd->pvData );
break;
default:
break;
}
}
WinCloseClipbrd( hab );
}
else
Msg( "RestClipboardData could not open the clipboard" );
free( pcdSave );
}
VOID RestClipboardText( HAB hab, PSZ szTextIn )
{
PSZ szTextOut = NULL;
ULONG ulRC =
DosAllocSharedMem( (PVOID) &szTextOut, NULL,
strlen( szTextIn ) + 1,
PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE );
if( !ulRC )
{
strcpy( szTextOut, szTextIn );
if( !WinSetClipbrdData( hab, (ULONG) szTextOut, CF_TEXT,
CFI_POINTER ) )
Msg( "RestClipboardText WinSetClipbrdData failed" );
}
else
Msg( "RestClipboardText DosAllocSharedMem RC: %u", ulRC );
}
VOID RestClipboardBmp( HAB hab, HBITMAP hbm )
{
if( !WinSetClipbrdData( hab, (ULONG) hbm, CF_BITMAP, CFI_HANDLE ) )
Msg( "RestClipboardBmp WinSetClipbrdData failed" );
}
VOID RestClipboardMeta( HAB hab, HMF hmf )
{
if( !WinSetClipbrdData( hab, (ULONG) hmf, CF_METAFILE, CFI_HANDLE ) )
Msg( "RestClipboardMeta WinSetClipbrdData failed" );
}
HBITMAP CopyBitmap( HAB hab, HBITMAP hbmIn )
{
BITMAPINFOHEADER2 bmih;
HBITMAP hbmOut = NULLHANDLE;
HDC hdcIn = NULLHANDLE, hdcOut = NULLHANDLE;
HPS hpsIn = NULLHANDLE, hpsOut = NULLHANDLE;
POINTL aptl[ 3 ];
SIZEL sizel = {0,0};
hdcIn = DevOpenDC( hab, OD_MEMORY, "*", 0, NULL, NULLHANDLE );
if( !hdcIn )
{
Msg( "CopyBitmap DevOpenDC for hdcIn RC = %x",
(USHORT) WinGetLastError( hab ) );
goto BYEBYE;
}
hdcOut = DevOpenDC( hab, OD_MEMORY, "*", 0, NULL, NULLHANDLE );
if( !hdcOut )
{
Msg( "CopyBitmap DevOpenDC for hdcOut RC = %x",
(USHORT) WinGetLastError( hab ) );
goto BYEBYE;
}
hpsIn = GpiCreatePS( hab, hdcIn, &sizel,PU_PELS |
GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC );
if( !hpsIn )
{
Msg( "CopyBitmap GpiCreatePS for hpsIn RC = %x",
(USHORT) WinGetLastError( hab ) );
goto BYEBYE;
}
hpsOut = GpiCreatePS( hab, hdcOut, &sizel,PU_PELS |
GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC );
if( !hpsOut )
{
Msg( "CopyBitmap GpiCreatePS for hpsOut RC = %x",
(USHORT) WinGetLastError( hab ) );
goto BYEBYE;
}
bmih.cbFix = sizeof( BITMAPINFOHEADER2 );
if( !GpiQueryBitmapInfoHeader( hbmIn, &bmih ) )
{
Msg( "CopyBitmap GpiQueryBitmapInfoHeader for hbmIn RC = %x",
(USHORT) WinGetLastError( hab ) );
goto BYEBYE;
}
hbmOut = GpiCreateBitmap( hpsOut, &bmih, 0, NULL, NULL );
if( hbmOut )
{
if( HBM_ERROR == GpiSetBitmap( hpsIn, hbmIn ) )
{
Msg( "CopyBitmap GpiSetBitmap for hpsIn RC = %x",
(USHORT) WinGetLastError( hab ) );
hbmOut = NULLHANDLE;
goto BYEBYE;
}
if( HBM_ERROR == GpiSetBitmap( hpsOut, hbmOut ) )
{
Msg( "CopyBitmap GpiSetBitmap for hpsOut RC = %x",
(USHORT) WinGetLastError( hab ) );
hbmOut = NULLHANDLE;
goto BYEBYE;
}
aptl[ 0 ].x = 0;
aptl[ 0 ].y = 0;
aptl[ 1 ].x = bmih.cx;
aptl[ 1 ].y = bmih.cy;
aptl[ 2 ].x = 0;
aptl[ 2 ].y = 0;
if( GPI_ERROR == GpiBitBlt( hpsOut, hpsIn, 3, aptl, ROP_SRCCOPY,
BBO_IGNORE ) )
{
Msg( "CopyBitmap GpiBitBlt for hpsOut RC = %x",
(USHORT) WinGetLastError( hab ) );
hbmOut = NULLHANDLE;
}
}
else
Msg( "CopyBitmap GpiCreateBitmap for hbmOut RC = %x",
(USHORT) WinGetLastError( hab ) );
BYEBYE:
if( hpsIn )
GpiDestroyPS( hpsIn );
if( hpsOut )
GpiDestroyPS( hpsOut );
if( hdcIn )
DevCloseDC( hdcIn );
if( hdcOut )
DevCloseDC( hdcOut );
return hbmOut;
}
Credit: Rick Fishman