�������� Linux Tags

18. Metafile

Metafile������ͼ�εĹ�ϵ���������ͼ��λԪӳ��ͼ�εĹ�ϵһ��������ͼͨ������ʵ�ʵ�ͼ�񣬶�metafile������ͨ�����Գ�ʽ��Ϊ�����ġ�Metafile��һϵ����ͼ�κ�ʽ������ͬ�Ķ���λ��¼��ɣ���Щ��¼һ����춻���ֱ�ߡ����ߡ��������������ֵȡ�

����ͼ��paint������ʽ��������ͼ��������ͼ(draw)����ʽ����metafile��������Ļ�ͼ��ʽ�У������׵ء�ץס��ij��������ͼ�����������һ��ֱ�ߣ��������ƶ�������λ�á�������Ϊ���ͼ�ε�ÿ����Ա�����Ե����ļ�¼����ġ��ڻ�ͼ��ʽ�У����Dz����ܵģ���ͨ����������ɾ����������ͼ���ο顣

���metafile��ͼ�λ�����������ͼ����˿��Զ�ͼ��������Ŷ�����ʧ�档����ͼ��Ȼ������Զ�����С����ʾ����ͼ����ȴ�޷��õ������Ľ����ȣ���ֻ����ˮƽ�ʹ�ֱ�������ظ�����ͼ��λԪ��

Metafile����ת��Ϊ����ͼ�����ǻᶪʧһЩ��Ѷ�����metafile��ͼ������������Ƕ����ģ����DZ��ϲ������ͼ�񡣽�����ͼת��ΪmetafileҪ���ѵö࣬һ�����춷dz��򵥵�ͼ�񣬶�������Ҫ���������������߽����������metafile���԰������Ƶ���ͼ�����

��Ȼmetafile������ΪͼƬ���������ڴ�Ƭ�ϣ��������Ǵ����춳�ʽͨ������������ͼƬ����������metafile��ͼƬ����Ϊͼ��ʽ���еļ��ϣ�������Ǽȱȵ���ͼռ�ø��ٵĿռ䣬�ֱȵ���ͼ����װ���޹ء�

Microsoft Windows֧Ԯ����metafile��ʽ��֧Ԯ��Щ��ʽ�����麯ʽ�����������۴�Windows 1.0��Ŀǰ��32λԪWindows�汾��֧Ԯ��metafile��ʽ��Ȼ������Ϊ32λԪWindowsϵͳ�����ġ���ǿ��metafile������ǿ��metafile��ԭ��metafile�Ļ���������һЩ�Ľ���Ӧ�þ����ܵؼ������á�

�ɵ�metafile��ʽ
��

Metafile���ܹ���ʱ�����ڼ������У�Ҳ�ܹ��Ե�������ʽ�����ڴ�Ƭ�ϡ���Ӧ�ó�ʽ��˵���������𲻴���������Windows��������Ƭ�ϴ��������metafile���ϵĵ���I/Oʱ��������ˡ�

������metafile�ļ�����
��

�������CreateMetaFile��ʽ������metafileװ�����ݣ�Windows�ͻ������ڵĸ�ʽ����һ��metafile��Ȼ��������ʹ�ô󲿷�GDI��ͼ��ʽ�ڸ�metafileװ�������Ͻ��л�ͼ����ЩGDI���в������κξ����װ���ϻ�ͼ���෴�أ����DZ�������metafile�С����ر�metafileװ������ʱ����õ�metafile�Ĵ��š���ʱ�Ϳ�����ij�������װ�������ϡ����š����metafile������ֱ��ִ��metafile��GDI��ʽ��Ч����ͬ��

CreateMetaFileֻ��һ����������������NULL�򵵰����ơ������NULL����metafile�����ڼ������С�����ǵ������ƣ���.WMF��Ϊ��Windows Metafile���ĸ�����������metafile�����ڴ�Ƭ�����С�

��ʽ18-1�е�METAFILE��ʾ����WM_CREATEѶϢ�����ڼ佨��������metafile�ķ���������WM_PAINTѶϢ�����ڼ佫ͼ����ʾ100�顣

 ï¿½ï¿½Ê½18-1  METAFILE
METAFILE.C
/*-------------------------------------------------------------------------
   	METAFILE.C -- 		Metafile Demonstration Program
                 							(c) Charles Petzold, 1998
--------------------------------------------------------------------------*/

#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    							PSTR szCmdLine, int iCmdShow)
{
     	static TCHAR szAppName [] = TEXT ("Metafile") ;
     	HWND         							hwnd ;
     	MSG          							msg ;
     	WNDCLASS     						wndclass ;

     	wndclass.style         					= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   			= WndProc ;
     	wndclass.cbClsExtra    			= 0 ;
     	wndclass.cbWndExtra    			= 0 ;
     	wndclass.hInstance     			= hInstance ;
     	wndclass.hIcon         					= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       				= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 		= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  		= NULL ;
     	wndclass.lpszClassName 		= szAppName ;
     
     	if (!RegisterClass (&wndclass))
	{
          		MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                      							szAppName, MB_ICONERROR) ;
          		return 0 ;
 	}
     
     	hwnd = CreateWindow (	szAppName, TEXT ("Metafile Demonstration"),
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         NULL, NULL, hInstance, NULL) ;
     
     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;
     
     	while (GetMessage (&msg, NULL, 0, 0))
     {
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
     	return msg.wParam ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
     	static HMETAFILE 		hmf ;
     	static int       				cxClient, cyClient ;
     	HBRUSH           					hBrush ;
     	HDC              						hdc, hdcMeta ;
     	int              						x, y ;
     	PAINTSTRUCT      				ps ;
     
     	switch (message)
     	{
     	case 	WM_CREATE:
          			hdcMeta	= 	CreateMetaFile (NULL) ;
          			hBrush	=	CreateSolidBrush (RGB (0, 0, 255)) ;
          			Rectangle 	(hdcMeta, 0, 0, 100, 100) ;
          
          			MoveToEx 		(hdcMeta,	0,	0, 	NULL) ;
          			LineTo   		(hdcMeta, 	100,	100) 	;
          			MoveToEx 		(hdcMeta,	0,	100, 	NULL) ;
          			LineTo   		(hdcMeta,	100,	0) 	;
          
          			SelectObject (hdcMeta, hBrush) ;
          			Ellipse (hdcMeta, 20, 20, 80, 80) ;
          
          			hmf = CloseMetaFile (hdcMeta) ;
          
          			DeleteObject (hBrush) ;
          			return 0 ;
          
     	case 	WM_SIZE:
          			cxClient = LOWORD (lParam) ;
          			cyClient = HIWORD (lParam) ;
          			return 0 ;
          
     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;
          
          			SetMapMode (hdc, MM_ANISOTROPIC) ;
          			SetWindowExtEx (hdc, 1000, 1000, NULL) ;
          			SetViewportExtEx (hdc, cxClient, cyClient, NULL) ;
          
          			for (x = 0 ; x < 10 ; x++)
          			for (y = 0 ; y < 10 ; y++)
          			{
               					SetWindowOrgEx (hdc, -100 * x, -100 * y, NULL) ;
               					PlayMetaFile (hdc, hmf) ;
          			}
          			EndPaint (hwnd, &ps) ;
          			return 0 ;
               
     	case 	WM_DESTROY:
          			DeleteMetaFile (hmf) ;
          			PostQuitMessage (0) ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

�����ʽչʾ����ʹ�ü�����metafileʱ���漰��4��metafile��ʽ���÷�����һ����CreateMetaFile����WM_CREATEѶϢ�����ڼ���NULL�������иú�ʽ��������metafileװ�����ݵĴ��š�Ȼ�ᣬMETAFILE�������metafileDC����������ֱ�ߺ�һ����ɫ��Բ����Щ��ʽ�����Զ���λ��ʽ������metafile�С�CloseMetaFile��ʽ����metafile�Ĵ��š���Ϊ���ỹҪ�õ���metafile���ţ����԰��������ھ�̬������

��metafile����GDI��ʽ���еĶ���λ��ʾ�룬����������MoveToEx���С�����LineTo���С�һ��SelectObject���У�ָ����ɫ��ˢ����һ��Ellipse���С�����û��ָ���κ�ӳ�䷽ʽ��ת��������ֻ����Ϊ��ֵ���ϱ�������metafile�С�

��WM_PAINTѶϢ�����ڼ䣬METAFILE�趨һ��ӳ�䷽ʽ������PlayMetaFile���Ӵ��л������100�Ρ�Metafile�к�ʽ���е����갴��Ŀ��װ�����ݵ�Ŀǰ�任��ʽ���Խ��͡��ں���PlayMetaFileʱ����ʵ�������ظ��غ��������WM_CREATEѶϢ�����ڼ佨��metafileʱ����CreateMetaFile��CloseMetaFile֮�����������к��С�

���κ�GDI���һ����metafile���ҲӦ���ڳ�ʽ��ֹǰ��ɾ����������WM_DESTROYѶϢ�����ڼ���DeleteMetaFile��ʽ�����Ĺ�����

METAFILE��ʽ�Ľ����ͼ18-1��ʾ��


��

ͼ18-1 METAFILE��ʽִ�н����ʾ

��metafile�����ڴŵ���
��

������������У�CreateMetaFile��NULL������ʾҪ���������ڼ������е�metafile������Ҳ���Խ�����Ϊ���������ڴŵ��ϵ�metafile�����ַ�����춴��metafile�ȽϺ��ʣ���Ϊ���Խ�ʡ������ռ䡣����һ���棬ÿ��ʹ�ô�Ƭ�ϵ�metafileʱ������Ҫ��ȡ��Ƭ��

Ҫ��METAFILEת��Ϊʹ��metafile��Ƭ�����ij�ʽ�������CreateMetaFile��NULL�����滻Ϊ�������ơ���WM_CREATE��������ʱ��������metafile����������DeleteMetaFile���������ű�ɾ�������Ǵ�Ƭ������Ȼ����������

�ڴ���WM_PAINTѶϢ�����ڼ䣬����ͨ������GetMetaFile��ȡ�ô˴ŵ�������metafile���ţ�

hmf = GetMetaFile (szFileName) ;

���ھͿ�����ǰ��������ʾ���metafile����WM_PAINTѶϢ��������ʱ�����������������ɾ����metafile���ţ�

DeleteMetaFile (hmf) ;

�ڿ�ʼ����WM_DESTROYѶϢʱ������ɾ��metafile����Ϊ���Ѿ���WM_CREATEѶϢ��ÿ��WM_PAINTѶϢ����ʱ��ɾ���ˣ�������Ȼ��Ҫɾ���ŵ�������

DeleteFile (szFileName) ;

��Ȼ���������봢��õ�����

�����ڵ�ʮ�����۹��ģ�metafileҲ������Ϊʹ�����Զ���Դ�������Լ򵥵ذ����������Ͽ����롣�������һ�����metafile���ݵ����ϣ���ô������ʹ��

hmf = SetMetaFileBitsEx (iSize, pData) ;

������metafile��SetMetaFileBitsEx��һ����Ӧ�ĺ�ʽ��GetMetaFileBitsEx���˺�ʽ��metafile�����ݸ��Ƶ���������С�

��ʽmetafile�������
��

��ʽmetafile�и������ȱ�ݡ������������ʽmetafile�Ĵ��ţ���ô����������ʾmetafileʱ���ȷ�����Ĵ�С�أ��������������metafile���ڲ��ṹ�������޷���֪��

���⣬����ʽ�Ӽ�����ȡ����ʽmetafileʱ�����metafile������Ϊ��MM_ISOTROPIC��MM_ANISOTROPICӳ�䷽ʽ����ʾ����˳�ʽ��ʹ�ø�metafileʱ�������̶ȵ�����ԡ���ʽ�յ���metafile�ᣬ�Ϳ�������ʾ��֮ǰ�򵥵�ͨ���趨�Ӳ��ķ�Χ������ͼ��Ȼ�������metafile�ڵ�ӳ�䷽ʽ���趨ΪMM_ISOTROPIC��MM_ANISOTROPIC�����յ���metafile�ij�ʽ���޷�����ִ�С���ʽ��������ʾmetafile֮ǰ��֮�����GDI���У�����������ʾmetafile���н���GDI���С�

Ϊ�˽����Щ���⣬��ʽmetafile���Ų�ֱ�ӷ����������������ʽȡ�ã�������Ϊ��metafileͼƬ����METAFILEPICT�ṹ��̬����һ���֡��˽ṹʹ�ôӼ�������ȡ��metafileͼƬ�ij�ʽ�ܹ�����ʾmetafile֮ǰ�趨ӳ�䷽ʽ���Ӳ���Χ��

METAFILEPICT�ṹ�ij���Ϊ16��λԪ�飬�������£�

typedef struct tagMETAFILEPICT
{
     	LONG mm ;             				// mapping mode
     	LONG xExt ;           				// width of the metafile image
     	LONG yExt ;           				// height of the metafile image
     	LONG hMF ;            				// handle to the metafile
}
METAFILEPICT ;

���MM_ISOTROPIC��MM_ANISOTROPIC���������ӳ�䷽ʽ��ͼ���С��xExt��yExtֵ��ʾ���䵥λ����mm������ӳ�䷽ʽ�ĵ�λ��������Щ��Ѷ���Ӽ���������metafileͼƬ�ṹ�ij�ʽ���ܹ�ȷ������ʾmetafileʱ�������ʾ�ռ䡣������metafile�ij�ʽ���Խ���Щֵ�趨Ϊ����metafile��GDI���ƺ�ʽ����ʹ�õ�����x�����y����ֵ��

��MM_ISOTROPIC��MM_ANISOTROPICӳ�䷽ʽ�£�xExt��yExt��λ�в�ͬ�Ĺ��ܡ������ڵ������������ܹ�һ����ʽ���ó�ʽΪ����GDI��ʽ��ʹ����ͼ��ʵ�ʳߴ��޹ص��߼���λ������MM_ISOTROPIC��MM_ANISOTROPICӳ�䷽ʽ������ʽֻ�뱣���ݺ�ȶ����Ժ���ͼ����ʾƽ��Ĵ�Сʱ������MM_ISOTROPICģʽ����֮��������Ҫ�����ݺ��ʱ����MM_ANISOTROPICģʽ����Ҳ�����ǵã����������ڳ�ʽ��ӳ�䷽ʽ�趨ΪMM_ISOTROPIC��MM_ANISOTROPIC�ᣬͨ�������SetWindowExtEx��SetViewportExtEx��SetWindowExtEx����ʹ���߼���λ��ָ����ʽ�ڻ���ʱʹ�õĵ�λ����SetViewportExtEx����ʹ�õ�װ�õ�λ��С��ȡ���ͼ����ʾƽ�棨���磬�Ӵ���ʾ����Ĵ�С����

�����ʽΪ������������MM_ISOTROPIC��MM_ANISOTROPIC��ʽ��metafile�����metafile������Ӧ������SetViewportExtEx�ĺ��У���Ϊ�ú����е�װ�õ�λӦ�����ݽ���metafile�ij�ʽ����ʾƽ�棬���������ݴӼ�������ȡ����ʾmetafile�ij�ʽ����ʾƽ�档�Ӽ�����ȡ��metafile�ij�ʽ��������xExt��yExtֵ���趨���ʵ��Ӳ���Χ�Ա���ʾmetafile�����ǵ�ӳ�䷽ʽ��MM_ISOTROPIC��MM_ANISOTROPICʱ��metafile���������趨�Ӵ���Χ�ĺ��С�Metafile�ڵ�GDI��ͼ��ʽ������������Щ�Ӵ��ķ�Χ��

����metafile��metafileͼƬ��ѭ���¹���

  • �趨METAFILEPICT�ṹ��mm��λ��ָ��ӳ�䷽ʽ��
    ��
  • ���MM_ISOTROPIC��MM_ANISOTROPIC�����ӳ�䷽ʽ��xExt��yExt��λ�趨Ϊͼ��Ŀ��͸ߣ���λ��mm��λ���Ӧ�������MM_ISOTROPIC��MM_ANISOTROPIC��ʽ����ʾ��metafile������Ҫ����һЩ����MM_ANISOTROPICģʽ�£�����ʽ�Ȳ���ͼƬ��С���ݺ�ȸ����κν�����Ѷʱ��xExt��yExt��ֵ��Ϊ�㡣��������ģʽ�£����xExt��yExt��ֵΪ���������Ǿ�����0.01mm���MM_HIMETRIC��λ����ʾ��ͼ��Ŀ��Ⱥ͸߶ȡ���MM_ISOTROPIC��ʽ�£����xExt��yExtΪ��ֵ�����Ǿ�ָ����ͼ����ݺ�ȶ����Ǵ�С��
    ��
  • ��MM_ISOTROPIC��MM_ANISOTROPICӳ�䷽ʽ�£�metafile�������ж�SetWindowExtEx�ĺ��У�Ҳ�����ж�SetWindowOrgEx�ĺ��С��༴������metafile�ij�ʽ��metafileװ�������к�����Щ��ʽ��Metafileһ�㲻�������SetMapMode��SetViewportExtEx��SetViewportOrgEx�ĺ��С�
    ��
  • metafileӦ���Ǽ�����metafile��������metafile������
    ��

������һ�η�����ʽ�룬������metafile�����临�Ƶ������������metafileʹ��MM_ISOTROPIC��MM_ANISOTROPICӳ�䷽ʽ�����metafile�ĵ�һ������Ӧ���趨�Ӵ���Χ��������ģʽ�У��Ӵ��Ĵ�С�ǹ̶��ģ�������������ģʽ�£��Ӵ���λ��Ӧ�����趨��

hdcMeta = CreateMetaFile (NULL) ;
SetWindowExtEx (hdcMeta, ...) ;
SetWindowOrgEx (hdcMeta, ...) ;

Metafile��ͼ��ʽ�е�����������Щ�Ӵ���Χ���Ӵ�ԭ�㡣����ʽʹ��GDI������metafileװ�������л�������ᣬ�ر�metafile�Եõ�metafile���ţ�

hmf = CloseMetaFile (hdcMeta) ;

�ó�ʽ����Ҫ����ָ��METAFILEPICT��̬�ṹ��ָ�꣬��Ϊ�˽ṹ����һ����������壺

GLOBALHANDLE   		hGlobal ;
LPMETAFILEPICT 		pMFP ;
�����г�ʽ
hGlobal= GlobalAlloc (GHND | GMEM_SHARE, sizeof (METAFILEPICT)) ;
pMFP = (LPMETAFILEPICT) GlobalLock (hGlobal) ;

��������ʽ�趨�ýṹ��4����λ��

pMFP->mm   	= MM_... ;
pMFP->xExt 	= ...  ;
pMFP->yExt 	= ...  ;
pMFP->hMF  	= hmf  ;

GlobalUnlock (hGlobal) ;

Ȼ�ᣬ��ʽ��������metafileͼƬ�����������鴫�͸���������

OpenClipboard (hwnd) ;
EmptyClipboard () ;
SetClipboardData (CF_METAFILEPICT, hGlobal) ;
CloseClipboard () ;

�����Щ�����ᣬhGlobal���ţ�����metafileͼƬ�ṹ�ļ�����飩��hmf���ţ�metafile�������ͶԽ������ǵij�ʽʧЧ�ˡ�

��������һ���ѵIJ��֡�����ʽ�Ӽ�����ȡ��metafile����ʾ��ʱ������������в��裺

  1. ��ʽ����metafileͼƬ�ṹ��mm��λ�趨ӳ�䷽ʽ��
  2. ���MM_ISOTROPIC��MM_ANISOTROPIC�����ӳ�䷽ʽ����ʽ��xExt��yExtֵ�趨�������λ�򵥵��趨ͼ���С������MM_ISOTROPIC��MM_ANISOTROPICӳ�䷽ʽ����ʽʹ��xExt��yExt���趨�Ӳ���Χ��
  3. Ȼ�ᣬ��ʽ��ʾmetafile��

�����ʽ�룬���ȴ򿪼��������õ�metafileͼƬ�ṹ���Ų�����������

OpenClipboard (hwnd) ;
hGlobal = GetClipboardData (CF_METAFILEPICT) ;
pMFP = (LPMETAFILEPICT) GlobalLock (hGlobal) ;

���ڿ��Դ���Ŀǰװ�����ݵ����ԣ�����ӳ�䷽ʽ�趨Ϊ�ṹ�е�mmֵ��

SaveDC (hdc) ;
SetMappingMode (pMFP->mm) ;

���ӳ�䷽ʽ����MM_ISOTROPIC��MM_ANISOTROPIC���������xExt��yExt��ֵ�趨�������Ρ����������ֵ���߼���λ��������LPtoDP����ת��Ϊ��춼������ε�װ�õ�λ�����ꡣҲ���Լ򵥵ش�����Щֵ������ͼ��Ĵ�С��

���MM_ISOTROPIC��MM_ANISOTROPICӳ�䷽ʽ��xExt��yExt�����趨�Ӳ���Χ��������һ��������ɴ�������ĺ�ʽ�����xExt��yExtû�н���Ĵ�С����ú�ʽ�ٶ�cxClient��cyClient�ֱ��ʾmetafile��ʾ�����ͼ�ظ߶ȺͿ��ȡ�

void PrepareMetaFile (	HDC hdc, LPMETAFILEPICT pmfp,
                      		int cxClient, int cyClient)
{
     	int xScale, yScale, iScale ;
     	SetMapMode (hdc, pmfp->mm) ;
     	if (pmfp->mm == MM_ISOTROPIC || pmfp->mm == MM_ANISOTROPIC)
     	{
          			if (pmfp->xExt == 0)
               				SetViewportExtEx (hdc, cxClient, cyClient, NULL) ;
          			else if (pmfp->xExt > 0)
               				SetViewportExtEx (hdc,
                    			pmfp->xExt *	GetDeviceCaps (hdc, HORZRES) /
                                GetDeviceCaps (hdc, HORZSIZE) / 100),
                    			pmfp->yExt *	GetDeviceCaps (hdc, VERTRES) /
                                GetDeviceCaps (hdc, VERTSIZE) / 100), NULL) ;
           			            else if (pmfp->xExt < 0)
          				{
               			xScale = 100 *	cxClient * GetDeviceCaps (hdc, HORZSIZE) /
                        GetDeviceCaps (hdc, HORZRES) / -pmfp->xExt ;
               			lScale = 100 *	cyClient * GetDeviceCaps (hdc, VERTSIZE) /
                        GetDeviceCaps (hdc, VERTRES) / -pmfp->yExt ;
               			iScale = min (xScale, yScale) ;

   SetViewportExtEx (hdc, -pmfp->xExt * iScale * GetDeviceCaps (hdc, HORZRES) /
                     GetDeviceCaps (hdc, HORZSIZE) / 100, -pmfp->yExt * iScale 
* GetDeviceCaps (hdc, VERTRES) / GetDeviceCaps (hdc, VERTSIZE) / 100, NULL) ;
   			}
		}
}

����ij�ʽ�����xExt��yExtͬʱ��Ϊ�㡢������С��㣬������״̬֮һ�������ΧΪ�㣬��ʾû�н����С���ݺ�ȣ��Ӳ���Χ�趨Ϊ��ʾmetafile�������������㣬��xExt��yExt��ֵ����ͼ��Ľ����С����λ��0.01mm��GetDeviceCaps��ʽ����ȷ��ÿ0.01mm�а�����ͼ���������Ҹ�ֵ��metafileͼƬ�ṹ�ķ�Χֵ��ˡ����С��㣬��xExt��yExt��ֵ��ʾ������ݺ�ȶ����ǽ���Ĵ�С��iScale��ֵ���ȸ��ݶ�ӦcxClient��cyClient�ĺ��ױ�ʾ���ݺ�ȼ����������������������趨ͼ�ص�λ���Ӳ���Χ��

��������������ᣬ�����趨�Ӳ�ԭ�㣬��ʾmetafile�����ָ�װ�����ݣ�

PlayMetaFile (pMFP->hMF) ;
RestoreDC (hdc, -1) ;

Ȼ�ᣬ�Լ������������رռ�������

GlobalUnlock (hGlobal) ;
CloseClipboard () ;

�����ʽʹ����ǿ��metafile�Ϳ���ʡȥ���������ij��Ӧ�ó�ʽ����Щ��ʽ�������������һ����ʽȴҪ��Ӽ������л��������ʽʱ��Windows���������Զ�����ʽmetafile����ǿ��metafile֮����и�ʽת����

��ǿ��metafile
��

����ǿ��metafile�� ��ʽ����32λԪWindows�汾�з����ġ�������һ���µĺ�ʽ���С�һ���µ����Ͻṹ���µļ�������ʽ���µĵ���������.EMF��

�����µ�metafile��ʽ����Ҫ�ĸĽ��Ǽ����ͨ����ʽ����ȡ�õĸ��ḻ�ı�ͷ��Ѷ�����ֱ�ͷ��Ѷ����������Ӧ�ó�ʽ��ʾmetafileͼ��

��Щ��ǿ��metafile��ʽʹ���ܹ�����ǿ��metafile(EMF)��ʽ����ʽmetafile��ʽ��Ҳ����Windows metafile(WMF)��ʽ��֮������ת������Ȼ������ת���ܿ��������鷳����Ϊ��ʽmetafile��ʽ����֧ԮijЩ������GDI��ͼ·���ȣ��µ�32λԪͼ�ι��ܡ�

��������
��

��ʽ18-2��ʾ��EMF1��������ʾ��ǿ��metafile��

 ï¿½ï¿½Ê½18-2  EMF1
EMF1.C
/*----------------------------------------------------------------------------
   	EMF1.C --	Enhanced Metafile Demo #1
             					(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/

#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    							LPSTR lpszCmdLine, int nCmdShow)
{
     	static TCHAR 	szAppName[] = TEXT ("EMF1") ;
     	HWND         				hwnd ;
     	MSG          				msg ;
     	WNDCLASS     			wndclass ;
     
     	wndclass.style         					= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   			= WndProc ;
     	wndclass.cbClsExtra    			= 0 ;
     	wndclass.cbWndExtra    			= 0 ;
     	wndclass.hInstance     			= hInstance ;
     	wndclass.hIcon         			= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       		= LoadCursor (NULL, IDC_ARROW) ;
  	wndclass.hbrBackground 		= GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  		= NULL ;
     	wndclass.lpszClassName 		= szAppName ;

     	if (!RegisterClass (&wndclass))
     	{
          			MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                      								szAppName, MB_ICONERROR) ;
          			return 0 ;
     }
     
     	hwnd = CreateWindow (	szAppName, TEXT ("Enhanced Metafile Demo #1"),
                          		WS_OVERLAPPEDWINDOW,
                          		CW_USEDEFAULT, CW_USEDEFAULT,
                          		CW_USEDEFAULT, CW_USEDEFAULT,
                          		NULL, NULL, hInstance, NULL) ;
     
     	ShowWindow (hwnd, nCmdShow) ;
     	UpdateWindow (hwnd) ;
     
     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          			TranslateMessage (&msg) ;
          			DispatchMessage (&msg) ;
     }
     	return msg.wParam ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
     	static HENHMETAFILE 	hemf ;
     	HDC                 							hdc, hdcEMF ;
     	PAINTSTRUCT         					ps ;
     	RECT                							rect ;
     
     	switch (message)
     {
     	case 	WM_CREATE:
          			hdcEMF = CreateEnhMetaFile (NULL, NULL, NULL, NULL) ;

          			Rectangle 	(hdcEMF, 100, 100, 200, 200) ;
          
          			MoveToEx  		(hdcEMF, 100, 100, NULL) ;
          			LineTo  		(hdcEMF, 200, 200) ;
          
          			MoveToEx 		(hdcEMF, 200, 100, NULL) ;
          			LineTo  		(hdcEMF, 100, 200) ;

          			hemf = CloseEnhMetaFile (hdcEMF) ;
          			return 0 ;
          
     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;
          
          			GetClientRect (hwnd, &rect) ;
          
          			rect.left   		=     			rect.right 		/ 4 ;
          			rect.right  		= 3 * 	rect.right		/ 4 ;
          			rect.top    		=     			rect.bottom		/ 4 ;
          			rect.bottom 		= 3 * 	rect.bottom		/ 4 ;
          
          			PlayEnhMetaFile (hdc, hemf, &rect) ;
          
          			EndPaint (hwnd, &ps) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			DeleteEnhMetaFile (hemf) ;
          
          			PostQuitMessage (0) ;
          			return 0 ;
     }
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

��EMF1���Ӵ�ѶϢ������ʽ����WM_CREATEѶϢ�����ڼ䣬��ʽ����ͨ������CreateEnhMetaFile��������ǿ��metafile���ú�ʽ��4�������������԰����Ƕ���ΪNULL���Ժ��ҽ�˵����4�������ڷ�NULL����µ�ʹ�÷�����

��CreateMetaFileһ����CreateEnhMetaFile��ʽ�����ض���װ�����ݴ��š��ó�ʽ����������Ż���һ�����κ͸þ��ε������Խ��ߡ���Щ��ʽ���м��������ת��Ϊ����λԪ����ʽ��������metafile�С�

����ͨ����CloseEnhMetaFile��ʽ�ĺ��н�������ǿ��metafile�Ľ���������ָ�����Ĵ��š��õ������Ŵ�����HENHMETAFILE��̬�ľ�̬�����С�

��WM_PAINTѶϢ�����ڼ䣬EMF1��RECT�ṹȡ�ó�ʽ����ʾ�����Ӵ���С��ͨ�������ṹ�е�4����λ��ʹ�þ��εij��Ϳ�Ϊ��ʾ�����Ӵ����Ϳ���һ�벢λ��Ӵ������롣Ȼ��EMF1����PlayEnhMetaFile���ú�ʽ�ĵ�һ���������Ӵ���װ�����ݴ��ţ��ڶ��������Ǹ���ǿ��metafile�Ĵ��ţ�������������ָ��RECT�ṹ��ָ�ꡣ

��metafile�Ľ��������У�GDI�ó�����metafileͼ��ijߴ硣�ڱ����У�ͼ��ij��Ϳ���Ϊ100����λ����metafile����ʾ�����У�GDI��ͼ����������ӦPlayEnhMetaFile��ʽָ���ľ��δ�С��EMF1��Windows��ִ�е�����ִ��ʵ����ͼ18-2��ʾ��


��

ͼ18-2 EMF1��өĻ��ʾ

���ᣬ��WM_DESTROYѶϢ�����ڼ䣬EMF1����DeleteEnhMetaFileɾ��metafile��

�������ܽ�һ�´�EMF1��ʽѧ����һЩ������

���ȣ��ó�ʽ�ڽ�����ǿ��metafileʱ�������κ�ֱ�ߵĺ�ʽ��ʹ�õ����겢����ʵ�������ϵ����ꡣ�����Խ�����ͬʱ�ӱ��򶼼�ȥij������������������ı䡣��Щ����ֻ���ڶ���ͼ��ʱ˵���˴˼�Ķ�Ӧ��ϵ��

��Σ�Ϊ������ڴ��ݸ�PlayEnhMetaFile��ʽ�ľ�������ʾ��ͼ���С�ᱻ���š���ˣ���ͼ18-2��ʾ��ͼ����ܻ���Ρ�����metafile����ָ����ͼ���������εģ���һ�����������ȴ�ò���������ͼ�񡣶���ijЩʱ����������������Ҫ�õ���ͼ�����磬��ͼ��Ƕ��һ�����鴦����ʽ��������ʱ�����ܻ�Ҫ��ʹ����Ϊͼ��ָ�����Σ�����ȷ������ͼ��ǡ��λ춾����ж����˷ѿռ䡣������ʹ���߿�ͨ���ʵ��������εĴ�С���õ���ȷ���ݺ�ȡ�

Ȼ����ʱ����Ҳ��ϣ������ͼ��������ݺ�ȣ���Ϊ��һ���춱����Ӿ���Ѷ��Ϊ��Ҫ�����磬��������ɷ���ͼ�Ȳ��ܱ�ԭ����Ҳ���ܱ�ԭ���ݡ�������ϣ������ԭ��ͼ��Ķ����ߴ磬ͼ���������Ӣ��ߣ�����Ͳ���������ʾ������������£�����ͼ���ԭ���ߴ�ͷdz���Ҫ�ˡ�

ͬʱҲҪע��metafile�л�������Щ�Խ����ƺ�û������ζ����ཻ���������Windows��metafile�д����������ķ�ʽ��ɵġ����ᣬ��˵������������ķ�����

�ҿ���Ļ
��

�����һ��metafile�����ݻ��metafile�����ķ�ʽ��һ�����õ����⡣�������һ��metafile�������⽫��������������ʽ18-3�е�EMF2��ʽ������һ��metafile��

 ï¿½ï¿½Ê½18-3  EMF2
EMF2.C
/*-----------------------------------------------------------------------------
   	EMF2.C --	Enhanced Metafile Demo #2
             					(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/

#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    							LPSTR lpszCmdLine, int nCmdShow)
{
     	static TCHAR 		szAppName[] = TEXT ("EMF2") ;
     	HWND         					hwnd ;
     	MSG          					msg ;
     	WNDCLASS     				wndclass ;
     	wndclass.style        					= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   			= WndProc ;
     	wndclass.cbClsExtra    			= 0 ;
     	wndclass.cbWndExtra    			= 0 ;
     	wndclass.hInstance     			= hInstance ;
     	wndclass.hIcon         			= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       		= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 		= GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  		= NULL ;
     	wndclass.lpszClassName 		= szAppName ;
     
     	if (!RegisterClass (&wndclass))
     	{
          		MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                      							szAppName, MB_ICONERROR) ;
          		return 0 ;
     	}
     
     	hwnd = CreateWindow (szAppName, TEXT ("Enhanced Metafile Demo #2"),
                          	WS_OVERLAPPEDWINDOW,
                          	CW_USEDEFAULT, CW_USEDEFAULT,
                          	CW_USEDEFAULT, CW_USEDEFAULT,
                          	NULL, NULL, hInstance, NULL) ;
     
     	ShowWindow (hwnd, nCmdShow) ;
     	UpdateWindow (hwnd) ;
     
     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
     	return msg.wParam ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	HDC          				hdc, hdcEMF ;
     	HENHMETAFILE 	hemf ;
     	PAINTSTRUCT  		ps ;
     	RECT         				rect ;
     
     	switch (message)
     	{
     	case 	WM_CREATE:
          	hdcEMF = CreateEnhMetaFile (NULL, TEXT ("emf2.emf"), NULL,
            TEXT ("EMF2\0EMF Demo #2\0")) ;

          			if (!hdcEMF)
               			return 0 ;

          			Rectangle 	(hdcEMF, 100, 100, 200, 200) ;

          			MoveToEx  		(hdcEMF, 100, 100, NULL) ;
          			LineTo    		(hdcEMF, 200, 200) ;
          
          			MoveToEx  		(hdcEMF, 200, 100, NULL) ;
          			LineTo    		(hdcEMF, 100, 200) ;
          
          			hemf = CloseEnhMetaFile (hdcEMF) ;
          
          			DeleteEnhMetaFile (hemf) ;
          			return 0 ;
          
     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;
          
          			GetClientRect (hwnd, &rect) ;
          
          			rect.left		= 	    rect.right      / 4 ;
          			rect.right  	= 3 * 	rect.right		/ 4 ;
          			rect.top    	=       rect.bottom		/ 4 ;
          			rect.bottom 	= 3 *	rect.bottom		/ 4 ;
          
          			if (hemf = GetEnhMetaFile (TEXT ("emf2.emf")))
          			{
               				PlayEnhMetaFile (hdc, hemf, &rect) ;
               				DeleteEnhMetaFile (hemf) ;
          			}
          			EndPaint (hwnd, &ps) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			PostQuitMessage (0) ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

��EMF1��ʽ�У�CreateEnhMetaFile��ʽ�����в��������趨ΪNULL����EMF2�У���һ�������Ծ��趨ΪNULL���ò�����������װ�����ݴ��š�GDIʹ�øò�����metafile��ͷ�в��������Ѷ���ܿ��һ�������������ò���ΪNULL����GDI��Ϊ������Ѷ������Ѷװ�����ݾ����ġ�

CreateEnhMetaFile��ʽ�ĵڶ��������ǵ������ơ�����ò���ΪNULL����EMF1��ΪNULL������EMF2�в�ΪNULL������ú�ʽ����������metafile��EMF2������ΪEMF2.EMF��metafile������

��ʽ�ĵ�����������RECT�ṹ��λַ����ָ������0.01mmΪ��λ��metafile���ܴ�С������metafile��ͷ�����м�����Ҫ����Ѷ���������ڵ�Windows metafile��ʽ��ȱ��֮һ��������ò���ΪNULL��GDI�������ߴ硣�ұȽ�ϲ������ҵϵͳ��������Щ�£����Խ��ò����趨ΪNULL����Ӧ�ó�ʽ������Ҫ��Ƚ��ϸ�ʱ������Ҫʹ�øò����Ա�����GDI����̫�ණ����

����IJ�����������metafile���ִ������ִ���Ϊ�����֣���һ��������NULL��Ԫ��β��Ӧ�ó�ʽ���ƣ���һ���dz�ʽ�ĵ������ƣ����ڶ������������Ӿ�ͼ�����ݵ�˵����������NULL��Ԫ��β��������C�еķ��š�\0����ΪNULL��Ԫ����������ִ������ǡ�LoonyCad V6.4\0Flying Frogs\0\0���������C��ͨ������ʹ�õ��ִ�ĩβ����һ��NULL��Ԫ��������EMF2��ʾ����ĩβ����һ����\0����

������metafile�ᣬ��EMF1һ����EMF2Ҳ͸��������CreateEnhMetaFile��ʽ���ص�װ�����ݴ��Ž���һЩGDI��ʽ���С�Ȼ���ʽ����CloseEnhMetaFileɾ��װ�����ݴ��Ų�ȡ����ɵ�metafile�Ĵ��š�

Ȼ�ᣬ��WM_CREATEѶϢ��û�������ʱ��EMF2����һЩEMF1û���������飺�ڻ��metafile����֮�ᣬ��ʽ����DeleteEnhMetaFile���ò����ͷ�����춴���metafile�����м�������Դ��Ȼ����metafile������Ȼ�����ڴŵ����У����Ը�⣬������ʹ����DeleteFile�ĵ���ɾ����ʽ��ɾ���õ�������ע��metafile���Ų�����EMF1�����������ھ�̬�����У�����ζ����ѶϢ֮�䲻��Ҫ��������

���ڣ�Ϊ��ʹ�ø�metafile��EMF2��Ҫ��ȡ��Ƭ������������WM_PAINTѶϢ�����ڼ�͸������GetEnhMetaFile���еġ�Metafile�ĵ��������Ǹú�ʽ��Ψһ�������ú�ʽ����metafile���š���EMF1һ����EMF2������������Ŵ��ݸ�PlayEnhMetaFile��ʽ����metafileͼ����PlayEnhMetaFile��ʽ������һ��������ָ���ľ�������ʾ����EMF1��ͬ���ǣ�EMF2��WM_PAINTѶϢ����֮ǰ��ɾ����metafile������ÿ�δ���WM_PAINTѶϢʱ��EMF2�����ٴζ�ȡmetafile����ʾ��ɾ������

Ҫ��ס����metafile��ɾ�����������ͷ������Դ���metafile�ļ�������Դ���ѣ���Ƭmetafile�����ڳ�ʽִ�н����ỹ�����ڴ�Ƭ�ϡ�

���EMF2������metafile�����������Կ�һ���������ݡ�ͼ18-3��ʾ�˸ó�ʽ������EMF2.EMF������һ��ʮ����λ���롣

0000  	01 00 00 00 88 00 00 00 64 00 00 00 64 00 00 00	    ........d...d...
0010  	C8 00 00 00 C8 00 00 00 35 0C 00 00 35 0C 00 00  	........5...5...
0020  	6A 18 00 00 6A 18 00 00 20 45 4D 46 00 00 01 00  	j...j...EMF....
0030  	F4 00 00 00 07 00 00 00 01 00 00 00 12 00 00 00  	................
0040  	64 00 00 00 00 00 00 00 00 04 00 00 00 03 00 00  	d...............
0050  	40 01 00 00 F0 00 00 00 00 00 00 00 00 00 00 00  	@...............
0060  	00 00 00 00 45 00 4D 00 46 00 32 00 00 00 45 00  	....E.M.F.2...E.
0070  	4D 00 46 00 20 00 44 00 65 00 6D 00 6F 00 20 00  	M.F..D.e.m.o..
0080  	23 00 32 00 00 00 00 00 2B 00 00 00 18 00 00 00  	#.2.....+.......
0090  	63 00 00 00 63 00 00 00 C6 00 00 00 C6 00 00 00  	c...c...........
00A0  	1B 00 00 00 10 00 00 00 64 00 00 00 64 00 00 00  	........d...d...
00B0  	36 00 00 00 10 00 00 00 C8 00 00 00 C8 00 00 00  	6...............
00C0  	1B 00 00 00 10 00 00 00 C8 00 00 00 64 00 00 00  	............d...
00D0  	36 00 00 00 10 00 00 00 64 00 00 00 C8 00 00 00  	6.......d.......
00E0  	0E 00 00 00 14 00 00 00 00 00 00 00 10 00 00 00  	................
00F0  	14 00 00 00									....
ͼ18-3 EMF2.EMF��ʮ����λ����

ͼ18-3��ʾ��metafile��EMF2��Microsoft Windows NT 4�£���Ѷ��ʾ���Ľ�����Ϊ1024��768ʱ�����ġ�ͬһ��ʽ��Windows 98�½�����metafile���ǰ����12��λԪ�飬��һ�㽫���������ۡ�ͬ���أ���Ѷ��ʾ���Ľ�����ҲӰ��metafile��ͷ��ijЩ��Ѷ��

��ǿ��metafile��ʽʹ���Ƕ�metafile�Ĺ�����ʽ�и���̵����⡣��ǿ��metafile�ɿɱ䳤�ȵļ�¼��ɣ���Щ��¼��һ���ʽ��ENHMETARECORD�ṹ˵��������WINGDI.H��ͷ�����ж������£�

typedef struct tagENHMETARECORD
{
     	DWORD iType ;         				// record type
     	DWORD nSize ;         				// record size
     	DWORD dParm [1] ;     		        // parameters
}
ENHMETARECORD ;

��Ȼ���Ǹ�ֻ��һ��Ԫ�ص�����ָ��������Ԫ�صı���������������ȡ��춼�¼��̬��iType��λ�����Ƕ�����WINGDI.H������������EMR_��ʼ�Ľ��ٸ�����֮һ��nSize��λ���ܼ�¼�Ĵ�С������iType��nSize��λ�Լ�һ������dParm��λ��

������Щ֪ʶ�ᣬ�����ǿ�һ��ͼ18-3����һ����λ��̬Ϊ0x00000001����СΪ0x00000088��������ռ�ݵ�����ǰ136��λԪ�顣��¼��̬Ϊ1��ʾ����EMR_HEADER�����Dz����ѶԱ�ͷ��¼����������飬������λ춵�һ����¼ĩβ��ƫ����0x0088����

�����5����¼��EMF2����metafile֮���5��GDI��ʽ�����йء��ü�¼��ƫ����0x0088����һ��ֵΪ0x0000002B����̬���룬�����EMR_RECTANGLE�������������Rectangle���е�metafile��¼�����ij���Ϊ0x00000018 ��ʮ��λ24��λԪ�飬��������4��32λԪ������ʵ����Rectangle��ʽ��5�����������ǵ�һ��������Ҳ����װ�����ݴ��Ų�δ������metafile�У���Ϊ��û��ʵ�����塣������EMF2�ĺ�ʽ������ָ���˾��εĶ�������ֱ���(100��100)��(200��200)����4�������е�2����0x00000063 (99)������2����0x000000C6 (198)��EMF2��ʽ��Windows 98�½�����metafile��ʾ��ǰ����������0x00000064 (100)����2��������0x000000C7(199)����Ȼ����Rectangle�������浽metafile֮ǰ��Windows���������˵�������û�б���һ�¡�����ǶԽ��߶˵�����ζ��㲻���غϵ�ԭ��

��Σ���4��16λԪ��¼��2��MoveToEx (0x0000001B��EMR_MOVETOEX)��LineTo (0x00000036��EMR_LINETO)�����йء�λ�metafile�еIJ����봫�ݸ���ʽ�IJ�����ͬ��

Metafile��20��λԪ�鳤����̬����Ϊ0x0000000E��EMR_EOF����end of file�����ļ�¼��β��

��ǿ��metafile�����Ա�ͷ��¼��ʼ������Ӧ�ENHMETAHEADER��̬�Ľṹ���������£�

typedef struct tagENHMETAHEADER
{
     	DWORD iType ;       // EMR_HEADER = 1
     	DWORD nSize ;       // structure size 
     	RECTL rclBounds ;    // bounding rectangle in pixels
     	RECTL rclFrame ;     // size of image in 0.01 millimeters
     	DWORD dSignature ;  // ENHMETA_SIGNATURE = " EMF"
     	DWORD nVersion ;    // 0x00010000
     	DWORD nBytes ;     // file size in bytes
     	DWORD nRecords ;   // total number of records
     	WORD  nHandles ;   // number of handles in handle table
     	WORD  sReserved ;
     	DWORD nDescription ;    // character length of description string
     	DWORD offDescription ;   // offset of description string in file
     	DWORD nPalEntries ;     // number of entries in palette
     	SIZEL szlDevice ;        // device resolution in pixels
     	SIZEL szlMillimeters ; 	   // device resolution in millimeters
     	DWORD cbPixelFormat ;  // size of pixel format
     	DWORD offPixelFormat ;  // offset of pixel format
     	DWORD bOpenGL ;      // FALSE if no OpenGL records
}
ENHMETAHEADER ;

���ֱ�ͷ��¼�Ĵ��ڿ�������ǿ��metafile��ʽ������Windows metafile��������Ϊ��Ҫ�ĸĽ�������Ҫ��metafile����ʹ�õ���I/O��ʽ��ȡ����Щ��ͷ��Ѷ���������metafile���ţ��Ϳ���ʹ��GetEnhMetaFileHeader��ʽ��

GetEnhMetaFileHeader (hemf, cbSize, &emh) ;

��һ��������metafile���š�����һ��������ָ��ENHMETAHEADER�ṹ��ָ�ꡣ�ڶ��������Ǹýṹ�Ĵ�С������ʹ�����Ƶ�GetEnh-MetaFileDescription��ʽȡ�������ִ���

������������ģ�ENHMETAHEADER�ṹ��100λԪ�鳤������MF2.EMFmetafile�У���¼�Ĵ�С���������ִ������Դ�СΪ0x88����136λԪ�顣��Windows 98metafile�ı�ͷ��¼������ENHMETAHEADER�ṹ������3����λ����һ�������12��λԪ��IJ��

rclBounds��λ��ָ��ͼ���С��RECT�ṹ����λ��ͼ�ء������ʮ����λת�����������ǿ�����ͼ����������ϣ���������������Ͻ�λ�(100,100)�����½�λ�(200,200)��

rclFrame��λ���ṩ��ͬ��Ѷ����һ�����νṹ����������0.01����Ϊ��λ������������£��õ�����ʾ���ԽǶ���ֱ�λ�(0x0C35,0x0C35)��(0x186A,0x186A)����ʮ��λ��ʾΪ(3125,3125)��(6250,6250)�ľ��Ρ���Щ��������ô���ģ����Ǻܿ�ͻ����ס�

dSignature��λʼ��ΪֵENHMETA_SIGNATURE��0x464D4520���⿴��ȥ��һ����ֵ����֣��������λԪ�������˳�򵹹���������Intel�������ڼ������д����λԪ������������ת����ASCII�룬�ͱ���ִ�" EMF"��dVersion��λ��ֵʼ����0x00010000��

������nBytes��λ������λ�ڱ�������0x000000F4�����Ǹ�metafile����λԪ������nRecords��λ���ڱ�������0x00000007��ָ���˼�¼����������ͷ��¼��5��GDI��ʽ���к͵���������¼��

����������ʮ��λԪ����λ��nHandles��λΪ0x0001������λһ��ָ��metafile��ʹ�õ�ͼ��������续�ʡ���ˢ�����壩�ķ��ڶ����ŵ����������û��ʹ����Щͼ������������ܻ���Ϊ����λΪ�㣬��ʵ����GDI�Լ������˵�һ����λ�����ǽ��ܿ�������Ŵ�����metafile�еķ�ʽ��

��������λָ�������ִ�����Ԫ�������Լ������ִ��ڵ����е�ƫ�������������Ƿֱ�Ϊ0x00000012��ʮ��λ����18����0x00000064�����metafileû�������ִ�������������λ��Ϊ�㡣

nPalEntries��λָ����metafile�ĵ�ɫ�̱�����Ŀ�ĸ�����������û�����������

������ͷ��¼��������SIZEL�ṹ�����ǰ�������32λ��λ��cx��cy��szlDevice��λ ����metafile�е�ƫ����Ϊ0x0040��ָ������ͼ��Ϊ��λ������豸��С��szlMillimeters��λ��ƫ����Ϊ0x0050��ָ�����Ժ���Ϊ��λ������豸��С������ǿ��metafile�ļ��У��������豸���������ο��豸��reference device����������������Ϊ��һ���������ݸ�CreateEnhMetaFile���еĴ�����ָ����װ�����ݡ�����ò�����ΪNULL����GDIʹ����Ѷ��ʾ������EMF2����������ʾ��metafileʱ����������Windows NT����1024��768��ʾģʽ��������������GDIʹ�õIJο��豸��

GDIͨ������GetDeviceCapsȡ�ô���Ѷ��EMF2.EMF�е�szlDevice��λ��0x0400��0x0300����1024��768����������HORZRES��VERTRES��Ϊ��������GetDeviceCaps�õ��ġ�szlMillimeters��λ��0x140��0xF0����320��240������HORZSIZE��VERTSIZE��Ϊ��������GetDeviceCaps�õ��ġ�

ͨ���򵥵ij����Ϳ��Եó�ͼ��Ϊ0.3125mm�ߺ�0.3125mm���������ǰ��������GDI����rclFrame���γߴ�ķ�����

��metafile�У�ENHMETAHEADER�ṹ���һ�������ִ������ִ���CreateEnhMetaFile��ʽ������һ���������ڱ����У����ִ������һ��NULL��Ԫ�ġ�EMF2���ִ����������NULL��Ԫ�ġ�EMF Demo #2���ִ���ɡ��ܹ�18����Ԫ��Ҫ����Unicode��ʽ������Ϊ36����Ԫ�����۽���metafile�ij�ʽִ����Windows NT����Windows 98�£����ִ�ʼ����Unicode��ʽ���档

metafile��GDI���
��

�����Ѿ�֪����GDI��ͼ�������metafile�з�ʽ�����ڿ�һ��GDI����Ĵ��淽ʽ����ʽ18-4 EMF3���˽�����춻��ƾ��κ�ֱ�ߵķ��ڶ����ʺͻ�ˢ���⣬��ǰ����ܵ�EMF2��ʽ�����ơ��ó�ʽҲ��Rectangle��������������һ���޸ġ�EMF3��ʽʹ��GetVersion��ȷ��ִ�л�����Windows 98����Windows NT�����ʵ��ص���������

 ï¿½ï¿½Ê½18-4  EMF3
EMF3.C
/*----------------------------------------------------------------------------
   	EMF3.C -- 	Enhanced Metafile Demo #3
             					(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/

#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    							PSTR szCmdLine, int iCmdShow)
{
     	static TCHAR szAppName[] = TEXT ("EMF3") ;
     	HWND         							hwnd ;
     	MSG          							msg ;
     	WNDCLASS     						wndclass ;
     
     	wndclass.style         					= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   			= WndProc ;
     	wndclass.cbClsExtra    			= 0 ;
     	wndclass.cbWndExtra    			= 0 ;
     	wndclass.hInstance     			= hInstance ;
     	wndclass.hIcon         					= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       				= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground	 	= GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  		= NULL ;
     	wndclass.lpszClassName 		= szAppName ;
     
     	if (!RegisterClass (&wndclass))
     	{
          		MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                      							szAppName, MB_ICONERROR) ;
          		return 0 ;
     }
     
	hwnd = CreateWindow (	szAppName, TEXT ("Enhanced Metafile Demo #3"),
                          	WS_OVERLAPPEDWINDOW,
                          	CW_USEDEFAULT, CW_USEDEFAULT,
                          	CW_USEDEFAULT, CW_USEDEFAULT,
                          	NULL, NULL, hInstance, NULL) ;
     
     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;
     
     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
	return msg.wParam ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
     	LOGBRUSH     				lb ;
     	HDC          					hdc, hdcEMF ;
     	HENHMETAFILE 		hemf ;
     	PAINTSTRUCT  			ps ;
     	RECT         					rect ;
     	switch (message)
     {
     	case 	WM_CREATE:
          	hdcEMF = CreateEnhMetaFile (NULL, TEXT ("emf3.emf"), NULL,
            TEXT ("EMF3\0EMF Demo #3\0")) ;
          
          			SelectObject (hdcEMF, CreateSolidBrush (RGB (0, 0, 255))) ;
          
          			lb.lbStyle = BS_SOLID ;
          			lb.lbColor = RGB (255, 0, 0) ;
          			lb.lbHatch = 0 ;

          			SelectObject (hdcEMF, 
               		ExtCreatePen (PS_SOLID | PS_GEOMETRIC, 5, &lb, 0, NULL)) ;
          
          			if (GetVersion () & 0x80000000) // Windows 98
               		Rectangle (hdcEMF, 100, 100, 201, 201) ;
          			else    
				   // Windows NT
               					Rectangle (hdcEMF, 101, 101, 202, 202) ;
          
          			MoveToEx  		(hdcEMF, 100, 100, NULL) ;
          			LineTo    		(hdcEMF, 200, 200) ;
          
          			MoveToEx  		(hdcEMF, 200, 100, NULL) ;
          			LineTo    		(hdcEMF, 100, 200) ;
          
          			DeleteObject (SelectObject (hdcEMF, GetStockObject (BLACK_PEN))) ;
          			DeleteObject (SelectObject (hdcEMF, GetStockObject (WHITE_BRUSH))) ;
          
          			hemf = CloseEnhMetaFile (hdcEMF) ;
          
          					DeleteEnhMetaFile (hemf) ;
        					return 0 ;
          
     			case 	WM_PAINT:
        					hdc = BeginPaint (hwnd, &ps) ;
          
       					GetClientRect (hwnd, &rect) ;
          
        					rect.left   		=     	rect.right  		/ 4 ;
          					rect.right  		= 3 * 	rect.right  		/ 4 ;
          					rect.top    		=     	rect.bottom 		/ 4 ;
          					rect.bottom 		= 3 * 	rect.bottom 		/ 4 ;
          
          					hemf = GetEnhMetaFile (TEXT ("emf3.emf")) ;
          
          					PlayEnhMetaFile (hdc, hemf, &rect) ;
          					DeleteEnhMetaFile (hemf) ;
          					EndPaint (hwnd, &ps) ;
          					return 0 ;
          
     			case 	WM_DESTROY:
          					PostQuitMessage (0) ;
          					return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

�������������ģ�������CreateEnhMetaFile���ص�װ�����ݴ���������GDI��ʽʱ����Щ��ʽ���б�������metafile�ж�����ֱ�������өĻ��ӡ�����ϡ�Ȼ����һЩGDI��ʽ�������漰�ض���װ�����ݡ������йؽ������ʺͻ�ˢ��ͼ�������GDI��ʽʮ����Ҫ����Ȼ�߼����ʺͻ�ˢ�Ķ��崢������GDI�����ļ������У������ڽ�����Щ���ʱ����Щ����Ķ��岢δ���κ��ض���װ��������ء�

EMF3����CreateSolidBrush��ExtCreatePen��ʽ����Ϊ��Щ��ʽ����Ҫװ�����ݴ��ţ�`����GDI�������Щ���д�����metafile�����������ʱ��GDI��ʽֻ�Ǽ򵥵ؽ���ͼ�λ������������Ӱ��metafile��

Ȼ��������ʽ����SelectObject��ʽ��GDI���ѡ��metafileװ������ʱ��GDI��Ϊ���������ʽ���루Դ����춴���������ڲ�GDI���ϣ�ҲΪmetafile�е�SelectObject���н��б��롣Ϊ�˽��乤����ʽ����������һ��EMF3.EMF������ʮ����λ���룬��ͼ18-4��ʾ��

0000  	01 00 00 00 88 00 00 00 60 00 00 00 60 00 00 00	    ........`...`...
0010  	CC 00 00 00 CC 00 00 00 B8 0B 00 00 B8 0B 00 00     ................
0020  	E7 18 00 00 E7 18 00 00 20 45 4D 46 00 00 01 00  	........EMF.....
0030  	88 01 00 00 0F 00 00 00 03 00 00 00 12 00 00 00  	................
0040  	64 00 00 00 00 00 00 00 00 04 00 00 00 03 00 00  	d...............
0050  	40 01 00 00 F0 00 00 00 00 00 00 00 00 00 00 00  	@...............
0060  	00 00 00 00 45 00 4D 00 46 00 33 00 00 00 45 00  	....E.M.F.3...E.
0070  	4D 00 46 00 20 00 44 00 65 00 6D 00 6F 00 20 00 	M.F....D.e.m.o..
0080  	23 00 33 00 00 00 00 00 27 00 00 00 18 00 00 00  	#.3.....'.......
0090  	01 00 00 00 00 00 00 00 00 00 FF 00 00 00 00 00  	................
00A0  	25 00 00 00 0C 00 00 00 01 00 00 00 5F 00 00 00  	%..........._...
00B0  	34 00 00 00 02 00 00 00 34 00 00 00 00 00 00 00  	4.......4.......
00C0  	34 00 00 00 00 00 00 00 00 00 01 00 05 00 00 00  	4...............
00D0  	00 00 00 00 FF 00 00 00 00 00 00 00 00 00 00 00  	................
00E0  	25 00 00 00 0C 00 00 00 02 00 00 00 2B 00 00 00  	%...........+...
00F0  	18 00 00 00 63 00 00 00 63 00 00 00 C6 00 00 00  	....c...c.......
0100  	C6 00 00 00 1B 00 00 00 10 00 00 00 64 00 00 00  	............d...
0110  	64 00 00 00 36 00 00 00 10 00 00 00 C8 00 00 00  	d...6...........
0120  	C8 00 00 00 1B 00 00 00 10 00 00 00 C8 00 00 00  	................
0130  	64 00 00 00 36 00 00 00 10 00 00 00 64 00 00 00  	d...6.......d...
0140  	C8 00 00 00 25 00 00 00 0C 00 00 00 07 00 00 80  	....%...........
0150  	28 00 00 00 0C 00 00 00 02 00 00 00 25 00 00 00  	(...........%...
0160  	0C 00 00 00 00 00 00 80 28 00 00 00 0C 00 00 00  	........(.......
0170  	01 00 00 00 0E 00 00 00 14 00 00 00 00 00 00 00  	................
0180  	10 00 00 00 14 00 00 00							    ........
ͼ18-4 EMF3.EMF��ʮ����λ����

��������metafile��ǰ���EMF2.EMF�������бȽϣ���һ����ͬ�����EMF3.EMF��ͷ�����е�rclBounds��λ����EMF2.EMF�У���ָ��ͼ���޶�������(0x64,0x64)��(0xC8,0xC8)�����ڡ�����EMF3.EMF�У�������(0x60,0x60)��(0xCC,0xCC)�����ʾʹ���˽ϴֵıʡ�rclFrame��λ����0.01mmΪ��λָ��ͼ���С��Ҳ�ܵ�Ӱ�졣

EMF2.EMF�е�nBytes��λ��ƫ����Ϊ0x0030����ʾ��metafile����Ϊ0xFAλԪ�飬EMF3.EMF�г���Ϊ0x0188λԪ�顣EMF2.EMFmetafile����7����¼��һ����ͷ��¼��5��GDI��ʽ���к�һ������������¼��������EMF3.EMF��������15����¼�������8����¼���������������ʽ��4����SelectObject��ʽ�ĺ��к�������DeleteObject��ʽ�ĺ��С�

nHandles��λ���ڵ�����ƫ����Ϊ0x0038��ָ��GDI����Ĵ��Ÿ���������λ��ֵ���DZ�metafileʹ�õķ��ڶ��������һ����Platform SDK�ļ���������������һ�ǡ��˱��б���������������������λ��EMF2.EMF��ֵΪ1������EMF3.EMF�е�ֵΪ3���������ָ���˻��ʺͻ�ˢ��

����������������ƫ����Ϊ0x0088�ĵط������ڶ�����¼����ͷ��¼֮��ĵ�һ����¼������¼��̬Ϊ0x27����Ӧ����ΪEMR_CREATE-BRUSHINDIRECT����metafile��¼���CreateBrushIndirect��ʽ���˺�ʽ��Ҫָ��LOGBRUSH�ṹ��ָ����Ϊ�������ü�¼�ij���Ϊ0x18����24��λԪ�顣

ÿ����ѡ��metafileװ�����ݵķDZ���GDI����õ�һ�����룬�ú����1��ʼ��š����ڴ˼�¼����4��λԪ����ָ������metafile�е�ƫ������0x0090���˼�¼�����3��4λԪ����λ�ֱ��ӦLOGBRUSH�ṹ��3����λ��0x00000000��BS_SOLID��lbStyle��λ����0x00FF0000��lbColor��λ����0x00000000��lbHatch��λ����

��һ����¼��EMF3.EMF�е�ƫ����Ϊ0x00A0����¼��̬Ϊ0x25����EMR_SELECTOBJECT�������SelectObject���е�metafile��¼���ü�¼�ij���Ϊ0x0C����12��λԪ�飬��һ����λ����ֵ0x01��ָ������ѡ�еĵ�һ��GDI�����������߼���ˢ��

EMF3.EMF�е�ƫ����0x00AC����һ����¼�����ļ�¼��̬Ϊ0x5F��EMR_EXTCREATEPEN���ü�¼��0x34����52����λԪ�顣��һ��4λԪ����λ��0x02������ʾ������metafile��ʹ�õĵڶ����DZ���GDI�����

EMR_EXTCREATEPEN��¼����4����λ�ظ���¼��С���Σ�֮����0��λ������0x34��0x00��0x34��0x00����һ����λ��0x00010000������PS_SOLID (0x00000000)��PS_GEOMETRIC (0x00010000)��ϵĻ�����ʽ����������5����Ԫ�Ŀ��ȣ���������ExtCreatePen��ʹ�õ��߼���ˢ�ṹ��3����λ�����0��λ��

����������Զ�����չ������ʽ��EMR_EXTCREATEPEN��¼�ᳬ��52��λԪ�飬������Ӱ���¼�ĵڶ���λ�������ظ��Ĵ�С��λ��������LOGBRUSH�ṹ��3����λ���治����0������EMF3.EMF��������������ָ�������ߺͿո�����������������������ߺͿո񳤶ȵ�������λ��

EMF3.EMF����һ��12λԪ�����λ��ָ���ڶ�����������ʣ�����һ��SelectObject���С���������5����¼��EMF2.EMF�е�һ����һ��0x2B(EMR_RECTANGLE)�ļ�¼��̬������0x1B (EMR_MOVETOEX)��0x36 (EMR_LINETO)��¼��

��Щ��ͼ��ʽ�����������0x25(EMR_SELECTOBJECT)��0x28 (EMR_DELETEOBJECT)��12λԪ���¼��ѡ�������¼����0x80000007��0x80000000�IJ��������趨��λԪʱ����ָ��һ������������ڴ�������0x07����ӦBLACK_PEN����0x00 (WHITE_BRUSH)��

DeleteObject������2��1���������������metafile��ʹ�õ��������ڶ��������ȻDeleteObject��ʽ������Ҫװ�����ݴ�����Ϊ���ĵ�һ����������GDI��Ȼ������metafile��ʹ�õı���ʽɾ���������

���ᣬmetafile��0x0E��EMF_EOF����¼������

�ܽ�һ�£�ÿ�����ڶ���GDI����״α�ѡ��metafileװ������ʱ��GDI����Ϊ�����������ʽ�ļ�¼���루�����У�ΪEMR_CREATEBRUSHINDIRECT��EMR_EXTCREATEPEN����ÿ�������һ�������1��ʼ��Ψһ��ֵ������ֵ�ɼ�¼�ĵ�������λ��ʾ�����ڴ˼�¼��������ø���ֵ��EMR_SELECTOBJECT��¼�����ᣬ�����ѡ��metafileװ������ʱ�����м�ʱ��û�б�ɾ��������ֻ��ҪEMR_SELECTOBJECT��¼�ˡ�

metafile�͵���ͼ
��

���ڣ�������������΢���ӵ��£���metafileװ�������л���һ������ͼ�����ʽ18-5 EMF4��ʾ��

 ï¿½ï¿½Ê½18-5  EMF4
EMF4.C
/*----------------------------------------------------------------------------
   	EMF4.C -- 	Enhanced Metafile Demo #4
             					(c) Charles Petzold, 1998
----------------------------------------------------------------------------*/

#define OEMRESOURCE
#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    							PSTR szCmdLine, int iCmdShow)
{
     	static TCHAR 	szAppName[] = TEXT ("EMF4") ;
     	HWND         				hwnd ;
     	MSG          				msg ;
     	WNDCLASS     			wndclass ;
     
     	wndclass.style         					= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   			= WndProc ;
     	wndclass.cbClsExtra    			= 0 ;
     	wndclass.cbWndExtra    			= 0 ;
     	wndclass.hInstance     			= hInstance ;
     	wndclass.hIcon         					= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       				= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 		= GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  		= NULL ;
     	wndclass.lpszClassName 		= szAppName ;
     
     	if (!RegisterClass (&wndclass))
     	{
          		MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                      							szAppName, MB_ICONERROR) ;
          		return 0 ;
     	}
     
     	hwnd = CreateWindow (	szAppName, TEXT ("Enhanced Metafile Demo #4"),
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         NULL, NULL, hInstance, NULL) ;
     
     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;
     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
	return msg.wParam ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
     	BITMAP       			bm ;
     	HBITMAP      			hbm ;
     	HDC          			hdc, hdcEMF, hdcMem ;
     	HENHMETAFILE 			hemf ;
     	PAINTSTRUCT  			ps ;
     	RECT         			rect ;
     
     	switch (message)
     	{
     	case 	WM_CREATE:
          	hdcEMF = CreateEnhMetaFile (NULL, TEXT ("emf4.emf"), NULL,
            TEXT ("EMF4\0EMF Demo #4\0")) ;
          
          			hbm = LoadBitmap (NULL, MAKEINTRESOURCE (OBM_CLOSE)) ;
          
          			GetObject (hbm, sizeof (BITMAP), &bm) ;
          
          			hdcMem = CreateCompatibleDC (hdcEMF) ;
          
          			SelectObject (hdcMem, hbm) ;
          
          			StretchBlt (hdcEMF,100,100,100,100,
                	hdcMem,	0,0,bm.bmWidth, bm.bmHeight, SRCCOPY) ;
          
          			DeleteDC (hdcMem) ;
			DeleteObject (hbm) ;
          
          			hemf = CloseEnhMetaFile (hdcEMF) ;
          
          			DeleteEnhMetaFile (hemf) ;
          			return 0 ;
          
     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;
          
          			GetClientRect (hwnd, &rect) ;
          			rect.left   		=     rect.right		/ 4 ;
          			rect.right  		= 3 * rect.right 		/ 4 ;
          			rect.top    			=     rect.bottom	/ 4 ;
          			rect.bottom 		= 3 * rect.bottom		/ 4 ;
          
          			hemf = GetEnhMetaFile (TEXT ("emf4.emf")) ;
          
          			PlayEnhMetaFile (hdc, hemf, &rect) ;
          			DeleteEnhMetaFile (hemf) ;
          			EndPaint (hwnd, &ps) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			PostQuitMessage (0) ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

Ϊ�˷��㣬EMF4�����ɳ���OEM_CLOSEָ����ϵͳ����ͼ����װ����������ʾ����ͼ�Ĺ��÷�����ͨ��ʹ��CreateCompatibleDC������Ŀ��װ�����ݣ�����Ϊmetafileװ�����ݣ����ݵļ�����װ�����ݡ�Ȼ�ᣬͨ��ʹ��SelectObject������ͼѡ��ü�����װ�����ݲ��ҴӸü�����װ�����ݺ���BitBlt��StretchBlt�ѵ���ͼ����Ŀ��װ�����ݡ������ᣬɾ��������װ�����ݺ͵���ͼ��

����ע�⵽EMF4Ҳ����GetObject��ȷ������ͼ�Ĵ�С�����SelectObject�����Ǻܱ�Ҫ�ġ�

���ȣ���ݳ�ʽ�봢��metafile�Ŀռ��GDI��˵���Ǹ���ս����StretchBlt����ǰ����û�б��GDI��ʽȥ����metafile��װ�����ݡ���ˣ�����������һ��EMF4.EMF��ͷ��������ģ�ͼ18-5ֻ��ʾ��һ���֡�

0000  	01 00 00 00 88 00 00 00 64 00 00 00 64 00 00 00  		........d...d...
0010  	C7 00 00 00 C7 00 00 00 35 0C 00 00 35 0C 00 00	  	    ........5...5...
0020  	4B 18 00 00 4B 18 00 00 20 45 4D 46 00 00 01 00  		K...K....EMF....
0030  	F0 0E 00 00 03 00 00 00 01 00 00 00 12 00 00 00  		................
0040  	64 00 00 00 00 00 00 00 00 04 00 00 00 03 00 00  		d...............
0050  	40 01 00 00 F0 00 00 00 00 00 00 00 00 00 00 00  		@...............
0060  	00 00 00 00 45 00 4D 00 46 00 34 00 00 00 45 00  		....E.M.F.4...E.
0070  	4D 00 46 00 20 00 44 00 65 00 6D 00 6F 00 20 00 		M.F...D.e.m.o...
0080  	23 00 34 00 00 00 00 00 4D 00 00 00 54 0E 00 00  		#.4.....M...T...
0090  	64 00 00 00 64 00 00 00 C7 00 00 00 C7 00 00 00  		d...d...........
00A0  	64 00 00 00 64 00 00 00 64 00 00 00 64 00 00 00  		d...d...d...d...
00B0  	20 00 CC 00 00 00 00 00 00 00 00 00 00 00 80 3F  		..............?
00C0  	00 00 00 00 00 00 00 00 00 00 80 3F 00 00 00 00  		...........?....
00D0  	00 00 00 00 FF FF FF 00 00 00 00 00 6C 00 00 00  		............l...
00E0  	28 00 00 00 94 00 00 00 C0 0D 00 00 28 00 00 00  		(...........(...
00F0  	16 00 00 00 28 00 00 00 28 00 00 00 16 00 00 00  		....(...(.......
0100  	01 00 20 00 00 00 00 00 C0 0D 00 00 00 00 00 00  		.. .............
0110  	00 00 00 00 00 00 00 00 00 00 00 00 C0 C0 C0 00  		................
0120  	C0 C0 C0 00 C0 C0 C0 00 C0 C0 C0 00 C0 C0 C0 00  	    ................
. . . . 
0ED0  	C0 C0 C0 00 C0 C0 C0 00 C0 C0 C0 00 0E 00 00 00  	    ................
0EE0  	14 00 00 00 00 00 00 00 10 00 00 00 14 00 00 00  		................
ͼ18-5 EMF4.EMF�IJ���ʮ����λ����

��metafileֻ����3����¼����ͷ��¼��0x0E54λԪ�鳤�ȵ�0x4D����EMR_STRETCHBLT���͵���������¼��

�Ҳ����͸ü�¼ÿ����λ�ĺ��壬���һ�ָ���ؼ����֣��Ա�����GDI��EMF4.C�е�һϵ�к�ʽ����ת��Ϊ����metafile��¼�ķ�����

GDI�Ѿ���ԭʼ�����豸��صĵ���ͼת��Ϊ��װ���޹صĵ���ͼ��DIB��������DIB�����ڼ�¼��������С�ļ�¼�С����룬����ʾmetafile�͵���ͼʱ��GDIʵ����ʹ��StretchDIBits��ʽ������StretchBlt�����ߣ�GDIʹ��CreateDIBitmap��DIBת������豸��صĵ���ͼ��Ȼ��ʹ�ü�����װ�����ݼ�StretchBlt����ʾ����ͼ��

EMR_STRETCHBLT��¼��ʼ�metafile��ƫ����0x0088����DIB������metafile�У���ƫ����0x00F4��ʼ����0x0EDC���ļ�¼��β������DIB��BITMAPINFOHEADER��̬��40λԪ��Ľṹ��ʼ����ƫ����0x011C������22��ͼ���У�ÿ��40��ͼ�ء�����ÿͼ��32λԪ��DIB������ÿ��ͼ����Ҫ4��λԪ�顣

�о�metafile����
��

����ϣ����ȡmetafile�ڵĸ����¼ʱ������ʹ�ó���metafile�оٵij������ʽ18-6 EMF5��ʾ���˳�ʽʹ��metafile����ʾ��EMF3��ͬ��ͼ�񣬵�����ͨ��metafile�о������еġ�

 ï¿½ï¿½Ê½18-6 EMF5
EMF5.C
/*----------------------------------------------------------------------------
   	EMF5.C -- 	Enhanced Metafile Demo #5
             					(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/
#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    							PSTR szCmdLine, int iCmdShow)
{
     	static TCHAR 	szAppName[] = TEXT ("EMF5") ;
     	HWND         				hwnd ;
     	MSG          				msg ;
     	WNDCLASS     			wndclass ;
     
     	wndclass.style         					= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   			= WndProc ;
     	wndclass.cbClsExtra    			= 0 ;
     	wndclass.cbWndExtra    			= 0 ;
     	wndclass.hInstance     			= hInstance ;
     	wndclass.hIcon         					= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       				= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 		= GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  		= NULL ;
     	wndclass.lpszClassName 		= szAppName ;
     
     	if (!RegisterClass (&wndclass))
     	{
          		MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                      							szAppName, MB_ICONERROR) ;
          		return 0 ;
     }
     
     	hwnd = CreateWindow (	szAppName, TEXT ("Enhanced Metafile Demo #5"),
                          	WS_OVERLAPPEDWINDOW,
                          	CW_USEDEFAULT, CW_USEDEFAULT,
                          	CW_USEDEFAULT, CW_USEDEFAULT,
                          	NULL, NULL, hInstance, NULL) ;
     
     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;
     
     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
     	return msg.wParam ;
}

int CALLBACK EnhMetaFileProc (	HDC hdc, HANDLETABLE * pHandleTable,
                                CONST ENHMETARECORD * pEmfRecord, 
                              	int iHandles, LPARAM pData)
{
     	PlayEnhMetaFileRecord (hdc, pHandleTable, pEmfRecord, iHandles) ;
     	return TRUE ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
     	HDC          		hdc ;
     	HENHMETAFILE 		hemf ;
     	PAINTSTRUCT  		ps ;
     	RECT         		rect ;
     
     	switch (message)
     {
     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;
          
          			GetClientRect (hwnd, &rect) ;
          
          			rect.left   			=     rect.right		/ 4 ;
          			rect.right  			= 3 * rect.right		/ 4 ;
          			rect.top    			=     rect.bottom		/ 4 ;
          			rect.bottom 			= 3 * rect.bottom		/ 4 ;
          
          		hemf = GetEnhMetaFile (TEXT ("..\\emf3\\emf3.emf")) ;
          
          			EnumEnhMetaFile (hdc, hemf, EnhMetaFileProc, NULL, &rect) ;
          			DeleteEnhMetaFile (hemf) ;
          			EndPaint (hwnd, &ps) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			PostQuitMessage (0) ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

�˳�ʽʹ��EMF3��ʽ������EMF3.EMF����������ȷ����ִ�д˳�ʽǰ��ִ��EMF3��ʽ��ͬʱ����Ҫ��Visual C++������ִ��������ʽ����ȷ��·������ȷ���ڴ���WM_PAINTʱ��������ʽ����Ҫ������EMF3����PlayEnhMetaFile����EMF5����EnumEnhMetaFile��PlayEnhMetaFile��ʽ��������﷨��

PlayEnhMetaFile (hdc, hemf, &rect) ;

��һ��������Ҫ��ʾ��metafile��װ�����ݴ��š��ڶ�����������ǿ��metafile���š�������������ָ������װ������ƽ���Ͼ��ε�RECT�ṹ��ָ�ꡣMetafileͼ���С�����Ź����Ա�պ��ܹ���ʾ�ڲ������þ��ε������ڡ�

EnumEnhMetaFile��5������������3����PlayEnhMetaFileһ������ȻRECT�ṹ��ָ���Ѿ��Ƶ���������ĩβ����

EnumEnhMetaFile�ĵ������������оٺ�ʽ�����ƣ�����춺���EnhMetaFileProc�����ĸ�������ϣ�����ݸ��оٺ�ʽ���������ϵ�ָ�꣬���ォ�ò����򵥵��趨ΪNULL��

���ڿ�һ���оٺ�ʽ��������EnumEnhMetaFileʱ�����metafile�е�ÿһ����¼��GDI��������EnhMetaFileProcһ�Σ�������ͷ��¼�͵���������¼��ͨ���оٺ�ʽ����TRUE���������ܴ���FALSE���Թ�ʣ�µ��оٳ���

���оٺ�ʽ��5��������������������ǡ��������ʽ�У��ҽ���ǰ4���������ݸ�PlayEnhMetaFileRecord����ʹGDIִ���ɸü�¼�����ĺ�ʽ���У���������ȷ�غ�����һ����

EMF5ʹ��EnumEnhMetaFile��PlayEnhMetaFileRecord�õ��Ľ����EMF3����PlayEnhMetaFile�õ��Ľ��һ�����������EMF5����ֱ�ӽ�����metafile����ʾ���򣬲��ܹ���ȡ����metafile��¼�����Ǻ����õġ�

�оٺ�ʽ�ĵ�һ��������װ�����ݴ��š�GDI��EnumEnhMetaFile�ĵ�һ�������м򵥵�ȡ�ô˴��š��оٺ�ʽ�Ѹô��Ŵ��ݸ�PlayEnhMetaFileRecord����ʶͼ����ʾ��Ŀ��װ�����ݡ�

�����������оٺ�ʽ�ĵ���������������ָ��ENHMETARECORD��̬�ṹ��ָ�꣬ǰ���Ѿ��ᵽ��������ṹ����ʵ�ʵ�metafile��¼��������������metafile�б���һ����

������дһЩ��ʽ���������Щ��¼����Ҳ�������ijЩ��¼���͵�PlayEnhMetaFileRecord��ʽ�����磬��EMF5.C�У������в��뵽PlayEnhMetaFileRecord���е�ǰ�棺

if (pEmfRecord->iType != EMR_LINETO)

���±������ִ��������ֻ�������Σ���û�������ߡ���ʹ�������������

if (pEmfRecord->iType != EMR_SELECTOBJECT)

���С�ı����GDI���ڶ������ʾͼ�񣬶�������metafile�������Ļ��ʺͻ�ˢ��

��ʽ�в�Ӧ���޸�metafile��¼�������Ȳ�Ҫ������һ�㡣������һ����ʽ18-7 EMF6��

 ï¿½ï¿½Ê½18-7 EMF6
EMF6.C
/*----------------------------------------------------------------------------
   	EMF6.C -- 	Enhanced Metafile Demo #6
             					(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/

#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    							PSTR lpszCmdLine, int iCmdShow)
{
     	static TCHAR 	szAppName[] = TEXT ("EMF6") ;
     	HWND         				hwnd ;
     	MSG          				msg ;
     	WNDCLASS     			wndclass ;
     
     	wndclass.style         			= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   			= WndProc ;
     	wndclass.cbClsExtra    			= 0 ;
     	wndclass.cbWndExtra    			= 0 ;
     	wndclass.hInstance     			= hInstance ;
     	wndclass.hIcon         			= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       		= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 		= GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  		= NULL ;
     	wndclass.lpszClassName 		= szAppName ;
     
     	if (!RegisterClass (&wndclass))
     	{
          		MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                      							szAppName, MB_ICONERROR) ;
          		return 0 ;
     	}
     
     	hwnd = CreateWindow (szAppName, TEXT ("Enhanced Metafile Demo #6"),
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         NULL, NULL, hInstance, NULL) ;
     
     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;
     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
     	return msg.wParam ;
}

int CALLBACK EnhMetaFileProc (	HDC hdc, HANDLETABLE * pHandleTable,
                              	CONST ENHMETARECORD * pEmfRecord, 
                              	int iHandles, LPARAM pData)
{
     	ENHMETARECORD * pEmfr ;
     	pEmfr = (ENHMETARECORD *) malloc (pEmfRecord->nSize) ;
     	CopyMemory (pEmfr, pEmfRecord, pEmfRecord->nSize) ;
     	if (pEmfr->iType == EMR_RECTANGLE)
          			pEmfr->iType = EMR_ELLIPSE ;
     	PlayEnhMetaFileRecord (hdc, pHandleTable, pEmfr, iHandles) ;
     	free (pEmfr) ;
     	return TRUE ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	HDC          		hdc ;
     	HENHMETAFILE 		hemf ;
     	PAINTSTRUCT  		ps ;
     	RECT         		rect ;
     
     	switch (message)
     	{
     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;
          
          			GetClientRect (hwnd, &rect) ;
          
          			rect.left   			=     rect.right	/ 4 ;
          			rect.right  			= 3 * rect.right 	/ 4 ;
          			rect.top    			=     rect.bottom	/ 4 ;
          			rect.bottom 			= 3 * rect.bottom	/ 4 ;
          
          	hemf = GetEnhMetaFile (TEXT ("..\\emf3\\emf3.emf")) ;
          	EnumEnhMetaFile (	hdc, hemf, EnhMetaFileProc, NULL, &rect) ;
          						DeleteEnhMetaFile (hemf) ;
          						EndPaint (hwnd, &ps) ;
          						return 0 ;
          
     	case 	WM_DESTROY:
          			PostQuitMessage (0) ;
          			return 0 ;
     }
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

��EMF5һ����EMF6ʹ��EMF3��ʽ������EMF3.EMFmetafile�����Ҫ��Visual C++��ִ�������ʽ֮ǰ��ִ�й�EMF3��ʽ��

EMF6չʾ���������ʾmetafile֮ǰҪ�޸����ǣ���������Ƿdz��򵥵ģ��������޸Ĺ��ĸ��������ͺ��ˡ������Կ������оٳ���һ��ʼʹ��malloc����һ��metafile��¼��С�ļ����壬�����ɴ��ݸ��ú�ʽ��pEmfRecord�ṹ��nSize��λ��ʾ�ġ������������ָ�괢���ڱ���pEmfr�У�pEmfr������ָ��ENHMETARECORD�ṹ��ָ�ꡣ

��ʽʹ��CopyMemory��pEmfRecordָ��Ľṹ���ݸ��Ƶ�pEmfrָ��Ľṹ�С��������ǾͿ�����Щ�޸��ˡ���ʽ����¼�Ƿ�ΪEMR_RECTANGLE��̬������ǣ�����EMR_ELLIPSEȡ��iType��λ��PEmfrָ�걻���ݵ�PlayEnhMetaFileRecordȻ�ᱻ�ͷš�����dz�ʽ����һ����Բ�����Ǿ��Ρ����������ݵ��޸ķ�ʽ������ͬ�ġ�

��Ȼ�����ǵ�С�ı�����������ã���ΪRectangle��Ellipse��ʽ��ͬ���IJ�������Щ����������ͬһ���£�ͼ���ı߽��Ҫ���з�Χ������޸���ҪһЩ��ͬmetafile��¼��ʽ�����֪ʶ��

��һ���������Dz���һ����������ļ�¼�����磬���������������EMF6.C�е�if������

if (pEmfr->iType == EMR_RECTANGLE)
{
     	PlayEnhMetaFileRecord (hdc, pHandleTable, pEmfr, nObjects) ;
     	pEmfr->iType = EMR_ELLIPSE ;
}

���ۺ�ʱ����Rectangle��¼����ʽ���ᴦ���˼�¼����������ΪEllipse��Ȼ������ʾ�����ڳ�ʽ���������κ���Բ��

��������һ�����о�metafileʱGDI��������ķ�ʽ��

��metafile��ͷ�У�ENHMETAHEADER�ṹ��nHandles��λ�DZ���metafile�н�����GDI�������Ҫ���ֵ����ˣ����EMF5��EMF6�е�metafile������λ��3����ʾ���ʡ���ˢ�������������������������ľ������ݣ������һ�˵����

����ע�⵽EMF5��EMF6���оٺ�ʽ�ĵ����ڶ���������Ҳ����nHandles������ͬһ������3��

�оٺ�ʽ�ĵڶ���������ָ��HANDLETABLE�ṹ��ָ�꣬��WINGDI.H�ж������£�

typedef struct tagHANDLETABLE
{
     	HGDIOBJ objectHandle [1] ;
}
HANDLETABLE ;

HGDIOBJ������̬��GDI����Ĵ��ţ�������Ϊ32λԪ��ָ�꣬�������������GDI�����������Щ����һ��Ԫ�ص�������λ�Ľṹ֮һ������ζ������λ���пɱ�ij��ȡ�objectHandle�����е�Ԫ�������nHandles���ڴ˳�ʽ����3��

���оٺ�ʽ�У�����ʹ����������ʽȡ����ЩGDI������ţ�

pHandleTable->objectHandle[i]

���3�����ţ�i��0��1��2��

ÿ�κ����оٺ�ʽʱ�����еĵ�һ��Ԫ�ض����������оٵ�metafile���š������ǰ���ᵽ�ġ�������������

�ڵ�һ�κ����оٺ�ʽʱ�����ĵڶ���������Ԫ�ؽ���0�������ǻ��ʺͻ�ˢ���ŵı���λ�á�

�������оٺ�ʽ�����ķ�ʽ��metafile�еĵ�һ�����������ʽ����EMR_CREATEBRUSHINDIRECT�ļ�¼��̬���˼�¼ָ����������1�����Ѹü�¼���ݸ�PlayEnhMetaFileRecordʱ��GDI������ˢ��ȡ�����Ĵ��š��˴��Ŵ�����objectHandle���е�Ԫ��1���ڶ���Ԫ�أ��С����ѵ�һ��EMR_SELECTOBJECT��¼���ݸ�PlayEnhMetaFileRecordʱ��GDI���ִ�������Ϊ1�����ܹ��ӱ����ҵ������ʵ�ʵĴ��ţ���������������SelectObject����metafile����ɾ����ˢʱ��GDI��objectHandle���е�Ԫ��1�趨��0��

ͨ����ȡobjectHandle���У�����ʹ������GetObjectType��GetObject�Ⱥ���ȡ����metafile��ʹ�õ������Ѷ��

Ƕ��ͼ��
��

�о�metafile������ҪӦ��Ҳ���������е�metafile��Ƕ������ͼ������������metafile������ʵ�ϣ����е�metafile���ֲ��䣻�������е��ǽ�����������metafile����Ƕ��ͼ�����metafile�������ļ����ǰ�metafileװ�����ݴ��Ŵ��ݸ�EnumEnhMetaFile����Ϊ���ĵ�һ����������ʹ���ܹ���metafileװ����������ʾmetafile��¼��GDI��ʽ���С�

��metafile�������еĿ�ͷ���βǶ����ͼ���Ǽ��򵥵ģ�����EMR_HEADER��¼֮�����EMF_EOF��¼֮ǰ��Ȼ�����������Ϥ���е�metafile�ṹ���Ϳ��԰��µĻ�ͼ����Ƕ��������κεط������ʽ18-8 EMF7��ʾ��

 ï¿½ï¿½Ê½18-8 EMF7
EMF7.C
/*---------------------------------------------------------------------------
   	EMF7.C -- Enhanced Metafile Demo #7
             					(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/

#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (	HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    								PSTR lpszCmdLine, int iCmdShow)
{
     	static TCHAR 	szAppName[] = TEXT ("EMF7") ;
     	HWND         				hwnd ;
     	MSG          				msg ;
     	WNDCLASS     			wndclass ;
     
  	wndclass.style         				= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   			= WndProc ;
     	wndclass.cbClsExtra    			= 0 ;
     	wndclass.cbWndExtra    			= 0 ;
     	wndclass.hInstance     			= hInstance ;
     	wndclass.hIcon         			= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       		= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 		= GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  		= NULL ;
     	wndclass.lpszClassName 		= szAppName ;
     
     	if (!RegisterClass (&wndclass))
     	{
          		MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                      							szAppName, MB_ICONERROR) ;
          		return 0 ;
     	}
     
     	hwnd = CreateWindow (szAppName, TEXT ("Enhanced Metafile Demo #7"),
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         NULL, NULL, hInstance, NULL) ;
     
     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;
     
     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
     return msg.wParam ;
}

int CALLBACK EnhMetaFileProc (	HDC hdc, HANDLETABLE * pHandleTable,
                              	CONST ENHMETARECORD * pEmfRecord, 
                                int iHandles, LPARAM pData)
{
     	HBRUSH   			hBrush ;
     	HPEN     				hPen ;
     	LOGBRUSH 			lb ;
     
     	if (pEmfRecord->iType != EMR_HEADER && pEmfRecord->iType != EMR_EOF)
          		PlayEnhMetaFileRecord (hdc, pHandleTable, pEmfRecord, iHandles) ;
     	if (pEmfRecord->iType == EMR_RECTANGLE)
     	{
          		hBrush = SelectObject (hdc, GetStockObject (NULL_BRUSH)) ;
         		lb.lbStyle = BS_SOLID ;
          		lb.lbColor = RGB (0, 255, 0) ;
          		lb.lbHatch = 0 ;
          
          		hPen = SelectObject (hdc,
               					ExtCreatePen (PS_SOLID | PS_GEOMETRIC, 5, &lb, 0, NULL)) ;
		Ellipse (hdc, 100, 100, 200, 200) ;
          		DeleteObject (SelectObject (hdc, hPen)) ;
          		SelectObject (hdc, hBrush) ;
     	}
     	return TRUE ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
     	ENHMETAHEADER 		emh ;
     	HDC           					hdc, hdcEMF ;
     	HENHMETAFILE  		hemfOld, hemf ;
     	PAINTSTRUCT   			ps ;
     	RECT          					rect ;
     	
     	switch (message)
     	{
     	case 	WM_CREATE:
          
               							// Retrieve existing metafile and header
          
          			hemfOld = GetEnhMetaFile (TEXT ("..\\emf3\\emf3.emf")) ;
          
         	 		GetEnhMetaFileHeader (hemfOld, sizeof (ENHMETAHEADER), &emh) ;
          
               							// Create a new metafile DC
          
			hdcEMF = CreateEnhMetaFile (NULL, TEXT ("emf7.emf"), NULL,
                                      	TEXT ("EMF7\0EMF Demo #7\0")) ;
          
               							// Enumerate the existing metafile
          
          			EnumEnhMetaFile (hdcEMF, hemfOld, EnhMetaFileProc, NULL,
                           			(RECT *) & emh.rclBounds) ;
          
               							// Clean up
          
			hemf = CloseEnhMetaFile (hdcEMF) ;
          
			DeleteEnhMetaFile (hemfOld) ;
          			DeleteEnhMetaFile (hemf) ;
          			return 0 ;
          
     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;
          
          			GetClientRect (hwnd, &rect) ;
          			rect.left   			=     rect.right 	/ 4 ;
          			rect.right  			= 3 * rect.right 	/ 4 ;
          			rect.top    			=     rect.bottom   / 4 ;
          			rect.bottom		        = 3 * rect.bottom   / 4 ;
          
          			hemf = GetEnhMetaFile (TEXT ("emf7.emf")) ;
          
          			PlayEnhMetaFile (hdc, hemf, &rect) ;
          			DeleteEnhMetaFile (hemf) ;
          			EndPaint (hwnd, &ps) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			PostQuitMessage (0) ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

EMF7ʹ��EMF3��ʽ������EMF3.EMF��������ִ��EMF7֮ǰҪִ��EMF3��ʽ����metafile��

EMF7�е�WM_PAINT����ʹ��PlayEnhMetaFile������EnumEnhMetaFile������WM_CREATE�����кܴ�IJ��

���ȣ���ʽͨ������GetEnhMetaFileȡ��EMF3.EMF������metafile���ţ�������GetEnhMetaFileHeader�õ���ǿ��metafile��ͷ��¼��Ŀ�����������EnumEnhMetaFile������ʹ��rclBounds��λ��

����������ʽ�����µ�metafile��������ΪEMF7.EMF��CreateEnhMetaFile��ʽΪmetafile����װ�����ݴ��š�Ȼ�ᣬʹ��EMF7.EMF��metafileװ�����ݴ��ź�EMF3.EMF��metafile���ź���EnumEnhMetaFile��

��������һ��EnhMetaFileProc��������оٵļ�¼���DZ�ͷ��¼�򵵰�������¼����ʽ�ͺ���PlayEnhMetaFileRecord�Ѽ�¼ת��Ϊ�µ�metafileװ�����ݣ�����һ���ų���ͷ��¼�򵵰�������¼�������ǻ�ʹmetafile��󣩡�

�����ת���ļ�¼��Rectangle���У���ʽ������������ɫ�������ߺ�͸�����ڲ���������Բ��ע���ʽ�о��ɴ�����ǰ�Ļ��ʺͻ�ˢ�������ָ�װ������״̬�ķ������ڴ��ڼ䣬������Щ��ʽ�������뵽metafile�У���ס��Ҳ����ʹ��PlayEnhMetaFile�����е�metafile�в�������metafile����

�ص�WM_CREATE��������ʽ����CloseEnhMetaFileȡ����metafile�Ĵ��š�Ȼ�ᣬ��ɾ������metafile���ţ���EMF3.EMF��EMF7.EMF�������ڴ�Ƭ�ϡ�

�ӳ�ʽ��ʾ����п��Ժ����Եؿ�������Բ���ھ���֮������������֮ǰ���Ƶġ�

��ǿ��metafile��������ӡ����
��

ʹ�ü�����ת����ǿ��metafile�dz��򵥣���������̬��CF_ENHMETAFILE��GetClipboardData��ʽ������ǿ��metafile���ţ�SetClipboardDataҲʹ�ø�metafile���š�����metafileʱ����ʹ��CopyEnhMetaFile��ʽ���������ǿ��metafile���ڼ������У�Windows������Ҫ�ɸ�ʽ����Щ��ʽҲ����ʹ����������ڼ������з��þɸ�ʽ��metafile��Windows��Ҳ���Զ�����Ҫ������ת��Ϊ��ǿ��metafile�ĸ�ʽ��

��ʽ18-9 EMFVIEW��ʾΪ�ڼ������д���metafile�ij�ʽ�룬��Ҳ�������롢�������ӡmetafile��

 ï¿½ï¿½Ê½18-9 EMFVIEW
EMFVIEW.C
/*---------------------------------------------------------------------------
   	EMFVIEW.C -- 	View Enhanced Metafiles
                						(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/

#include <windows.h>
#include <commdlg.h>
#include "resource.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
TCHAR szAppName[] = TEXT ("EmfView") ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    							PSTR szCmdLine, int iCmdShow)
{
     	HACCEL   			hAccel ;
     	HWND     				hwnd ;
     	MSG      				msg ;
	WNDCLASS wndclass ;
     	wndclass.style         			= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   			= WndProc ;
     	wndclass.cbClsExtra    			= 0 ;
     	wndclass.cbWndExtra    			= 0 ;
     	wndclass.hInstance     			= hInstance ;
     	wndclass.hIcon         		= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       		= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 		= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  		= szAppName ;
     	wndclass.lpszClassName 		= szAppName ;

     	if (!RegisterClass (&wndclass))
     	{
          		MessageBox (	NULL, TEXT ("This program requires Windows NT!"), 
                      							szAppName, MB_ICONERROR) ;
          		return 0 ;
     	}

     	hwnd = CreateWindow (	szAppName, TEXT ("Enhanced Metafile Viewer"),
                          		WS_OVERLAPPEDWINDOW,
                          		CW_USEDEFAULT, CW_USEDEFAULT,
                          		CW_USEDEFAULT, CW_USEDEFAULT, 
                          		NULL, NULL, hInstance, NULL) ;

     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;

     	hAccel = LoadAccelerators (hInstance, szAppName) ;
     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          		if (!TranslateAccelerator (hwnd, hAccel, &msg))
          		{
               			TranslateMessage (&msg) ;
              	 		DispatchMessage (&msg) ;
          		}
     	}
     	return msg.wParam ;
}

HPALETTE CreatePaletteFromMetaFile (HENHMETAFILE hemf)
{
     	HPALETTE     			hPalette ;
     	int          				iNum ;
     	LOGPALETTE *	plp ;

     	if (!hemf)
          			return NULL ;
     	if (0 == (iNum = GetEnhMetaFilePaletteEntries (hemf, 0, NULL)))
          			return NULL ;
     	plp = malloc (sizeof (LOGPALETTE) + (iNum - 1) * sizeof (PALETTEENTRY)) ;
     	plp->palVersion    = 0x0300 ;
     	plp->palNumEntries = iNum ;

     	GetEnhMetaFilePaletteEntries (hemf, iNum, plp->palPalEntry) ;
     	hPalette = CreatePalette (plp) ;
     	free (plp) ;
     	return hPalette ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
     	static DOCINFO  	di = { sizeof (DOCINFO), TEXT ("EmfView: Printing") } ;
     	static HENHMETAFILE hemf ;
     	static OPENFILENAME ofn ;
     	static PRINTDLG     		printdlg = { sizeof (PRINTDLG) } ;
     	static TCHAR        			szFileName [MAX_PATH], szTitleName [MAX_PATH] ;
     	static TCHAR        			szFilter[] = 
                               								TEXT ("Enhanced Metafiles (*.EMF)\0*.emf\0")
                               								TEXT ("All Files (*.*)\0*.*\0\0") ;
     	BOOL                						bSuccess ;
     	ENHMETAHEADER       			header ;
     	HDC                 						hdc, hdcPrn ;
     	HENHMETAFILE        			hemfCopy ;
     	HMENU               						hMenu ;
     	HPALETTE            					hPalette ;
     	int                 						i, iLength, iEnable ;
     	PAINTSTRUCT         				ps ;
     	RECT                						rect ;
     	PTSTR               						pBuffer ;

     	switch (message)
     	{
     	case WM_CREATE:
               			// Initialize OPENFILENAME structure
          			ofn.lStructSize       			= sizeof (OPENFILENAME) ;
          			ofn.hwndOwner         			= hwnd ;
          			ofn.hInstance         			= NULL ;
          			ofn.lpstrFilter       			= szFilter ;
          			ofn.lpstrCustomFilter 		    = NULL ;
          			ofn.nMaxCustFilter    			= 0 ;
          			ofn.nFilterIndex      			= 0 ;
          			ofn.lpstrFile         			= szFileName ;
          			ofn.nMaxFile          			= MAX_PATH ;
          			ofn.lpstrFileTitle    			= szTitleName ;
          			ofn.nMaxFileTitle     			= MAX_PATH ;
          			ofn.lpstrInitialDir   			= NULL ;
          			ofn.lpstrTitle        			= NULL ;
          			ofn.Flags             			= 0 ;   
          			ofn.nFileOffset       			= 0 ;
          			ofn.nFileExtension    			= 0 ;
          			ofn.lpstrDefExt       			= TEXT ("emf") ;
          			ofn.lCustData         			= 0 ;
          			ofn.lpfnHook          			= NULL ;
          			ofn.lpTemplateName    			= NULL ;
         	 		return 0 ;

 	case 	WM_INITMENUPOPUP:
          			hMenu = GetMenu (hwnd) ;

          			iEnable = hemf ? MF_ENABLED : MF_GRAYED ;

          	EnableMenuItem (hMenu, IDM_FILE_SAVE_AS,    		iEnable) ;
          	EnableMenuItem (hMenu, IDM_FILE_PRINT,      		iEnable) ;
          	EnableMenuItem (hMenu, IDM_FILE_PROPERTIES, 		iEnable) ;
         	EnableMenuItem (hMenu, IDM_EDIT_CUT,        		iEnable) ;
   			EnableMenuItem (hMenu, IDM_EDIT_COPY,       		iEnable) ;
   			EnableMenuItem (hMenu, IDM_EDIT_DELETE,     		iEnable) ;
   			EnableMenuItem (hMenu, IDM_EDIT_PASTE,
			IsClipboardFormatAvailable (CF_ENHMETAFILE) ?
			MF_ENABLED : MF_GRAYED) ;
   			return 0 ;

     	case 	WM_COMMAND:
          		switch (LOWORD (wParam))
          				{
          			case 	IDM_FILE_OPEN:
                			// Show the File Open dialog box

               					ofn.Flags = 0 ;
     
               					if (!GetOpenFileName (&ofn))
                    							return 0 ;
               
                			// If there's an existing EMF, get rid of it.

               					if (hemf)
               					{
                    							DeleteEnhMetaFile (hemf) ;
                    							hemf = NULL ;
               					}
                    							// Load the EMF into memory

               				SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
               				ShowCursor (TRUE) ;

               				hemf = GetEnhMetaFile (szFileName) ;

               				ShowCursor (FALSE) ;
               				SetCursor (LoadCursor (NULL, IDC_ARROW)) ;

                    	// Invalidate the client area for later update

               				InvalidateRect (hwnd, NULL, TRUE) ;

               				if (hemf == NULL)
               				{
                    MessageBox (	hwnd, TEXT ("Cannot load metafile"), 
                                	szAppName, MB_ICONEXCLAMATION | MB_OK) ;
               				}
               				return 0 ;

          		case 	IDM_FILE_SAVE_AS:
               				if (!hemf)
                    						return 0 ;

                    						// Show the File Save dialog box

               				ofn.Flags = OFN_OVERWRITEPROMPT ;
     
               				if (!GetSaveFileName (&ofn))
                    						return 0 ;
               
                    						// Save the EMF to disk file

               				SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
               				ShowCursor (TRUE) ;

               				hemfCopy = CopyEnhMetaFile (hemf, szFileName) ;

               				ShowCursor (FALSE) ;
               				SetCursor (LoadCursor (NULL, IDC_ARROW)) ;
               				if (hemfCopy)
               				{
                    						DeleteEnhMetaFile (hemf) ;
                    						hemf = hemfCopy ;
               				}
               				else
                    MessageBox (	hwnd, TEXT ("Cannot save metafile"), 
                                	szAppName, MB_ICONEXCLAMATION | MB_OK) ;
               				return 0 ;

          		case 	IDM_FILE_PRINT:
                    		// Show the Print dialog box and get printer DC

               	printdlg.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION ;

               				if (!PrintDlg (&printdlg))
                    						return 0 ;
               
               				if (NULL == (hdcPrn = printdlg.hDC)) 
               				{
                   MessageBox (	hwnd, TEXT ("Cannot obtain printer DC"),
                                szAppName, MB_ICONEXCLAMATION | MB_OK) ;
                    						return 0 ;
               				}
                    						// Get size of printable area of page

               				rect.left   		= 0 ;
               				rect.right  		= GetDeviceCaps (hdcPrn, HORZRES) ;
               				rect.top    		= 0 ;
               				rect.bottom 		= GetDeviceCaps (hdcPrn, VERTRES) ;

               				bSuccess = FALSE ;

                    						// Play the EMF to the printer

               				SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
               				ShowCursor (TRUE) ;

               				if ((StartDoc (hdcPrn, &di) > 0) && (StartPage (hdcPrn) > 0))
				{
                    						PlayEnhMetaFile (hdcPrn, hemf, &rect) ;
                    
                    					if (EndPage (hdcPrn) > 0)
                    					{
                         							bSuccess = TRUE ;
                         							EndDoc (hdcPrn) ;
                    					}
               				}
               				ShowCursor (FALSE) ;
               				SetCursor (LoadCursor (NULL, IDC_ARROW)) ;

               				DeleteDC (hdcPrn) ;

               				if (!bSuccess)
                MessageBox (	hwnd, TEXT ("Could not print metafile"),
                                	  szAppName, MB_ICONEXCLAMATION | MB_OK) ;
               				return 0 ;

          		case 	IDM_FILE_PROPERTIES:
               				if (!hemf)
                    						return 0 ;

               				iLength = GetEnhMetaFileDescription (hemf, 0, NULL) ;
               				pBuffer = malloc ((iLength + 256) * sizeof (TCHAR)) ;

               				GetEnhMetaFileHeader (hemf, sizeof (ENHMETAHEADER), &header) ;

                    					// Format header file information 

               				i  = wsprintf (pBuffer, 
                              							TEXT ("Bounds = (%i, %i) to (%i, %i) pixels\n"),
                              							header.rclBounds.left, header.rclBounds.top,
                              							header.rclBounds.right, header.rclBounds.bottom) ;

               				i += wsprintf (pBuffer + i, 
                              							TEXT ("Frame = (%i, %i) to (%i, %i) mms\n"),
                              							header.rclFrame.left, header.rclFrame.top,
                              							header.rclFrame.right, header.rclFrame.bottom) ;

               				i += wsprintf (pBuffer + i,
                              							TEXT ("Resolution = (%i, %i) pixels")
                              							TEXT (" = (%i, %i) mms\n"),
                              							header.szlDevice.cx, header.szlDevice.cy,
                              							header.szlMillimeters.cx, 
                              							header.szlMillimeters.cy) ;

               				i += wsprintf (pBuffer + i,
                              							TEXT ("Size = %i, Records = %i, ")
                              							TEXT ("Handles = %i, Palette entries = %i\n"),
                              							header.nBytes, header.nRecords,
                              							header.nHandles, header.nPalEntries) ;
                    							// Include the metafile description, if present

               				if (iLength)
               				{
                    							i += wsprintf (pBuffer + i, TEXT ("Description = ")) ;
                    							GetEnhMetaFileDescription (hemf, iLength, pBuffer + i) ;
                    							pBuffer [lstrlen (pBuffer)] = '\t' ;
               				}

               				MessageBox (hwnd, pBuffer, TEXT ("Metafile Properties"), MB_OK) ;
               				free (pBuffer) ;                              
               				return 0 ;

          		case 	IDM_EDIT_COPY:
          		case 	IDM_EDIT_CUT:
               				if (!hemf)
                    						return 0 ;

                    						// Transfer metafile copy to the clipboard

               				hemfCopy = CopyEnhMetaFile (hemf, NULL) ;

               				OpenClipboard (hwnd) ;
               				EmptyClipboard () ;
               				SetClipboardData (CF_ENHMETAFILE, hemfCopy) ;
               				CloseClipboard () ;

               				if (LOWORD (wParam) == IDM_EDIT_COPY)
                    						return 0 ;
                                       		// fall through if IDM_EDIT_CUT 
          		case 	IDM_EDIT_DELETE:
               				if (hemf)
               				{
                    					DeleteEnhMetaFile (hemf) ;
                    					hemf = NULL ;
                    					InvalidateRect (hwnd, NULL, TRUE) ;
               				}
               				return 0 ;

  		case 	IDM_EDIT_PASTE:
               				OpenClipboard (hwnd) ;
               				hemfCopy = GetClipboardData (CF_ENHMETAFILE) ;

               				CloseClipboard () ;
               				if (hemfCopy && hemf)
               				{
                    					DeleteEnhMetaFile (hemf) ;
                    					hemf = NULL ;
               				}

               				hemf = CopyEnhMetaFile (hemfCopy, NULL) ;
               				InvalidateRect (hwnd, NULL, TRUE) ;
               				return 0 ;

		case	IDM_APP_ABOUT:
               				MessageBox (	hwnd, 	TEXT ("Enhanced Metafile Viewer\n")
                            TEXT ("(c) Charles Petzold, 1998"),
                           									szAppName, MB_OK) ;
               				return 0 ;

		case 	IDM_APP_EXIT:
               				SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
               				return 0 ;
          		}
        		break ;
         
     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;

          			if (hemf)
          			{
               				if (	hPalette = CreatePaletteFromMetaFile (hemf))
               				{
                    						SelectPalette (hdc, hPalette, FALSE) ;
                    						RealizePalette (hdc) ;
               				}
               				GetClientRect (hwnd, &rect) ;
               				PlayEnhMetaFile (hdc, hemf, &rect) ;

               				if (hPalette)
                    						DeleteObject (hPalette) ;
          			}
          			EndPaint (hwnd, &ps) ;
          			return 0 ;

     	case 	WM_QUERYNEWPALETTE:
          			if (!hemf || !(hPalette = CreatePaletteFromMetaFile (hemf)))
               					return FALSE ;

          			hdc = GetDC (hwnd) ;
          			SelectPalette (hdc, hPalette, FALSE) ;
          			RealizePalette (hdc) ;
          			InvalidateRect (hwnd, NULL, FALSE) ;
          
          			DeleteObject (hPalette) ;
          			ReleaseDC (hwnd, hdc) ;
          			return TRUE ;

     	case 	WM_PALETTECHANGED:
          			if ((HWND) wParam == hwnd)
               					break ;

          			if (!hemf || !(hPalette = CreatePaletteFromMetaFile (hemf)))
               					break ;

          			hdc = GetDC (hwnd) ;
          			SelectPalette (hdc, hPalette, FALSE) ;
          			RealizePalette (hdc) ;
          			UpdateColors (hdc) ;
          
          			DeleteObject (hPalette) ;
          			ReleaseDC (hwnd, hdc) ;
          			break ;
          
     	case 	WM_DESTROY:
          			if (hemf)
               					DeleteEnhMetaFile (hemf) ;

          			PostQuitMessage (0) ;
          			return 0 ;
     	}
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}
 EMFVIEW.RC ��ժ¼��
//Microsoft Developer Studio generated resource script.
#include "resource.h"
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
// Menu
EMFVIEW MENU DISCARDABLE 
BEGIN
    	POPUP "&File"
    	BEGIN
        MENUITEM "&Open\tCtrl+O",  IDM_FILE_OPEN
        MENUITEM "Save &As...",    IDM_FILE_SAVE_AS
		MENUITEM SEPARATOR
		MENUITEM "&Print...\tCtrl+P",IDM_FILE_PRINT
        MENUITEM SEPARATOR
		MENUITEM "&Properties",  	 IDM_FILE_PROPERTIES
		MENUITEM SEPARATOR
		MENUITEM "E&xit",  		 IDM_APP_EXIT
END
    	POPUP "&Edit"
    	BEGIN
        MENUITEM "Cu&t\tCtrl+X", 				IDM_EDIT_CUT
        MENUITEM "&Copy\tCtrl+C", 			IDM_EDIT_COPY
		MENUITEM "&Paste\tCtrl+V",    	 	IDM_EDIT_PASTE
        MENUITEM "&Delete\tDel",    	   		IDM_EDIT_DELETE
    	END
    	POPUP "Help"
    	BEGIN
        MENUITEM "&About EmfView...",  	 	IDM_APP_ABOUT
    	END
END

/////////////////////////////////////////////////////////////////////////////
// Accelerator
EMFVIEW ACCELERATORS DISCARDABLE 
BEGIN
"C",IDM_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
"O",IDM_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
"P",IDM_FILE_PRINT,VIRTKEY, CONTROL, NOINVERT
"V",IDM_EDIT_PASTE,VIRTKEY, CONTROL, NOINVERT
VK_DELETE,IDM_EDIT_DELETE,VIRTKEY, NOINVERT
"X",IDM_EDIT_CUT,VIRTKEY, CONTROL, NOINVERT
END
 RESOURCE.H ��ժ¼��
// Microsoft Developer Studio generated include file.
// Used by EmfView.rc

#define 		IDM_FILE_OPEN             40001
#define 		IDM_FILE_SAVE_AS          40002
#define 		IDM_FILE_PRINT            40003
#define 		IDM_FILE_PROPERTIES       40004
#define 		IDM_APP_EXIT              40005
#define 		IDM_EDIT_CUT              40006
#define 		IDM_EDIT_COPY             40007
#define 		IDM_EDIT_PASTE            40008
#define 		IDM_EDIT_DELETE           40009
#define 		IDM_APP_ABOUT             40010

EMFVIEWҲ֧Ԯ�����ĵ�ɫ�̴������Ա�֧Ԯ�е�ɫ�̱�����Ѷ��metafile����͸������Selectpalette�����У����ó�ʽ��CreatePaletteFromMetaFile��ʽ�д�����ɫ�̣��ڴ���WM_PAINT��ʾmetafile�Լ�����WM_QUERYNEWPALETTE��WM_PALETTECHANGEDѶϢʱ�����������ʽ��

�ڻ�Ӧ���ܱ��еġ�Print������ʱ��EMFVIEW��ʾ��ͨ��ӡ�����Ի����飬Ȼ��ȡ��ҳ���п���ӡ����Ĵ�С��Metafile�����ų��ʵ��ߴ���������������EMFVIEW���Ӵ��������Ʒ� ʽ��ʾmetafile��

��File�����ܱ��еġ�Properties����ʹEMFVIEW��ʾ����metafile��ͷ��Ѷ��ѶϢ���顣

�����ӡ����ǰ�潨����EMF2.EMFmetafileͼ�������ᷢ���ø߽����ȵ�ӡ������ӡ���������dz�ϸ������������������ľ�ݡ���ӡ����ͼ��ʱӦ��ʹ�ýϿ��Ļ��ʣ����磬һ�����������������ʾ��ֱ��ͼ������������ġ�

��ʾ��ȷ��metafileͼ��
��

Metafileͼ��ĺô�������ܹ��������С���Ų������ܱ���һ���ı���ȡ�������Ϊmetafileͨ����һϵ������ͼ�εĻ���ͼ����ɣ�����ͼ����ָ����������������Լ���������ȵȡ��������Сͼ��ֻ�Ǽ򵥵����Ŷ�����Щ����ͼ�ε���������㡣��һ���棬�Ե���ͼ��˵��ѹ��ͼ�����©�����е�ͼ�أ����ʧȥ��Ҫ����ʾ��Ѷ��

��Ȼ��metafile��ѹ��������������ȱ�ġ�������ʹ�õ�ͼ������豸��ͼ�ش�С�����޵ġ���metafileͼ��ѹ����һ����Сʱ�����metafile�Ĵ�����������ģ���İߵ㣬ͬʱ��������ͼ���ͻ�ɫ������Ҳ����֡����metafile�а���Ƕ��ĵ���ͼ��ɵĵ������壬ͬ�����������Ƶ����⡣

������ˣ�����������metafile������������š����ڰ�metafile�������鴦��������ӡˢ�ļ���ʱ�dz����á�һ����˵����������Ӧ�ó�ʽ��ѡ��metafileͼ��ʱ�������Χ��ͼ��ľ��Σ��������û����϶��þ��Σ���������Ϊ�����С��ͼ���͵�ӡ����ʱ����Ҳ����ͬ����Ӧ�Ĵ�С��

Ȼ������ʱ��������metafile�����Ǹ������⡣���磺��������һ�����������ͻ�ǩ������������ϵͳ����Щǩ����һϵ�����ߵķ�ʽ������metafile�С���metafile������߻�ʹǩ�����Σ����Ӧ�ñ���ͼ����ݺ��һ�¡�

��ǰ��ķ�����ʽ�У�������ʾ����Ĵ�С��ȷ��PlayEnhMetaFile����ʹ�õ�Χ�ƾ��η�Χ�����ԣ�����ı��ʽ�����Ĵ�С��Ҳ�͸ı���ͼ��Ĵ�С�����������鴦���ļ��иı�metafileͼ���С�ĸ������ơ�

��ȷ����ʾmetafileͼ�����ض��Ķ�����λ�����ʵ����ݺ�ȣ�����Ҫʹ��metafile��ͷ�еĴ�С��Ѷ�����ݴ���Ѷ�趨���νṹ��

�ڱ���ʣ�µķ�����ʽ�н�ʹ����ΪEMF.C�ij�ʽ�ܹ�����������ӡ�����ij�ʽ�롢��Դ������EMF.RC�ͱ�ͷ����RESOURCE.H����ʽ18-10��ʾ����Щ�����Լ�EMF8.C��ʽ���ó�ʽʹ����Щ������ʾһ��6Ӣ���ֱ�ߡ�

 ï¿½ï¿½Ê½18-10  EMF8
EMF8.C
/*---------------------------------------------------------------------------
   	EMF8.C -- Enhanced Metafile Demo #8
             					(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/

#include <windows.h>
TCHAR szClass 		[] = TEXT ("EMF8") ;
TCHAR szTitle 		[] = TEXT ("EMF8: Enhanced Metafile Demo #8") ;

void DrawRuler (HDC hdc, int cx, int cy)
{
     	int     			iAdj, i, iHeight ;
     	LOGFONT 		lf ;
     	TCHAR   			ch ;

     	iAdj = GetVersion () & 0x80000000 ? 0 : 1 ;
          				// Black pen with 1-point width
     	SelectObject (hdc, CreatePen (PS_SOLID, cx / 72 / 6, 0)) ;
          				// Rectangle surrounding entire pen (with adjustment)
     	Rectangle (hdc, iAdj, iAdj, cx + iAdj + 1, cy + iAdj + 1) ;
          				// Tick marks
     	for (i = 1 ; i < 96 ; i++)
     	{
				if (i % 16 == 0) iHeight = cy /  2 ;		// inches
		else 	if (i %  8 == 0) iHeight = cy /  3 ;    	// half inches
		else 	if (i %  4 == 0) iHeight = cy /  5 ;    	// quarter inches
		else 	if (i %  2 == 0) iHeight = cy /  8 ;    	// eighths
		else                  iHeight = cy / 12 ;    		// sixteenths

          		MoveToEx (hdc, i * cx / 96, cy, NULL) ;
          		LineTo   (hdc, i * cx / 96, cy - iHeight) ;
     	}
          				// Create logical font 
     	FillMemory (&lf, sizeof (lf), 0) ;
     	lf.lfHeight = cy / 2 ;
     	lstrcpy (lf.lfFaceName, TEXT ("Times New Roman")) ;

     	SelectObject 	(hdc, CreateFontIndirect (&lf)) ;
     	SetTextAlign 	(hdc, TA_BOTTOM | TA_CENTER) ;
     	SetBkMode 		(hdc, TRANSPARENT) ;

          				// Display numbers

     	for (i = 1 ; i <= 5 ; i++)
     	{
          			ch = (TCHAR) (i + '0') ;
          			TextOut (hdc, i * cx / 6, cy / 2, &ch, 1) ;
     	}
          				// Clean up
     	DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
     	DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN))) ;
}

void CreateRoutine (HWND hwnd)
{
     	HDC          				hdcEMF ;
     	HENHMETAFILE hemf ;
     	int          				cxMms, cyMms, cxPix, cyPix, xDpi, yDpi ;

     	hdcEMF = CreateEnhMetaFile (NULL, TEXT ("emf8.emf"), NULL,
                                 	TEXT ("EMF8\0EMF Demo #8\0")) ;
     	if (hdcEMF == NULL)
          			return ;
     	cxMms 		= GetDeviceCaps (hdcEMF, HORZSIZE) ;
     	cyMms 		= GetDeviceCaps (hdcEMF, VERTSIZE) ;
     	cxPix 		= GetDeviceCaps (hdcEMF, HORZRES) ;
     	cyPix 		= GetDeviceCaps (hdcEMF, VERTRES) ;

     	xDpi 		= cxPix * 254 / cxMms / 10 ;
     	yDpi		= cyPix * 254 / cyMms / 10 ;

     	DrawRuler (hdcEMF, 6 * xDpi, yDpi) ;
     	hemf = CloseEnhMetaFile (hdcEMF) ;
     	DeleteEnhMetaFile (hemf) ;
}

void PaintRoutine (HWND hwnd, HDC hdc, int cxArea, int cyArea)
{
     	ENHMETAHEADER 		emh ;
     	HENHMETAFILE  		hemf ;
     	int           					cxImage, cyImage ;
     	RECT          					rect ;

     	hemf = GetEnhMetaFile (TEXT ("emf8.emf")) ;
     	GetEnhMetaFileHeader (hemf, sizeof (emh), &emh) ;
     	cxImage = emh.rclBounds.right - emh.rclBounds.left ;
     	cyImage = emh.rclBounds.bottom - emh.rclBounds.top ;

     	rect.left   		= (cxArea - cxImage) / 2 ;
     	rect.right  		= (cxArea + cxImage) / 2 ;
     	rect.top    		= (cyArea - cyImage) / 2 ;
     	rect.bottom 		= (cyArea + cyImage) / 2 ;

     	PlayEnhMetaFile (hdc, hemf, &rect) ;
     	DeleteEnhMetaFile (hemf) ;
}
 EMF.C
/*----------------------------------------------------------------------------
   	EMF.C -- 	Enhanced Metafile Demonstration Shell Program
            					(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/

#include <windows.h>
#include <commdlg.h>
#include "..\\emf8\\resource.h"

extern void CreateRoutine (HWND) ;
extern void PaintRoutine  (HWND, HDC, int, int) ;

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
HANDLE hInst ;
extern TCHAR szClass [] ;
extern TCHAR szTitle [] ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    							PSTR szCmdLine, int iCmdShow)
{
     	TCHAR    				szResource [] = TEXT ("EMF") ;
     	HWND     				hwnd ;
     	MSG      				msg ;
     	WNDCLASS 			wndclass ;

     	hInst = hInstance ;
     	wndclass.style         			= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   			= WndProc ;
     	wndclass.cbClsExtra    			= 0 ;
     	wndclass.cbWndExtra    			= 0 ;
     	wndclass.hInstance     			= hInstance ;
     	wndclass.hIcon         			= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       			= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 		= GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  		= szResource ;
     	wndclass.lpszClassName 		= szClass ;
     
     	if (!RegisterClass (&wndclass))
     	{
          		MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                      							szClass, MB_ICONERROR) ;
          		return 0 ;
     	}
     
     	hwnd = CreateWindow (	szClass, szTitle,
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         NULL, NULL, hInstance, NULL) ;

     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;

     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
     	return msg.wParam ;
}

BOOL PrintRoutine (HWND hwnd)
{
     	static DOCINFO  		di ;
     	static PRINTDLG 		printdlg = { sizeof (PRINTDLG) } ;
     	static TCHAR    			szMessage [32] ;
     	BOOL            						bSuccess = FALSE ;
     	HDC             						hdcPrn ;
     	int             						cxPage, cyPage ;

     	printdlg.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION ;
     	if (!PrintDlg (&printdlg))
          			return TRUE ;
     	if (NULL == (hdcPrn = printdlg.hDC))
          			return FALSE ;
     	cxPage = GetDeviceCaps (hdcPrn, HORZRES) ;
     	cyPage = GetDeviceCaps (hdcPrn, VERTRES) ;

     	lstrcpy (szMessage, szClass) ;
     	lstrcat (szMessage, TEXT (": Printing")) ;

     	di.cbSize      			= sizeof (DOCINFO) ;
     	di.lpszDocName 		= szMessage ;

     	if (StartDoc (hdcPrn, &di) > 0)
	{
          		if (StartPage (hdcPrn) > 0)
          		{
               			PaintRoutine (hwnd, hdcPrn, cxPage, cyPage) ;
               			if (EndPage (hdcPrn) > 0)
               			{
                    					EndDoc (hdcPrn) ;
                    					bSuccess = TRUE ;
               			}
          		}
     	}
     	DeleteDC (hdcPrn) ;
     	return bSuccess ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
     	BOOL        				bSuccess ;
     	static int  		cxClient, cyClient ;
     	HDC         				hdc ;
     	PAINTSTRUCT 		ps ;
     
     	switch (message)
     	{
     	case 	WM_CREATE:
          			CreateRoutine (hwnd) ;
          			return 0 ;
          
     	case 	WM_COMMAND:
          			switch (wParam)
          			{
          			case 	IDM_PRINT:
               					SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
               					ShowCursor (TRUE) ;
               
               					bSuccess = PrintRoutine (hwnd) ;
               
               					ShowCursor (FALSE) ;
               					SetCursor (LoadCursor (NULL, IDC_ARROW)) ;
               
               					if (!bSuccess)
           MessageBox (hwnd, TEXT ("Error encountered during printing"),
                       szClass, MB_ICONASTERISK | MB_OK) ;
               		   return 0 ;
               
          			case 	IDM_EXIT:
               					SendMessage (hwnd, WM_CLOSE, 0, 0) ;
               					return 0 ;
               
          			case 	IDM_ABOUT:
           MessageBox (hwnd, TEXT ("Enhanced Metafile Demo Program\n")
                       TEXT ("Copyright (c) Charles Petzold, 1998"),
                       szClass, MB_ICONINFORMATION | MB_OK) ;
               		   return 0 ;
          			}
          			break ;
          
     	case 	WM_SIZE:
          			cxClient = LOWORD (lParam) ;
          			cyClient = HIWORD (lParam) ;
          			return 0 ;
          
	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;
          
          			PaintRoutine (hwnd, hdc, cxClient, cyClient) ;
          
          			EndPaint (hwnd, &ps) ;
          			return 0 ;
          
     	case 	WM_DESTROY :
          			PostQuitMessage (0) ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}
 EMF.RC ��ժ¼��
//Microsoft Developer Studio generated resource script.
#include "resource.h"
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
// Menu
EMF MENU DISCARDABLE 
BEGIN
    	POPUP "&File"
    	BEGIN
        			MENUITEM "&Print...", 					IDM_PRINT
       	 		MENUITEM SEPARATOR
        			MENUITEM "E&xit",     	      					IDM_EXIT
    	END
    	POPUP "&Help"
    	BEGIN
        			MENUITEM "&About...",  	 				IDM_ABOUT
    	END
END
 RESOURCE.H ��ժ¼��
// Microsoft Developer Studio generated include file.
// Used by Emf.rc
//
#define IDM_PRINT                40001
#define IDM_EXIT                 40002
#define IDM_ABOUT                40003

�ڴ���WM_CREATEѶϢ�����ڼ䣬EMF.C������ΪCreateRoutine���ⲿ��ʽ���ú�ʽ����metafile��EMF.C�������ط�����PaintRoutine��ʽ��һ����WM_PAINTѶϢ�����ڼ䣬��һ���ں�ʽPrintRoutine���Ի�Ӧ���ܱ�������ӡͼ��

��Ϊ�ִ���ӡ����ͨ������Ѷ��ʾ���и��ߵĽ����ȣ���ӡmetafile�������Dz������ض���С����ͼ����������Ҫ���ߡ���EMF8������metafileͼ�����ض���С��ʾʱ���������塣��ͼ����һ��6Ӣ�糤1Ӣ�����ֱ�ߣ�ÿӢ���Ϊʮ�������ִ�1��5ΪTrueType���塣

Ҫ����һ��6Ӣ���ֱ�ߣ���Ҫ֪��һЩ�豸�����ȵ�֪ʶ��EMF8.C�е�CreateRoutine��ʽ���Ƚ���metafile��Ȼ��ʹ�ô�CreateEnhMetaFile���ص�װ�����ݴ��ź���GetDeviceCaps�ĴΡ���Щ����ȡ�õ�λ�ֱ�Ϊ���׺�ͼ�ص���ʾƽ��ĸ߶�����ȡ�

���������е�֡�Metafileװ������ͨ������ΪGDI��������Ĵ���ý�飬����������Ѷ��ʾ����ӡ�����������豸����ô���Ŀ��Ⱥ͸߶ȴӺζ�����

�������Ѿ��������ˣ�CreateEnhMetaFile�ĵ�һ���������������ο�װ�����ݡ���GDI����Ϊmetafile�����豸���硣��������趨ΪNULL����EMF8�У���GDI�Ͱ���ʾ����Ϊ�ο�װ�����ݡ��������EMF8ʹ��װ�����ݺ���GetDeviceCapsʱ����ʵ����ȡ���й���ʾ������Ѷ��

EMF8.C��ͼ�ش�С���Ժ��״�С������25.4��1Ӣ��Ϊ25.4���ף�������ÿӢ��ĵ���Ϊ��λ�Ľ����ȡ�

��ʹ���Ƿdz��������metafileֱ�ߵ���ȷ��С�����������������������Dz����ġ�PlayEnhMetaFile��ʽ����ʾͼ��ʱ��ʹ����Ϊ����һ���������ݸ����ľ���������ͼ���С����˸þ��α����趨Ϊֱ�ߵĴ�С��

��춴�ԭ��EMF8�е�PaintRoutine��ʽ����GetEnhMetaFileHeader��ʽ��ȡ��metafile�ı�ͷ��Ѷ��ENHMETAHEADER�ṹ��rclBounds��λָ����ͼ��Ϊ��λ��metafileͼ���Χ�ƾ��Ρ���ʽʹ�ô���Ѷʹֱ��λ���ʾ�������룬��ͼ18-6��ʾ��


��

ͼ18-6 EMF8��өĻ��ʾ

��ס���������ֱ����өĻ�е�ֱ�߱Ƚ�ʱ�����߲���һ���dz��Ǻϡ���ͬ���������������ģ���ʾ��ֻ�ܽ��Ƶ�ʵ����ʾ�ߴ硣

��Ȼ���������������ˣ����ھ���������ӡͼ���ۣ��������һ̨300dpi������ӡ��������ô��ӡ����ֱ�ߵĿ�������11/3Ӣ�硣�����������������Ѷ��ʾ����ͼ�سߴ�����ӡ����Ȼ��������Ϊ���С�ߺܿɰ�������������������Ҫ�ġ�����������һ�ԡ�

ENHMETAHEADER�ṹ������������ͼ���С�ľ��νṹ����һ����rclBounds��EMF8ʹ�����������ͼ��Ϊ��λ����ͼ��Ĵ�С���ڶ�ΪrclFrame������0.01����Ϊ��λ����ͼ��Ĵ�С����������λ֮��Ĺ�ϵ�����������metafileʱʹ�õIJο�װ�����ݾ����ģ��ڴ������Ϊ��ʾ����metafile��ͷҲ����������ΪszlDevice��szlMillimeters����λ��������SIZEL�ṹ���ֱ���ͼ�ص�λ�ͺ��׵�λָ���˲ο��豸�Ĵ�С�������GetDeviceCaps�õ�����Ѷһ������

EMF9ʹ��ͼ��ĺ��״�С��Ѷ�����ʽ18-11��ʾ��

 ï¿½ï¿½Ê½18-11  EMF9
EMF9.C
/*---------------------------------------------------------------------------
   	EMF9.C -- Enhanced Metafile Demo #9
             					(c) Charles Petzold, 1998
----------------------------------------------------------------------------*/

#include <windows.h>
#include <string.h>

TCHAR szClass 		[] = TEXT ("EMF9") ;
TCHAR szTitle 		[] = TEXT ("EMF9: Enhanced Metafile Demo #9") ;

void CreateRoutine (HWND hwnd)
{
}

void PaintRoutine (HWND hwnd, HDC hdc, int cxArea, int cyArea)
{
     	ENHMETAHEADER 		emh ;
     	HENHMETAFILE  		hemf ;
     	int           					cxMms, cyMms, cxPix, cyPix, cxImage, cyImage ;
     	RECT          					rect ;

     	cxMms 		= GetDeviceCaps (hdc, HORZSIZE) ;
     	cyMms 		= GetDeviceCaps (hdc, VERTSIZE) ;
     	cxPix 		= GetDeviceCaps (hdc, HORZRES) ;
     	cyPix 		= GetDeviceCaps (hdc, VERTRES) ;

     	hemf = GetEnhMetaFile (TEXT ("..\\emf8\\emf8.emf")) ;
     	GetEnhMetaFileHeader (hemf, sizeof (emh), &emh) ;
     	cxImage 			= emh.rclFrame.right - emh.rclFrame.left ;
     	cyImage 			= emh.rclFrame.bottom - emh.rclFrame.top ;

     	cxImage 			= cxImage * cxPix / cxMms / 100 ;
     	cyImage 			= cyImage * cyPix / cyMms / 100 ;

     	rect.left   		= (cxArea - cxImage) / 2 ;
     	rect.right  		= (cxArea + cxImage) / 2 ;
     	rect.top    		= (cyArea - cyImage) / 2 ;
     	rect.bottom 		= (cyArea + cyImage) / 2 ;

     	PlayEnhMetaFile (hdc, hemf, &rect) ;
     	DeleteEnhMetaFile (hemf) ;
}

EMF9ʹ��EMF8������metafile�����ȷ��ִ��EMF8��

EMF9�е�PaintRoutine��ʽ����ʹ��Ŀ��װ�����ݺ���GetDeviceCaps�ĴΡ�����EMF8�е�CreateRoutine��ʽһ������Щ�����ṩ�й��豸�����ȵ���Ѷ���ڵõ�metafile����֮�ᣬ��ȡ�ñ�ͷ�ṹ��ʹ��rclFrame��λ��������0.01����Ϊ��λ��metafileͼ���С�����ǵ�һ����

Ȼ�ᣬ��ʽͨ����������豸��ͼ�ش�С�����Ժ��״�С�ٳ���100����Ϊ�����ߴ���0.01����Ϊ��λ�����˴�Сת��Ϊͼ�ش�С�����ڣ�PaintRoutine��ʽ������ͼ��Ϊ��λ��ֱ�ߴ�С������ʾ���޹ء������ʺ�Ŀ���豸��ͼ�ش�С�����Һ�����ʹͼ����ж��롣

����ʾ�����ԣ�EMF9����ʾ��EMF8��ʾ��һ�������������EMF9��ӡֱ�ߣ����ῴ����������ֱ�ߣ�6Ӣ�糤��1Ӣ�����

���ű������ݺ��
��

��Ҳ������Ҫʹ��EMF8������ֱ��metafile����������ʾ6Ӣ���ͼ�񡣱���ͼ����ȷ��6��1���ݺ������Ҫ�ġ���ǰ�����������鴦����ʽ����Ӧ�ó�ʽ��ʹ��Χ�Ʒ������ı�metafile�Ĵ�С�Ǻܷ���ģ����������ᵼ��ij�̶ֳȵ�ʧ�档������Ӧ�ó�ʽ�У�Ӧ�ø�ʹ����һ��ѡ��������ԭ�ȵ��ݺ�ȣ������ù�Χ�Ʒ���Ĵ�С��α仯�������˵�����ݸ�PlayEnhMetaFile�ľ��νṹ����ֱ����ʹ����ѡ���Χ�Ʒ����塣���ݸ��ú�ʽ�ľ��νṹֻ��Χ�Ʒ����һ���֡�

�����ǿ�һ����ʽ18-12 EMF10��������ġ�

 ï¿½ï¿½Ê½18-12  EMF10
EMF10.C
/*--------------------------------------------------------------------------
   	EMF10.C -- 	Enhanced Metafile Demo #10
              					(c) Charles Petzold, 1998
---------------------------------------------------------------------------*/

#include <windows.h>
TCHAR szClass 		[] = TEXT ("EMF10") ;
TCHAR szTitle 		[] = TEXT ("EMF10: Enhanced Metafile Demo #10") ;
void CreateRoutine (HWND hwnd)
{
}

void PaintRoutine (HWND hwnd, HDC hdc, int cxArea, int cyArea)
{
     	ENHMETAHEADER 		emh ;
     	float         					fScale ;
     	HENHMETAFILE  		hemf ;
     	int           					cxMms, cyMms, cxPix, cyPix, cxImage, cyImage ;
     	RECT          					rect ;

     	cxMms 		= GetDeviceCaps (hdc, HORZSIZE) ;
     	cyMms 		= GetDeviceCaps (hdc, VERTSIZE) ;
     	cxPix 		= GetDeviceCaps (hdc, HORZRES) ;
     	cyPix 		= GetDeviceCaps (hdc, VERTRES) ;

     	hemf 	= GetEnhMetaFile (TEXT ("..\\emf8\\emf8.emf")) ;

     	GetEnhMetaFileHeader (hemf, sizeof (emh), &emh) ;

     	cxImage 	= emh.rclFrame.right - emh.rclFrame.left ;
     	cyImage 	= emh.rclFrame.bottom - emh.rclFrame.top ;

     	cxImage 	= cxImage * cxPix / cxMms / 100 ;
     	cyImage 	= cyImage * cyPix / cyMms / 100 ;

     	fScale 	= min ((float) cxArea / cxImage, (float) cyArea / cyImage) ;

     	cxImage 			= (int) (fScale * cxImage) ;
     	cyImage 			= (int) (fScale * cyImage) ;

     	rect.left   		= (cxArea - cxImage) / 2 ;
     	rect.right		= (cxArea + cxImage) / 2 ;
     	rect.top    			= (cyArea - cyImage) / 2 ;
     	rect.bottom = (cyArea + cyImage) / 2 ;
     	PlayEnhMetaFile (hdc, hemf, &rect) ;
     	DeleteEnhMetaFile (hemf) ;
}

EMF10��չֱ��ͼ������Ӧ��ʾ���򣨻���ӡҳ��Ŀ���ӡ���֣���������ʧ�档ͨ��ֱ�߻���չ����ʾ������������ȣ����ǻ����¾��ж��롣��������Ӵ�����̫С����ֱ�߻�����ʾ����һ��ߣ����ǻ�ˮƽ���ж��롣

�����������ַ�����������ʵ���ʾ���Σ���������ֻ����EMF9�ķ�ʽ��ɸ������EMF10.C�е�PaintRoutine��ʽ��ʼ������EMF9.C��ͬ��ΪĿ��װ�����ݼ���6Ӣ�糤��ֱ��ͼ���ʵ���ͼ�ش�С��

Ȼ�ᣬ��ʽ������ΪfScale�ĸ���ֵ��������ʾ���������ͼ����ȵı�ֵ�Լ���ʾ����߶���ͼ��߶ȱ�ֵ���ߵ���Сֵ����������ڼ���Χ�ƾ���ǰ�������ͼ���ͼ�ش�С��

metafile�е�ӳ�䷽ʽ
��

ǰ����Ƶ�ֱ�ߵ�λ��Ӣ�磬Ҳ�к��ס����ֹ���ʹ��GDI�ṩ�ĸ���ӳ�䷽ʽ�ƺ��dz��ʺϡ������Ҽ��ʹ��ͼ�أ������ֹ���������б�Ҫ�ļ��㡣Ϊʲô�أ�

�𰸺ܼ򵥣����ǽ�ӳ�䷽ʽ��metafileһ��ʹ�û�ʮ�ֻ��ҡ����Dz���ʵ��һ�¡�

��ʹ��metafileװ�����ݺ���SetMapModeʱ���ú�ʽ��metafile��������GDI��ʽһ�������롣���ʽ18-13 EMF11��ʾ��������

 ï¿½ï¿½Ê½18-13  EMF11
EMF11.C
/*---------------------------------------------------------------------------
   	EMF11.C -- Enhanced Metafile Demo #11
              						(c) Charles Petzold, 1998
  ------------------------------------------------------------------------*/

#include <windows.h>
TCHAR szClass 		[] = TEXT ("EMF11") ;
TCHAR szTitle 		[] = TEXT ("EMF11: Enhanced Metafile Demo #11") ;

void DrawRuler (HDC hdc, int cx, int cy)
{
     	int     			i, iHeight ;
     	LOGFONT 		lf ;
     	TCHAR   			ch ;

          			// Black pen with 1-point width

     	SelectObject (hdc, CreatePen (PS_SOLID, cx / 72 / 6, 0)) ;
          			// Rectangle surrounding entire pen (with adjustment)
     	if (GetVersion () & 0x80000000) 	`			// Windows 98
  			Rectangle (hdc, 0, -2, cx + 2, cy) ;
     	else   
// Windows NT
          			Rectangle (hdc, 0, -1, cx + 1, cy) ;

          			// Tick marks
          
     	for (i = 1 ; i < 96 ; i++)
     	{
         if	(i %16== 0)	iHeight = cy /	2 	;  	// inches
         else if(i % 8	== 0)iHeight = cy /	3 ;	// half inches
         else if(i % 4	== 0)iHeight = cy /	5 ;	// quarter inches
         else if(i % 2	== 0)iHeight = cy /	8 ;	// eighths
         else iHeight = cy /12	;	// sixteenths

		MoveToEx (hdc, i * cx / 96, 0, NULL) ;
          		LineTo   (hdc, i * cx / 96, iHeight) ;
     	}
          		// Create logical font 
     	FillMemory (&lf, sizeof (lf), 0) ;
     	lf.lfHeight = cy / 2 ;
     	lstrcpy (lf.lfFaceName, TEXT ("Times New Roman")) ;

     	SelectObject 	(hdc, CreateFontIndirect (&lf)) ;
     	SetTextAlign 	(hdc, TA_BOTTOM | TA_CENTER) ;
     	SetBkMode    		(hdc, TRANSPARENT) ;

          		// Display numbers

     	for (i = 1 ; i <= 5 ; i++)
     	{
          		ch = (TCHAR) (i + '0') ;
          		TextOut (hdc, i * cx / 6, cy / 2, &ch, 1) ;
     	}
          		// Clean up
     	DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
  	    DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN))) ;
}

void CreateRoutine (HWND hwnd)
{
     	HDC          	hdcEMF ;
     	HENHMETAFILE 	hemf ;
     
	hdcEMF = CreateEnhMetaFile (NULL, TEXT ("emf11.emf"), NULL,
                                 	  TEXT ("EMF11\0EMF Demo #11\0")) ;
     	SetMapMode (hdcEMF, MM_LOENGLISH) ;
     	DrawRuler (hdcEMF, 600, 100) ;
     	hemf = CloseEnhMetaFile (hdcEMF) ;
     	DeleteEnhMetaFile (hemf) ;
}

void PaintRoutine (HWND hwnd, HDC hdc, int cxArea, int cyArea)
{
     	ENHMETAHEADER 		emh ;
     	HENHMETAFILE  		hemf ;
     	int           		cxMms, cyMms, cxPix, cyPix, cxImage, cyImage ;
     	RECT          		rect ;
     
     	cxMms 		= GetDeviceCaps (hdc, HORZSIZE) ;
     	cyMms 		= GetDeviceCaps (hdc, VERTSIZE) ;
     	cxPix 		= GetDeviceCaps (hdc, HORZRES) ;
     	cyPix 		= GetDeviceCaps (hdc, VERTRES) ;
     
     	hemf = GetEnhMetaFile (TEXT ("emf11.emf")) ;
     	GetEnhMetaFileHeader (hemf, sizeof (emh), &emh) ;
     	cxImage 	= emh.rclFrame.right - emh.rclFrame.left ;
     	cyImage 	= emh.rclFrame.bottom - emh.rclFrame.top ;
     
     	cxImage 	= cxImage * cxPix / cxMms / 100 ;
     	cyImage 	= cyImage * cyPix / cyMms / 100 ;
     
     	rect.left   		= (cxArea - cxImage) / 2 ;
     	rect.top    		= (cyArea - cyImage) / 2 ;
     	rect.right  		= (cxArea + cxImage) / 2 ;
     	rect.bottom 		= (cyArea + cyImage) / 2 ;
     
     	PlayEnhMetaFile (hdc, hemf, &rect) ;
     	DeleteEnhMetaFile (hemf) ;
}

EMF11�е�CreateRoutine��ʽ��EMF8�������ֱ��metafile��ʽ���е��Ǹ��򵥣���Ϊ������Ҫ����GetDeviceCaps��ȷ����ÿӢ�����Ϊ��λ����ʾ�������ȡ��෴��EMF11����SetMapMode��ӳ�䷽ʽ�趨ΪMM_LOENGLISH�����߼���λ���0.01Ӣ�硣�����ֱ�ߵĴ�СΪ600��100����λ��������Щ��ֵ���ݸ�DrawRuler��

����MoveToEx��LineTo���л���ֱ�ߵĿ̶��⣬EMF11�е�DrawRuler��ʽ��EMF9�е�һ��������ͼ�ص�λ����ʱ���ڶ���MM_TEXTӳ�䷽ʽ������ֱ���ϵĵ�λ����өĻ�������������MM_LOENGLISHӳ�䷽ʽ���Լ���������ӳ�䷽ʽ���������������������Ҫ�޸ij�ʽ�롣ͬʱ��Ҳ��Ҫ����Rectangle��ʽ�еĵ���������

EMF11�е�PaintRoutine��ʽ��������EMF9�е���ͬ���Ǹ��汾�ij�ʽ������ʾ����ӡ����������ȷ�ߴ���ʾֱ�ߡ�Ψһ��֮ͬ�����EMF11ʹ��EMF11.EMF��������EMF9ʹ��EMF8������EMF8.EMF������

EMF11��ʾ��ͼ���������EMF9����ʾ����ͬ����ˣ���������Կ�����SetMapMode����Ƕ��metafile�ܹ���metafile�Ľ��������Ҳ�Ӱ��������ȷ��С��ʾmetafile�Ļ��ơ�

ӳ������ʾ
��

��EMF11�м���Ŀ�ľ��ΰ�����GetDeviceCaps�ļ������С����ǵĵڶ���Ŀ����ʹ��ӳ�䷽ʽ������Щ���С�GDI��Ŀ�ľ��ε�������Ϊ�߼����ꡣΪ��Щ����ʹ��MM_HIMETRIC�ƺ��Ǹ��÷�������Ϊ��ʹ��0.01������Ϊ�߼���λ������ǿ��metafile��ͷ�����Χ�ƾ��εĵ�λ��ͬ��

��ʽ18-14����ʾ��EMF12��ʽ��������EMF8��ʹ�õ�DrawRuler������ʽ������ʹ��MM_HIMETRICӳ�䷽ʽ��ʾmetafile��

 ï¿½ï¿½Ê½18-14  EMF12
EMF12.C
/*---------------------------------------------------------------------------
   	EMF12.C -- 	Enhanced Metafile Demo #12
              					(c) Charles Petzold, 1998
---------------------------------------------------------------------------*/

#include <windows.h>
TCHAR szClass 		[] = TEXT ("EMF12") ;
TCHAR szTitle 		[] = TEXT ("EMF12: Enhanced Metafile Demo #12") ;
void DrawRuler (HDC hdc, int cx, int cy)
{
     	int     			iAdj, i, iHeight ;
     	LOGFONT 		lf ;
     	TCHAR   			ch ;

     	iAdj = GetVersion () & 0x80000000 ? 0 : 1 ;
          			// Black pen with 1-point width
     	SelectObject (hdc, CreatePen (PS_SOLID, cx / 72 / 6, 0)) ;
          			// Rectangle surrounding entire pen (with adjustment)
     	Rectangle (hdc, iAdj, iAdj, cx + iAdj + 1, cy + iAdj + 1) ;
          			// Tick marks
     	for (i = 1 ; i < 96 ; i++)
     	{
         if (i % 16 == 0) 	iHeight = cy /  2 ;    		// inches
         else if (i %  8 == 0) 	iHeight = cy /  3 ;    	// half inches
         else if (i %  4 == 0) 	iHeight = cy /  5 ;    	// quarter inches
         else if (i %  2 == 0) 	iHeight = cy /  8 ;    	// eighths
         else iHeight = cy / 12 ;    	// sixteenths

          		MoveToEx (hdc, i * cx / 96, cy, NULL) ;
          		LineTo   (hdc, i * cx / 96, cy - iHeight) ;
     	}
          			// Create logical font 
     	FillMemory (&lf, sizeof (lf), 0) ;
     	lf.lfHeight = cy / 2 ;
     	lstrcpy (lf.lfFaceName, TEXT ("Times New Roman")) ;

     	SelectObject (hdc, CreateFontIndirect (&lf)) ;
     	SetTextAlign (hdc, TA_BOTTOM | TA_CENTER) ;
     	SetBkMode    (hdc, TRANSPARENT) ;

          			// Display numbers

     	for (i = 1 ; i <= 5 ; i++)
     {
          		ch = (TCHAR) (i + '0') ;
          		TextOut (hdc, i * cx / 6, cy / 2, &ch, 1) ;
	}
          		// Clean up
     	DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
     	DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN))) ;
}

void CreateRoutine (HWND hwnd)
{
     	HDC          				hdcEMF ;
     	HENHMETAFILE 	hemf ;
     	int          				cxMms, cyMms, cxPix, cyPix, xDpi, yDpi ;
     
     	hdcEMF = CreateEnhMetaFile (NULL, TEXT ("emf12.emf"), NULL,
                                 	TEXT ("EMF13\0EMF Demo #12\0")) ;
     
     	cxMms = GetDeviceCaps (hdcEMF, HORZSIZE) ;
     	cyMms = GetDeviceCaps (hdcEMF, VERTSIZE) ;
     	cxPix = GetDeviceCaps (hdcEMF, HORZRES) ;
     	cyPix = GetDeviceCaps (hdcEMF, VERTRES) ;
     
     	xDpi = cxPix * 254 / cxMms / 10 ;
     	yDpi = cyPix * 254 / cyMms / 10 ;
     
     	DrawRuler (hdcEMF, 6 * xDpi, yDpi) ;
     	hemf = CloseEnhMetaFile (hdcEMF) ;
     	DeleteEnhMetaFile (hemf) ;
}

void PaintRoutine (HWND hwnd, HDC hdc, int cxArea, int cyArea)
{
     	ENHMETAHEADER 		emh ;
     	HENHMETAFILE  		hemf ;
     	POINT         					pt ;
     	int           					cxImage, cyImage ;
     	RECT          					rect ;
     
     	SetMapMode (hdc, MM_HIMETRIC) ;
     	SetViewportOrgEx (hdc, 0, cyArea, NULL) ;
     	pt.x = cxArea ;
     	pt.y = 0 ;
     
     	DPtoLP (hdc, &pt, 1) ;
     	hemf = GetEnhMetaFile (TEXT ("emf12.emf")) ;
     	GetEnhMetaFileHeader (hemf, sizeof (emh), &emh) ;
     	cxImage 	= emh.rclFrame.right - emh.rclFrame.left ;
     	cyImage 	= emh.rclFrame.bottom - emh.rclFrame.top ;
     
     	rect.left   		= (pt.x - cxImage) / 2 ;
     	rect.top    		= (pt.y + cyImage) / 2 ;
     	rect.right  		= (pt.x + cxImage) / 2 ;
     	rect.bottom 		= (pt.y - cyImage) / 2 ;
     
     	PlayEnhMetaFile (hdc, hemf, &rect) ;
     	DeleteEnhMetaFile (hemf) ;
}

EMF12�е�PaintRoutine��ʽ���Ƚ�ӳ�䷽ʽ�趨ΪMM_HIMETRIC������������ӳ�䷽ʽһ����yֵ����өĻ����������Ȼ����ԭ����������өĻ�����Ͻǣ������ζ��ʾ�����ڵ�y����ֵ�Ǹ�����Ϊ�˾���������⣬��ʽ����SetViewportOrgEx��ԭ�������趨�����½ǡ�

װ������(cxArea,0)λ�өĻ�����Ͻǡ��Ѹ�����㴫�ݸ�DPtoLP����װ������㵽�߼�����㡹����ʽ���õ���0.01����Ϊ��λ����ʾ�����С��

Ȼ�ᣬ��ʽ����metafile��ȡ�õ�����ͷ�����ҵ���0.01����Ϊ��λ��metafile��С����������Ŀ�ľ�������ʾ������ж����λ�þͱ��ʮ�ּ򵥡�

�������ǿ������ڽ���metafileʱ�ܹ�ʹ��ӳ�䷽ʽ����ʾ��ʱҲ��ʹ��ӳ�䷽ʽ��������һ�����������

���ʽ18-15 EMF13չʾ�����������ǿ��Եġ�

 ï¿½ï¿½Ê½18-15  EMF13
EMF13.C
/*---------------------------------------------------------------------------
   	EMF13.C --	Enhanced Metafile Demo #13
              					(c) Charles Petzold, 1998
----------------------------------------------------------------------------*/

#include <windows.h>
TCHAR szClass 		[] = TEXT ("EMF13") ;
TCHAR szTitle 		[] = TEXT ("EMF13: Enhanced Metafile Demo #13") ;

void CreateRoutine (HWND hwnd)
{
}

void PaintRoutine (HWND hwnd, HDC hdc, int cxArea, int cyArea)
{
     	ENHMETAHEADER 		emh ;
     	HENHMETAFILE  		hemf ;
     	POINT         					pt ;
     	int           					cxImage, cyImage ;
     	RECT          					rect ;
     
     	SetMapMode (hdc, MM_HIMETRIC) ;
     	SetViewportOrgEx (hdc, 0, cyArea, NULL) ;
     	pt.x 	= cxArea ;
     	pt.y 	= 0 ;
     
     	DPtoLP (hdc, &pt, 1) ;
     
     	hemf = GetEnhMetaFile (TEXT ("..\\emf11\\emf11.emf")) ;
     
     	GetEnhMetaFileHeader (hemf, sizeof (emh), &emh) ;
     
     	cxImage 	= emh.rclFrame.right - emh.rclFrame.left ;
     	cyImage 	= emh.rclFrame.bottom - emh.rclFrame.top ;
     
     	rect.left   		= (pt.x - cxImage) / 2 ;
     	rect.top    		= (pt.y + cyImage) / 2 ;
     	rect.right  		= (pt.x + cxImage) / 2 ;
     	rect.bottom 		= (pt.y - cyImage) / 2 ;
     
     	PlayEnhMetaFile (hdc, hemf, &rect) ;
     	DeleteEnhMetaFile (hemf) ;
}

��EMF13�У����ֱ��metafile����EMF11������������û��ʹ��ӳ�䷽ʽ����metafile��EMF13ֻ�Ǽ򵥵�����metafile��Ȼ����EMF11һ��ʹ��ӳ�䷽ʽ����Ŀ�ľ��Ρ�

���ڣ����ǿ��Խ���һЩ�����ڽ���metafileʱ��GDIʹ�ö�ӳ�䷽ʽ������Ƕ���޸ģ���������ͼ�غͺ���Ϊ��λ��metafileͼ��Ĵ�С��ͼ��Ĵ�С������metafile��ͷ�ڡ�����ʾmetafileʱ��GDI�ں���PlayEnhMetaFileʱ������Ч��ӳ�䷽ʽ����Ŀ�ľ��ε�ʵ��λ�ã���������metafile�в�û���κμ�¼ȥ�������λ�á�