ID Number: Q83023
3.10
WINDOWS
Summary:
A metafile is one of the presentation formats that can be used by an
object linking and embedding (OLE) server application. A server
application must prepare data in the presentation format under two
circumstances:
- When the user copies an object to the clipboard, using the Copy
command from the Edit menu
- When the OLE libraries call the GetData method
If the server creates a metafile as the presentation format, it must
follow the restrictions regarding mapping mode and object size set by
the OLE libraries. Then the server creates a METAFILEPICT structure
containing the data. This article describes the steps required for
this task.
More Information:
METAFILEPICT Structure
----------------------
When an application creates a metafile to use with the OLE libraries
or with the clipboard, all interactions occur through the METAFILEPICT
data structure, which is defined as follows:
typedef struct tagMETAFILEPICT
{
int mm; // Mapping mode
int xExt, yExt; // Horizontal and vertical size
HANDLE hMF; // Handle to the metafile
} METAFILEPICT;
The mapping mode for the metafile must be MM_ANISOTROPIC, which
ensures that the object will scale properly when the client
application displays it. However, the OLE libraries store a size for
the object that is specified in MM_HIMETRIC units [0.01 millimeter
(mm)]. The maximum size of an object is 327.67 mm by 327.67 mm.
The application obtains the handle to the metafile by calling the
CreateMetaFile function with NULL as the lpFilename parameter. Doing
so creates a memory-based metafile.
Fonts
-----
A server application should use a TrueType font whenever possible in a
metafile. This is important because the user can scale the object to
many different sizes in the client application and TrueType fonts
scale well under a variety of conditions. To specify a TrueType font,
set bit 2 (04h) of the lfPitchAndFamily member in the LOGFONT data
structure.
Creating the Metafile
---------------------
The following eleven steps present the procedure to create a metafile
compatible with the OLE libraries:
1. Retrieve a metafile device context (DC).
hMetaDC = CreateMetaFile(NULL);
2. Call the SetWindowOrg function to set the origin to (0, 0).
SetWindowOrg(hMetaDC, 0, 0);
3. Call the SetWindowExt function specifying the width and the height
of the object.
SetWindowExt(hMetaDC, ObjWidth, ObjHeight);
4. Draw the object in the metafile DC.
DrawObject(hMetaDC, lpObject); // Application-specific function
// that draws the object into an
// arbitrary DC.
5. Close the metafile.
hMF = CloseMetaFile(hMetaDC);
6. Allocate a METAFILEPICT structure from global memory. Because this
memory will be shared between applications, the memory must
allocated with the GMEM_SHARE flag.
hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
sizeof(METAFILEPICT));
7. Lock the memory block to retrieve a pointer to the METAFILEPICT
structure (lpMFP).
lpMFP = (LPMETAFILEPICT)GlobalLock(hMem);
8. Set the mapping mode to MM_ANISOTROPIC.
lpMFP->mm = MM_ANISOTROPIC;
9. Convert the object width and height into MM_HIMETRIC units. Fill
in the METAFILEPICT data structure with the information.
pt.x = ObjWidth;
pt.y = ObjHeight;
hDC = GetDC(hWnd); // Borrow a DC from the main window.
oldMapMode = SetMapMode(hDC, MM_HIMETRIC);
DPtoLP(hDC, &pt, 1);
SetMapMode(hDC, oldMapMode);
ReleaseDC(hWnd, hDC);
lpMFP.xExt = pt.x;
lpMFP.yExt = pt.y;
10. Put the metafile handle into the METAFILEPICT data structure.
lpMFP->hMF = hMF;
11. Unlock the memory block and use the handle appropriately.
GlobalUnlock(hMem);
Additional reference words: 3.10