In the above example, the NULL parameter to CreateMetaFile meant that we wanted to create a metafile stored in memory. We can also create a metafile stored on the disk as a normal file. This method is preferred for large metafiles because it uses less memory space. Windows has to maintain a relatively small area in memory to store the name of the file containing the metafile. On the other hand, a metafile stored on disk requires a disk access every time you play it.
Let's use the example of the company logo again. In addition to the variables shown above, you'll need a variable to store the filename of the metafile:
static char szFileName [80] ;
In this example, we'll use a temporary file. During processing of the WM_CREATE message, you can create a filename for a temporary file using the Windows GetTempFileName function:
GetTempFileName (0, MF, 0, szFileName) ;
Windows first checks the TEMP variable in the MS-DOS environment to select a disk and subdirectory for this file. If there is no TEMP variable in the MS-DOS environment, Windows uses the root directory of the first fixed disk. The filename begins with a tilde (~) followed by the characters we've specified in the GetTempFileName function (MF) and a unique number; the extension is .TMP. On return from the call, the filename is stored in the szFileName array.
We create the metafile device context using this filename:
hMetaDC = CreateMetaFile (szFileName) ;
We can write to this device context just as we did in the original example and then close the metafile device context to get the metafile handle:
hmf = CloseMetaFile (hdcMeta) ;
The processing of the WM_PAINT message is the same as in the original example. However, during processing of the WM_DESTROY message, you'll have to add something. The statement:
DeleteMetaFile (hmf) ;
deletes the area of memory that references the metafile handle to the disk file, but the disk file still exists. You should also delete that file using the normal C function:
unlink (szFileName) ;
Here's another way to use disk-based metafiles. This method doesn't require that you maintain hmf as a static variable. First, you get a temporary filename and create the metafile device context as before:
GetTempFileName (0, MF, 0, szFileName) ;
hdcMeta = CreateMetaFile (szFileName) ;
Now you draw on the metafile device context. When you're finished, you can close the device context and get a handle to the metafile:
hmf = CloseMetaFile (hdcMeta) ;
But now you also delete the metafile:
DeleteMetaFile (hmf) ;
Do we really want to do this? We might. Deleting a disk-based metafile invalidates the metafile handle, freeing the memory required for the metafile but leaving the disk file intact. During processing of the WM_PAINT message, you can get a metafile handle to this disk file by calling GetMetaFile:
hmf = GetMetaFile (szFileName) ;
Now you can play this metafile just as before. When processing of the WM_PAINT message is over, you can delete the metafile handle:
DeleteMetaFile (hmf) ;
When it comes time to process the WM_DESTROY message, you don't have to delete the metafile, because it was deleted at the end of the WM_CREATE message and at the end of each WM_PAINT message. But you still should delete the disk file:
unlink (szFileName) ;