Microsoft Knowledge Base Article
This article contents is Microsoft Copyrighted material.
©2005-©2007 Microsoft Corporation. All rights reserved.
Terms
of Use |
Trademarks
Article ID: 230675 - Last Review: January 24, 2007 - Revision: 2.6
How To Draw on a Pre-Existing Enhanced Metafile
This article was previously published under 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:
- Load the source EMF using GetEnhMetaFile().
- Calculate the size of the source EMF from its header.
- Create a new EMF DC that is the same size as the original.
- 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;
}
For additional information about how to read all kinds of metafiles, please see the following
article in the Microsoft Knowledge Base:
145999Â
(http://kbalertz.com/Feedback.aspx?kbNumber=145999/EN-US/
)
SAMPLE: How to Create & Play Enhanced Metafiles in Win32
APPLIES TO
- Microsoft Windows 2000 Server
- Microsoft Windows 2000 Advanced Server
- Microsoft Windows 2000 Professional Edition
- Microsoft Platform Software Development Kit-January 2000 Edition
- Microsoft Windows NT Server 3.51
- Microsoft Windows NT Workstation 4.0 Developer Edition
- Microsoft Windows 95
- Microsoft Windows 98 Standard Edition
- Microsoft Windows 98 Second Edition
- Microsoft Windows XP Home Edition
- Microsoft Windows XP Professional
- the operating system: Microsoft Windows XP 64-Bit Edition
| kbhowto kbmetafile kbgdi kbfaq kbdswgdi2003swept KB230675 |
Community Feedback System
Very often, it takes hours to solve a problem. Very often, you've looked high
and low, and have tried a lot of solutions. When you finally found it, chances
are, it was because someone else helped you. Here's your chance to give back.
Use our community feedback tool to let others know what worked for you and what
didn't.
Please also understand that the community feedback system is not warranted to be
correct, it's simply a system that we've built to let people try and help each
other. If something in a feedback response doesn't make sense to you, or you're
not comfortable making changes that the feedback talks about (like registry
edits), please consult a professional.
Thank you for using kbAlertz.com Feedback System.
-- Scott Cate