|
Figure 1. Metafile in static control |
|
Figure 2. Metafile as background image |
Introduction
This article explains how to use the CMeta
class in a WTL
application. The sample project included with this article is a wizard-generated
dialog application enhanced with two static controls to display metafile images.
The About dialog demonstrates using a metafile as a background image. The class
supports both windows and enhanced metafiles and can load either resources or
disk files.
Metafiles
There are two types of metafile images: the older Windows Metafile (WMF) and
the newer Enhanced Metafile (EMF). WMF files are readily available as part of
clipart collections and are installed with several Microsoft products. EMF is
less popular but used internally in several software functions, such as print
previewers. Both types are scalable and support image transparency.
Using CMeta
CMeta
inherits from CEnhMetaFile
which is in the WTL
atlgdi.h header file. It adds support for loading both windows and
enhanced metafiles from either resource or disk file. For ease of use, windows
metafiles are converted to enhanced, upon load. After a metafile is loaded, it
can be assigned to a static or other control that supports enhanced metafiles.
These are the basic steps to display a metafile resource in a static control on
a dialog:
- Include Meta.h in the application .cpp
- Use the resource editor to import a Metafile (custom resource) to the project
- Add a
CMeta
member variable to the dialog class
- Load the metafile from resource in
OnInitDialog()
- Use the resource editor to add a static control to the dialog
- Set the static control type to Enhanced Metafile
- Use
SetEnhMetaFile()
to assign the metafile to the static
control
Here is example code from OnInitDialog()
showing how to load the
metafile image from resource:
m_meta.LoadMetaResource(IDR_BIRD, FALSE);
CStatic(GetDlgItem(IDC_STATIC1)).SetEnhMetaFile(m_meta);
A metafile can also be "played" onto a device context using
PlayEnhMetaFile()
after it is loaded from resource or disk. These
are the basic steps to play a metafile resource on a dialog's device context:
- Step 1 through 4 from above
- Use
PlayEnhMetaFile()
to (dis)play the metafile
The section "Background Image" later in this article explains how to set up
message handlers and play the metafile as a dialog background image. In the
sample project, this is demonstrated in the About dialog.
LoadMetaResource()
The LoadMetaResource()
method is used to load either an enhanced or windows
metafile resource. A resource is binary data that a resource compiler adds to an
application's executable file. There are standard resources, such as icons
and strings, and custom resources, which can be virtually anything. Both
types of metafiles are custom resources. Call the Custom Resource Type either
Metafile or EnhMetafile as appropriate when importing a metafile.
LoadMetaResource()
accepts a resource ID as input and sets the
m_hEMF
variable to the handle of the resultant metafile. A boolean
input parameter indicates whether the metafile is enhanced (TRUE
) or windows
(FALSE
).
LoadMetaFile()
LoadMetaFilee()
accepts a boolean input parameter to indicate
whether the metafile is enhanced (TRUE
) or windows (FALSE
). It also accepts an
optional file name and prompts the user with a standard file open dialog if no
file name parameter is supplied.
When you click the File button on the sample project's main dialog, it calls
the following method to load a disk-based metafile. m_left
is the
CMeta
member variable for the metafile used in the left static
control.
LRESULT OnFileOpen(WORD, WORD, HWND, BOOL&)
{
m_left.LoadMetaFile(m_hWnd, FALSE);
CStatic st(GetDlgItem(IDC_STATIC1));
st.SetEnhMetaFile(m_left);
st.Invalidate();
return 0; }
Background Image
An example of how to use a metafile as a background image is provided in the
About dialog of the sample project. The basic steps for how to "play" a metafile
were discussed earlier in the article. In addition to those steps, a
WM_ERASEBKGND
message is added to the dialog's message map and the
following handler is added to process the message. m_bkgnd
is the
CMeta
member variable and wParam
carries the dialog's
device context.
LRESULT OnEraseBkgnd(UINT, WPARAM wParam, LPARAM, BOOL&)
{
RECT rc;
GetClientRect(&rc);
::FillRect((HDC)wParam, &rc, (HBRUSH)(COLOR_BACKGROUND));
return ::PlayEnhMetaFile((HDC)wParam, m_bkgnd, &rc);
}
In addition, add WM_CTLCOLORSTATIC
to the message map and use
this message handler so that static controls transparently display over the
background image:
LRESULT OnCtlColorStatic(UINT, WPARAM wParam, LPARAM lParam, BOOL&)
{
SetBkMode((HDC)wParam, TRANSPARENT);
return (LRESULT)::GetStockObject(NULL_BRUSH);
}
Terms Of Use
The sample application and source code available with this article, is free
for any purpose.
THIS SOFTWARE IS DISTRIBUTED AS-IS, WITHOUT WARRANTIES OF ANY KIND.