INF: Creating Metafiles to Use with OLE Applications

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