HOWTO: Draw on a Pre-Existing Enhanced MetafileID: Q230675
|
Sometimes it is desirable to draw on the surface of a pre-existing enhanced metafile. Unfortunately, the GetEnhMetaFile() API returns an HENHMETAFILE handle rather than a device context. This article shows how to create a device context that contains the contents of a disk-based EMF, and on which you can draw using normal GDI APIs.
The following steps show how to create a device context (DC) from a pre-existing EMF:
// This function returns an EMF HDC, on which has already been drawn the contents of the source EMF.
HDC MakeNewWritableMetafile( LPTSTR szSourceFileName, LPTSTR szTargetFileName )
{
HENHMETAFILE hSourceEMF;
HDC hTargetDC, hRefDC;
ENHMETAHEADER emh;
RECT Rect, rcSource;
float PixelsX, PixelsY, MMX, MMY;
// Get a reference DC. Normally, you'd get the highest resolution DC available,
// for example a printer DC. We just use a screen DC for this demonstration.
if( (hRefDC = GetDC( NULL )) == NULL )
return NULL;
// Open the source EMF
if( (hSourceEMF = GetEnhMetaFile( szSourceFileName )) == NULL )
{
ReleaseDC( NULL, hRefDC );
return NULL;
}
// Get the header from the enhanced metafile.
ZeroMemory( &emh, sizeof(ENHMETAHEADER) );
emh.nSize = sizeof(ENHMETAHEADER);
if( GetEnhMetaFileHeader( hSourceEMF, sizeof( ENHMETAHEADER ), &emh ) == 0 )
{
DeleteEnhMetaFile( hSourceEMF );
ReleaseDC( NULL, hRefDC );
return NULL;
}
// Get the characteristics of the output device.
PixelsX = (float)GetDeviceCaps( hRefDC, HORZRES );
PixelsY = (float)GetDeviceCaps( hRefDC, VERTRES );
MMX = (float)GetDeviceCaps( hRefDC, HORZSIZE );
MMY = (float)GetDeviceCaps( hRefDC, VERTSIZE );
// Calculate the rect in which to draw the metafile based on the
// intended size and the current output device resolution.
// Remember that the intended size is given in 0.01 mm units, so
// convert those to device units on the target device.
Rect.top = (int)((float)(emh.rclFrame.top) * PixelsY / (MMY*100.0f));
Rect.left = (int)((float)(emh.rclFrame.left) * PixelsX / (MMX*100.0f));
Rect.right = (int)((float)(emh.rclFrame.right) * PixelsX / (MMX*100.0f));
Rect.bottom = (int)((float)(emh.rclFrame.bottom) * PixelsY / (MMY*100.0f));
// Create the new metafile the same size as the old one.
SetRect( &rcSource, emh.rclFrame.left, emh.rclFrame.top, emh.rclFrame.right, emh.rclFrame.bottom );
hTargetDC = CreateEnhMetaFile( hRefDC, szTargetFileName, &rcSource, "Desc\0Desc\0\0" );
// Play the old metafile on to the new one.
PlayEnhMetaFile( hTargetDC, hSourceEMF, &Rect );
// Clean up.
DeleteEnhMetaFile( hSourceEMF );
ReleaseDC( NULL, hRefDC );
return hTargetDC;
}
For additional information about how to read all kinds of metafiles, please see the following article in the Microsoft Knowledge Base:
Q145999 SAMPLE: How to Create & Play Enhanced Metafiles in Win32
Additional query words: enhanced metafile emf wmf
Keywords : kbGDI kbMetafile kbSDKWin32 kbGrpGDI
Version : WINDOWS:95,98,98 Second Edition; winnt:
Platform : WINDOWS winnt
Issue type : kbhowto
Last Reviewed: May 7, 1999