Microsoft KB Archive/230675

{|
 * width="100%"|

HOWTO: Draw on a Pre-Existing Enhanced Metafile

 * }

Q230675

-

The information in this article applies to:


 * Microsoft Win32 Software Development Kit (SDK)
 * Microsoft Windows NT Server
 * Microsoft Windows NT Workstation
 * Microsoft Windows 95
 * Microsoft Windows 98
 * Microsoft Windows 98 Second Edition
 * Microsoft Windows 2000 Advanced Server
 * Microsoft Windows 2000 Server
 * Microsoft Windows 2000 Professional

-

SUMMARY
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.

MORE INFORMATION
The following steps show how to create a device context (DC) from a pre-existing EMF:


 * 1) Load the source EMF using GetEnhMetaFile.
 * 2) Calculate the size of the source EMF from its header.
 * 3) Create a new EMF DC that is the same size as the original.
 * 4) Play the source EMF on to the new DC.

The following code demonstrates this approach:

// 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; }