Microsoft KB Archive/145999

{|
 * width="100%"|

How to Create & Play Enhanced Metafiles in Win32

 * }

Q145999

-

The information in this article applies to:


 * Microsoft Win32 Software Development Kit (SDK)
 * Microsoft Windows 2000 Advanced Server
 * Microsoft Windows 2000 Server
 * Microsoft Windows 2000 Professional

-

SUMMARY
The Win32 SDK introduces a new type of metafile known as an enhanced metafile. These new metafiles address developer's need for device independence without requiring a separate code path, which was a requirement of the older style metafiles.

This article and the accompanying sample (ENMETA.EXE) show you how to properly create and play enhanced metafiles scaled or to original size. The sample also supports the clipboard and reads and writes Aldus placeable metafiles as well as regular 16-bit Windows metafiles.

MORE INFORMATION
The following file is available for download from the Microsoft Download Center:

"Enmeta.exe" For additional information about how to download Microsoft Support files, click the article number below to view the article in the Microsoft Knowledge Base:

"Q119591 How to Obtain Microsoft Support Files from Online Services" Microsoft used the most current virus detection software available on the date of posting to scan this file for viruses. Once posted, the file is housed on secure servers that prevent any unauthorized changes to the file.

Creating the Enhanced Metafile
An enhanced metafile is created with a call to CreateEnhMetaFile. CreateEnhMetaFile is declared as follows:

  HDC CreateEnhMetaFile( HDC hdcRef, LPCTSTR lpFilename,

CONST RECT *lpRect, LPCTSTR lpDescription ); Following are the parameters to this call:

hdcRef is a reference DC and provides some crucial reference information for the construction of the metafile. The resolutions in both pixels and millimeters are taken from this device, and all font metrics are based on this DC. For the best possible reproduction on all output devices, it is a good idea to choose a high resolution device for the reference device. Otherwise, some grainyness may appear if the output device is of considerably higher resolution than the reference device.

lpFileName is the name of the file that will contain the metafile. If this parameter is NULL, the metafile is a memory metafile and is not stored on disk.

lpRect is a rectangle that specifies the dimensions in 0.01 mm units of the virtual metafile device. This rectangle is stored in the metafile and can be retrieved at play time to determine the desired real size of the output. Although no clipping is performed for this rectangle, some metafile players may presume that the image in the metafile fits in the rectangle.

lpDescription simply provides a way to store the name of the application that created the metafile as well as a description of the contents in the form of two NULL-terminated strings, terminated with an additional NULL as in this example:

  App\0Description\0\0 App is the name of the application that created the metafile and Description is a description of the image.

The Metafile Device
The metafile device has a real size defined by the lpRect parameter in 0.01 mm units. The number of device units on the metafile can be determined by using the pixel/mm ratio of the reference DC and the metafile device size given in the lpRect parameter. For example:

  MetaPixelsX = MetaWidthMM * MetaPixels / (MetaMM * 100);

where MetaPixelsX = number of pixels on the X axis MetaWidthMM = metafile width in 0.01mm units MetaPixels = width in pixels of the reference device MetaMM     = width in millimeters of the reference device A similar calculation can be used to determine the number of pixels in the Y direction of the metafile device.

Note that although the metafile device has a real size, it does not clip output to that region. It is entirely possible to record drawing commands that have output outside of the metafile device surface.

Playing the Enhanced Metafile
The metafile device provides only half of the mapping from metafile space to target device space. The other half is provided by the RECT passed to the PlayEnhMetaFile call. It specifies a play rectangle in which to play the metafile and is specified in logical coordinates on the target device context. The metafile device rectangle is mapped to this play rectangle. This provides the scalability of enhanced metafiles; adjusting the play rectangle adjusts the size of the output. No clipping is performed on the play rectangle.

So, neither the metafile device nor the play rectangle perform clipping. This means that if any drawing commands were recorded to occur outside the metafile device, they will be shown outside the play rectangle when the metafile is played. This mapping is illustrated in the Sample1.emf sample enhanced metafile.

If the goal is to play the metafile at its true size, the size of the original metafile device can be determined by a call to GetEnhMetaFileHeader. This call fills in an ENHMETAHEADER structure, of which the rclFrame member specifies the metafile device rectangle in 0.01 mm units. That rectangle can be translated into logical units for the target DC and used as the lpRect parameter for PlayEnhMetaFile. The PlayEnhMetaFileAtOriginalSize function in the sample demonstrates this.

Mapping Modes
During the recording of the metafile, the mapping mode, window extents and origin, and viewport extents and origin combine to map logical units to device units on the metafile device. As with a normal DC, the window extents and origin define the logical space, while the viewport extents and origin are relative to the metafile device units described above.

For example: The following code creates an enhanced metafile that is dwInchesX wide by dwInchesY tall with dwDPI logical Dots Per Inch (DPI):

  HDC MyCreateEnhMetaFile( LPTSTR szFileName,  // Metafile filename                            DWORD dwInchesX,    // Width in inches                            DWORD dwInchesY,    // Height in inches                            DWORD dwDPI )       // DPI (logical units) {      RECT   Rect = { 0, 0, 0, 0 }; TCHAR  szDesc[] = "AppName\0Image Description\0\0"; HDC     hMetaDC, hScreenDC; float  PixelsX, PixelsY, MMX, MMY;

// dwInchesX x dwInchesY in .01mm units SetRect( &Rect, 0, 0, dwInchesX*2540, dwInchesY*2540 );

// Get a Reference DC      hScreenDC = GetDC( NULL );

// Get the physical characteristics of the reference DC      PixelsX = (float)GetDeviceCaps( hScreenDC, HORZRES ); PixelsY = (float)GetDeviceCaps( hScreenDC, VERTRES ); MMX = (float)GetDeviceCaps( hScreenDC, HORZSIZE ); MMY = (float)GetDeviceCaps( hScreenDC, VERTSIZE );

// Create the Metafile hMetaDC = CreateEnhMetaFile(hScreenDC, szFileName, &Rect, szDesc); // Release the reference DC      ReleaseDC( NULL, hScreenDC ); // Did you get a good metafile? if( hMetaDC == NULL ) return NULL;

// Anisotropic mapping mode SetMapMode( hMetaDC, MM_ANISOTROPIC ); // Set the Windows extent SetWindowExtEx( hMetaDC, dwInchesX*dwDPI, dwInchesY*dwDPI, NULL );

// Set the viewport extent to reflect // dwInchesX" x dwInchesY" in device units SetViewportExtEx( hMetaDC,                        (int)((float)dwInchesX*25.4f*PixelsX/MMX),                         (int)((float)dwInchesY*25.4f*PixelsY/MMY),                         NULL ); return hMetaDC; } Note that clipping is not performed by the window extents, viewport extents, or the metafile device. It is possible to draw beyond the window extents, which will map beyond the viewport extents. Those numbers provide only a ratio of logical units to metafile device units. Further, it is possible to have viewport extents that extend beyond the metafile surface. The drawing is not clipped to the metafile surface. This mapping is illustrated in the Sample2.emf sample enhanced metafile.

Palettes in Enhanced Metafiles
The SelectPalette API can be used to record a palette into an enhanced metafile. That palette can then be retrieved at play-time via the GetEnhMetaFilePaletteEntries API. This allows the player to faithfully reproduce palletized images and properly respond to palette messages. The GetEnhancedMetafilePalette function in the sample demonstrates extracting a palette from an enhanced metafile.

Note that if multiple palettes were used in recording the metafile, the palette entries retrieved by GetEnhMetaFilePaletteEntries()includes all the entries from all the palettes. If this includes more entries than the current display can reproduce, it is the player's responsibility to choose a subset of those colors from which to create the actual palette to be used during playback.

Additional query words: kbDSupport kbdsd kbGDI kbMetafile

Keywords : _IK kbfile kbsample kbOSWin2000 kbSDKWin32 kbGDIFAQ

Issue type : kbinfo

Technology : kbwin2000AdvServ kbwin2000AdvServSearch kbwin2000Serv kbwin2000ServSearch kbwin2000Search kbwin2000ProSearch kbwin2000Pro kbWin32SDKSearch kbAudDeveloper kbSDKSearch kbWinAdvServSearch kbWin32sSearch