emfmain.cpp

来自「Windows 图形编程 书籍」· C++ 代码 · 共 756 行 · 第 1/2 页

CPP
756
字号
//-----------------------------------------------------------------------------------//
//              Windows Graphics Programming: Win32 GDI and DirectDraw               //
//                             ISBN  0-13-086985-6                                   //
//                                                                                   //
//  Written            by  Yuan, Feng                             www.fengyuan.com   //
//  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
//  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
//                                                                                   //
//  FileName   : emfmain.cpp					                                     //
//  Description: EMF demo program, Chapter 16				                         //
//  Version    : 1.00.000, May 31, 2000                                              //
//-----------------------------------------------------------------------------------//

#define STRICT
#define _WIN32_WINNT 0x0500
#define NOCRYPT

#pragma pack(push, 4)
#include <windows.h>
#pragma pack(pop)

#include <assert.h>
#include <tchar.h>
#include <math.h>

#include "..\..\include\wingraph.h"
#include "..\..\include\ListView.h"
#include "..\..\include\MVC.h"
#include "..\..\include\GDIObject.h"
#include "..\..\include\pen.h"
#include "..\..\include\filedialog.h"
#include "..\..\include\treeview.h"
#include "..\..\include\emf.h"
#include "..\..\include\fonttext.h"
#include "..\..\include\axis.h"

#include "resource.h"
#include "EMFView.h"

//////////////////////////////////////////////////////////////

class KEMFResourceDialog : public KDialog
{
	HENHMETAFILE hEmf;

    virtual BOOL DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
    	switch (uMsg)
	    {
		    case WM_INITDIALOG:
				{
					hEmf = LoadEMF((HMODULE) GetWindowLong(hWnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDR_EMF1));

					SendDlgItemMessage(hWnd, IDC_EMF, STM_SETIMAGE, IMAGE_ENHMETAFILE,
						(LPARAM) hEmf);

					return TRUE;
				}

			case WM_NCDESTROY:
				if ( hEmf )
					DeleteEnhMetaFile(hEmf);
				return TRUE;

		    case WM_COMMAND:
				if ( LOWORD(wParam)==IDOK )
					EndDialog(hWnd, IDOK);
				return TRUE;
	    }

	    return FALSE;
    }
};


void Demo_EMFResource(HINSTANCE hInst)
{
	KEMFResourceDialog dlg;

	dlg.Dialogbox(hInst, MAKEINTRESOURCE(IDD_EMFRES));
}

//////////////////////////////////////////////////////////////

void SampleDraw(HDC hDC, int x, int y)
{
	Ellipse(hDC, x+25, y+25, x+75, y+75);

	SetTextAlign(hDC, TA_CENTER | TA_BASELINE);

	const TCHAR * mess = "Default Font";
	TextOut(hDC, x+50, y+50, "Default Font", _tcslen(mess));
}


void Demo_Scale(HDC hDC)
{
	HENHMETAFILE hSample1;
	HENHMETAFILE hSample2;
	
	{
		HDC hDCEMF = CreateEnhMetaFile(hDC, NULL, NULL, NULL);
		SampleDraw(hDCEMF, 0, 0);
		hSample1 = CloseEnhMetaFile(hDCEMF);


		RECT rect = { 0, 0, 100, 100 };
		Map10um(hDC, rect);
		hDCEMF = CreateEnhMetaFile(hDC, NULL, & rect, NULL);
		SampleDraw(hDCEMF, 0, 0);
		hSample2 = CloseEnhMetaFile(hDCEMF);
	}

	HBRUSH yellow = CreateSolidBrush(RGB(0xFF, 0xFF, 0));

	// test EMF without proper frame rectangle
	{
		RECT rect = { 10, 10, 10+100, 10+100 }; 
		
		FillRect(hDC, & rect, yellow);
		SampleDraw(hDC, 10, 10); // original
	}

	for (int test=0, x=120; test<3; test++)
	{
		RECT rect = { x, 10, x+(test/2+1)*100, 10+((test+1)/2+1)*100 };
	
		FillRect(hDC, & rect, yellow);
		PlayEnhMetaFile(hDC, hSample1, & rect);

		x = rect.right + 10;
	}

	// test EMF with proper frame rectangle
	{
		RECT rect = { 10, 220, 10+100, 220+100 };
		
		FillRect(hDC, & rect, yellow); // original
		SampleDraw(hDC, 10, 220);
	}

	for (test=0, x=120; test<3; test++)
	{
		RECT rect = { x, 220, x+(test/2+1)*100, 220+((test+1)/2+1)*100 };
	
		FillRect(hDC, & rect, yellow);
		PlayEnhMetaFile(hDC, hSample2, & rect);

		x = rect.right + 10;
	}

	DeleteObject(yellow);

	DeleteEnhMetaFile(hSample1);
	DeleteEnhMetaFile(hSample2);
}


////////////////////////////////////


void Demo_LineCurveArea(HDC hDC)
{
	{
		int x= 300, y = 50;

		MoveToEx(hDC, x,    y,   NULL); LineTo(hDC, x +50, y);
		MoveToEx(hDC, x+50, y+1, NULL); LineTo(hDC, x+100, y+1);

		Rectangle(hDC, x,    y+10, x +50, y+60);
		Rectangle(hDC, x+50, y+30, x+100, y+80);

		Ellipse(hDC, x+110, y+10, x+160, y+100);
		Ellipse(hDC, x+160, y+10, x+210, y+100);

		PatBlt(hDC, x,     y+100, 100, 100, BLACKNESS);
		PatBlt(hDC, x+100, y+110, 100, 100, PATINVERT);

		RECT rect = { x, y+ 250, x+100, y+350 };
		FillRect(hDC, & rect, GetSysColorBrush(COLOR_3DSHADOW));

		OffsetRect(& rect, 120, 0);
		FrameRect(hDC, & rect, GetSysColorBrush(COLOR_ACTIVECAPTION));

		OffsetRect(& rect, 120, 0);
		InvertRect(hDC, & rect);
	}

	KPen Red (PS_DOT, 0, RGB(0xFF, 0, 0));
	KPen Blue(PS_SOLID, 3, RGB(0, 0, 0xFF));

	for (int z=0; z<=160; z+=40)
	{
		int x = 10, y = 200;

		POINT p[4] = { x, y, x+ 40, y-z, x+80, y-z, x+120, y }; x+= 136;
		POINT q[4] = { x, y, x+ 40, y-z, x+80, y+z, x+120, y }; 
		
		Red.Select(hDC);
		Polyline(hDC, p, 4);
		Polyline(hDC, q, 4);
		Red.UnSelect();

		Blue.Select(hDC);
		PolyBezier(hDC, p, 4);
		PolyBezier(hDC, q, 4);
		Blue.UnSelect();
	} 
}


////////////////////////////////

const BITMAPINFO * LoadDIB(HMODULE hModule, LPCTSTR pBitmapName)
{
	HRSRC   hRes = FindResource(hModule, pBitmapName, RT_BITMAP);

	if ( hRes==NULL )
		return NULL;

	HGLOBAL hGlb = LoadResource(hModule, hRes);

	if ( hGlb==NULL )
		return NULL;

	return (const BITMAPINFO *) LockResource(hGlb);
}

int GetDIBColorCount(const BITMAPINFOHEADER & bmih)
{
	if ( bmih.biBitCount <= 8 )
		if ( bmih.biClrUsed )
			return bmih.biClrUsed;
		else
			return 1 << bmih.biBitCount;
	else if ( bmih.biCompression==BI_BITFIELDS )
		return 3 + bmih.biClrUsed;
	else
		return bmih.biClrUsed;
}


void DispResBitmap(HDC hDC, int x, int y, int resid, int & width, int & height)
{
	const BITMAPINFO * pBMI = LoadDIB(
		(HINSTANCE) GetWindowLong(WindowFromDC(hDC), GWL_HINSTANCE), 
		MAKEINTRESOURCE(resid));
	
	width  = pBMI->bmiHeader.biWidth;
	height = abs(pBMI->bmiHeader.biHeight);

	const BYTE * pBits = (const BYTE *) & pBMI->bmiColors[GetDIBColorCount(pBMI->bmiHeader)];

	StretchDIBits(hDC, x, y, width, height, 
		0, 0, width, height, pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
}


void Demo_Bitmaps(HDC hDC)
{
	const BITMAPINFO * pBMI = LoadDIB(
		(HINSTANCE) GetWindowLong(WindowFromDC(hDC), GWL_HINSTANCE), 
		MAKEINTRESOURCE(IDB_PANDA));

	// load as DIB
	const BYTE * pBits = (const BYTE *) & pBMI->bmiColors[GetDIBColorCount(pBMI->bmiHeader)];
	
	int width  = pBMI->bmiHeader.biWidth;
	int height = abs(pBMI->bmiHeader.biHeight);

	int x = 10;
	int y = 10;

	// full DIB, duplication: is GDI smart enough to merge: NO
	{
		StretchDIBits(hDC, x, y, width, height, 0, 0, width, height, 
			pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
		y += height + 10;

		StretchDIBits(hDC, x, y, width, height, 0, 0, width, height, 
			pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
		y += height + 10;
	}

	x += width + 10;
	y  = 10;

	// 1/2 DIB: is GDI smart enough to split: YES
	{
		StretchDIBits(hDC, x, y, width, height/2, 0, height/2, width, height/2, 
			pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
		y += height/2 + 1;

		StretchDIBits(hDC, x, y, width, height/2, 0, 0, width, height/2, 
			pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
		y += height/2 + 9;
	}

	// 1/4 DIB: is GDI smart enough to split: NO

	{
		StretchDIBits(hDC, x, y, width/2, height/2, 
			0, height/2, width/2, height/2, pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);

		y += height/2 + 1;

		StretchDIBits(hDC, x, y, width/2, height/2, 
			0, 0, width/2, height/2, pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);

		y -= height/2 + 1;

		x += width/2 + 1;

		
		StretchDIBits(hDC, x, y, width/2, height/2, 
			width/2, height/2, width/2, height/2, pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);

		y += height/2 + 1;

		StretchDIBits(hDC, x, y, width/2, height/2, 
			width/2, 0, width/2, height/2, pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);

		y -= height/2 + 1;

		x += width/2 + 1;

	}
}


void Comment(HDC hDC, const char * mess)
{
	GdiComment(hDC, _tcslen(mess), (const BYTE *) mess);
}


int LineSpace(HDC hDC)
{
	TEXTMETRIC tm;

	GetTextMetrics(hDC, & tm);

	return tm.tmHeight + tm.tmExternalLeading;
}


void Demo_Texts(HDC hDC)
{
	KLogFont lf(-PointSizetoLogical(hDC, 15), "Times New Roman");
	KGDIObject font(hDC, lf.CreateFont());

	KGDIObject yellowbrush(hDC, CreateSolidBrush(RGB(0xFF, 0xFF, 0))); 

	const TCHAR * mess1 = "Quick\t Brown\t Fox\t Jumps\t Over\t a\t Lazy\t Dog.";

	int x = 10, y = 10;

	SetTextAlign(hDC, TA_LEFT | TA_TOP);

	Comment(hDC, "->TextOut");
	TextOut(hDC, x, y, mess1, _tcslen(mess1));
	Comment(hDC, "<-TextOut");

	y += LineSpace(hDC) + 10;

	Comment(hDC, "ExtTextOut");

	ExtTextOut(hDC, x, y, 0, NULL, mess1, _tcslen(mess1), NULL);
	y += LineSpace(hDC) + 10;

	int tab[1] = { 50 };

	Comment(hDC, "->TabbedTextOut");
	TabbedTextOut(hDC, x, y, mess1, _tcslen(mess1), 1, tab, x);
	Comment(hDC, "<-TabbedTextOut");

	y += LineSpace(hDC) + 10;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?