Click here to Skip to main content
15,895,283 members
Articles / Desktop Programming / WTL

WTL Metafile Helper

Rate me:
Please Sign up or sign in to vote.
4.71/5 (3 votes)
12 Oct 20024 min read 76.5K   2.2K   17  
This article describes a helper class that can load metafiles from either resource or disk. It supports both windows and enhanced metafiles.
// Meta.h : include file for loading metafiles
// Version 1.0	October 10, 2002
// Copyright (C) 2002 Softgee.	All rights reserved.
//
// This extension to atlgdi.h is designed for use with the Windows
// Template Library (WTL). It supports loading windows and enhanced
// metafiles from resource or disk file.
//
// You may use this code in your own programs for free as long as the
// copyright notices are maintained. This software is provided "as-is"
// without warranty of any kind, either expressed or implied.
////////////////////////////////////////////////////////////////////////

#if !defined(_META_H_)
#define _META_H_

#pragma once

#include <atlgdi.h>

//////////////////////////////////////////////////////////
/* METAFILEHEADER (22 bytes) placeable metafile header. */
//////////////////////////////////////////////////////////
#include <pshpack2.h>
typedef struct tagMETAFILEHEADER {
	DWORD mfKey;	  // Magic number (always 0x9AC6CDD7)
	WORD mfHandle;	  // Metafile HANDLE number (always 0)
	WORD mfLeft;	  // Left coordinate in metafile units (twips)
	WORD mfTop;	  // Top coordinate in metafile units
	WORD mfRight;	  // Right coordinate in metafile units
	WORD mfBottom;	  // Bottom coordinate in metafile units
	WORD mfInch;	  // Number of metafile units per inch.
					  // Unscaled = 1440; 720 = 2:1; 2880 = 1:2; etc.
	DWORD mfReserved; // Reserved (always 0)
	WORD mfChecksum;  // Checksum value for previous 10 WORDs
} METAFILEHEADER, FAR *LPMETAFILEHEADER;
#include <poppack.h>


//template <class T>
class CMeta : public CEnhMetaFile 
{
public:
	BOOL CreateMeta(BOOL bEMF, DWORD dwSize, BYTE* pBytes)
	{
		BOOL bSuccess = FALSE;
		if (bEMF)
		{	// Enhanced Metafile
			LPENHMETAHEADER lpEMF = (LPENHMETAHEADER)pBytes;
			if (lpEMF->dSignature == ENHMETA_SIGNATURE)
			{
				m_hEMF = ::SetEnhMetaFileBits(dwSize, pBytes);
				if (m_hEMF != NULL) bSuccess = TRUE;
			}
		}
		else
		{	// Windows Metafile
			LPMETAFILEHEADER lpMF = (LPMETAFILEHEADER)pBytes;
			if (lpMF->mfKey == 0x9AC6CDD7)
			{
				dwSize -= sizeof(METAFILEHEADER);
				pBytes += sizeof(METAFILEHEADER);
				m_hEMF = ::SetWinMetaFileBits(dwSize, pBytes, NULL, NULL);
				if (m_hEMF != NULL) bSuccess = TRUE;
			}
		}
		return bSuccess;
	}

	void LoadMetaResource(_U_STRINGorID rsrcID, BOOL bEMF = TRUE)
	{
		TCHAR szType[12];
		if (bEMF) lstrcpy(szType, "ENHMETAFILE");
		else lstrcpy(szType, "METAFILE");

		// get a byte pointer to the resource
		HINSTANCE hInst = _Module.GetResourceInstance();
		HRSRC hRsrc = ::FindResource(hInst, rsrcID.m_lpstr, szType);
		ATLASSERT(hRsrc != NULL);
		HGLOBAL hGlobal = ::LoadResource(hInst, hRsrc);
		BYTE* pBytes = (BYTE*)::LockResource(hGlobal);

		// if bytes are valid, assign the metafile
		if (pBytes != NULL)
		{
			DWORD dwSize = ::SizeofResource(hInst, hRsrc);
			CreateMeta(bEMF, dwSize, pBytes);
		}
	}	

	void LoadMetaFile(BOOL bEMF = TRUE, LPCTSTR lpName = NULL)
	{
		BOOL bSuccess = FALSE;
		LPCTSTR lpFilters;
		TCHAR szName[_MAX_PATH];

		// launch file open dialog
		if (lpName == NULL)
		{
			if (bEMF)
				lpFilters = 
				_T("Enhanced MetaFiles (*.emf)\0*.emf\0All Files (*.*)\0*.*\0");
			else
				lpFilters = 
				_T("Windows MetaFiles (*.wmf)\0*.wmf\0All Files (*.*)\0*.*\0");


			CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, lpFilters, NULL);

			if (dlg.DoModal() == IDOK) lstrcpy(szName, dlg.m_szFileName);
			else return;
		}
		else lstrcpy(szName, lpName);

		// read the file
		HANDLE hFile = ::CreateFile(szName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
		if (hFile != INVALID_HANDLE_VALUE)
		{
		DWORD dwRead = 0;
			DWORD dwSize = ::GetFileSize(hFile, NULL);
			BYTE* pBytes = (BYTE*)::CoTaskMemAlloc(dwSize);
			if (pBytes != NULL && dwSize > 0)
			{
				if (::ReadFile(hFile, pBytes, dwSize, &dwRead, NULL))
					bSuccess = CreateMeta(bEMF, dwSize, pBytes);
			}
		}
		::CloseHandle(hFile);

		if (!bSuccess)
			::MessageBox(NULL, "Can't read file", "Error", MB_OK | MB_ICONERROR);
	}
};

#endif // !defined(_META_H_)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Founder Choycer
United States United States
Ed has over 40 years experience in computer technology and a bachelor's degree in Business Administration. He's currently a marketing technology consultant. During his career, he's led software development departments and created software still in use in the communications and healthcare industries. Ed is a veteran of the United States Army. He lives in Arizona in the United States.

Find Ed on Linkedin.

This material is copyright 2019 by Ed Gadziemski. Unauthorized use is strictly prohibited. All rights reserved.

Comments and Discussions