GdiPlus使用方法

GDI是Graphics Device Interface的缩写,含义是图形设备接口,它的主要任务是负责系统与绘图程序之间的信息交换,处理所有Windows程序的图形输出。

在Windows操作系统下,绝大多数具备图形界面的应用程序都离不开GDI,我们利用GDI所提供的众多函数就可以方便的在屏幕、打印机及其它输出设备上输出图形,文本等操作。GDI的出现使程序员无需要关心硬件设备及设备驱动,就可以将应用程序的输出转化为硬件设备上的输出,实现了程序开发者与硬件设备的隔离,大大方便了开发工作。

GDI+是Windows XP中的一个子系统,它主要负责在显示屏幕和打印设备输出有关信息,它是一组通过C++类实现的应用程序编程接口。顾名思义,GDI+是以前版本GDI的继承者,出于兼容性考虑,Windows XP仍然支持以前版本的GDI,但是在开发新应用程序的时候,开发人员为了满足图形输出需要应该使用GDI+,因为GDI+对以前的Windows版本中GDI进行了优化,并添加了许多新的功能。

作为图形设备接口的GDI+使得应用程序开发人员在输出屏幕和打印机信息的时候无需考虑具体显示设备的细节,他们只需调用GDI+库输出的类的一些方法即可完成图形操作,真正的绘图工作由这些方法交给特定的设备驱动程序来完成,GDI+使得图形硬件和应用程序相互隔离.从而使开发人员编写设备无关的应用程序变得非常容易。


GdiPlus使用方法:

开发工具:VS2008

1.新建对话框应用程序


2.拷贝 GdiPlus_Includes文件夹、Lib文件、gdiplus.dll文件 到应用程序中

GdiPlus使用方法_第1张图片

3.在StdAfx.h文件中添加如下代码

//GDI+
#define UNICODE
#ifndef ULONG_PTR
#define ULONG_PTR unsigned long*
#endif
//#include "c:\gdi+\includes\gdiplus.h"   ////请修改为你的头文件路径
//using namespace Gdiplus;  
//#pragma comment(lib, "c:\\gdi+\\lib\\gdiplus.lib") ////请修改为你的.lib文件路径
#include "../GdiPlus_Includes\\gdiplus.h"
using namespace Gdiplus;
#pragma comment(lib, "../GdiPlus_Lib\\gdiplus.lib")

4.在C**App.cpp文件的InitInstance()函数中

在C**Dlg dlg之前,添加如下代码:
	GdiplusStartupInput gdiplusStartupInput;
	ULONG_PTR           gdiplusToken;
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

在dlg后,return前,添加如下代码:
	//关闭gdiplus的环境
	GdiplusShutdown(gdiplusToken);

如:
BOOL CGdiPlusDemoApp::InitInstance()
{
	// 如果一个运行在 Windows XP 上的应用程序清单指定要
	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
	//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	// 将它设置为包括所有要在应用程序中使用的
	// 公共控件类。
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);

	CWinApp::InitInstance();

	AfxEnableControlContainer();

	// 标准初始化
	// 如果未使用这些功能并希望减小
	// 最终可执行文件的大小,则应移除下列
	// 不需要的特定初始化例程
	// 更改用于存储设置的注册表项
	// TODO: 应适当修改该字符串,
	// 例如修改为公司或组织名
	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));

	GdiplusStartupInput gdiplusStartupInput;
	ULONG_PTR           gdiplusToken;
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

	CGdiPlusDemoDlg dlg;
	m_pMainWnd = &dlg;
	INT_PTR nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
		// TODO: 在此放置处理何时用
		//  “确定”来关闭对话框的代码
	}
	else if (nResponse == IDCANCEL)
	{
		// TODO: 在此放置处理何时用
		//  “取消”来关闭对话框的代码
	}

	//关闭gdiplus的环境
	GdiplusShutdown(gdiplusToken);

	// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
	//  而不是启动应用程序的消息泵。
	return FALSE;
}


5.C**Dlg操作

OnInitDialog:设置对话框位置和大小,获取资源信息
OnPaint:画图

头文件
private:
	Image *m_pImageBackground;
	int m_nBackgroundWidth, m_nBackgroundHeight;

	Image *m_pImagePic;
	int m_nPicWidth, m_nPicHeight;

private:
	void MyInitDialog();
	void InitUi();//设置界面初始化信息
	void GetImageSource();//获取图片信息

	void MyPaint();
	void DrawBackground(HDC hDC);//绘制背景
	void DrawPic(HDC hDC);//绘制图片

	//获取图片信息
	BOOL ImageFromIDResource(UINT nID, LPCTSTR sTR, Image *&pImg);
	BOOL ImageFromIDResource(CString sFilePathName, Image *&pImg);

源文件
void CGdiPlusDemoDlg::MyInitDialog()
{
	InitUi();
	GetImageSource();
}

void CGdiPlusDemoDlg::MyPaint()
{
	CPaintDC dc(this); 

	CRect rcClient;
	GetClientRect(&rcClient);

	CDC dcMem;
	CBitmap bmpMem;
	dcMem.CreateCompatibleDC(&dc);
	if(bmpMem.CreateCompatibleBitmap(&dc,rcClient.Width(),rcClient.Height()))
	{
		CBitmap* pOldBmp = dcMem.SelectObject(&bmpMem);
		CWnd::DefWindowProc(WM_PAINT,(WPARAM)dcMem.m_hDC,0);

		DrawBackground(dcMem.m_hDC);
		DrawPic(dcMem.m_hDC);

		dc.BitBlt(0,0,rcClient.right,rcClient.bottom,&dcMem,0,0,SRCCOPY);
		dcMem.SelectObject(pOldBmp);
		bmpMem.DeleteObject();
	}
	dcMem.DeleteDC();
}

void CGdiPlusDemoDlg::InitUi()
{
	//对话框背景图片宽和高
	const int nBkBmpWidth  = 800;
	const int nBkBmpHeight = 450;
	//获得电脑显示器的像素宽度和像素高度
	int ax = GetDC()->GetDeviceCaps(HORZRES) - nBkBmpWidth; 
	int ay = GetDC()->GetDeviceCaps(VERTRES) - nBkBmpHeight;

	int nWidth = 0;   
	int nHeight = 0;	
	if(ax <= 0)
	{		ax =0;	}
	else
	{		ax = ax/2;	}
	if(ay <=0 )
	{		ay =0;	}
	else
	{		ay = ay/2;	}

	RECT clientRect;
	clientRect.left = ax;
	clientRect.top = ay;
	clientRect.right = clientRect.left + nBkBmpWidth;
	clientRect.bottom = clientRect.top + nBkBmpHeight;
	MoveWindow(&clientRect);
}

void CGdiPlusDemoDlg::GetImageSource()
{
	ImageFromIDResource(IDB_PNG_BG,_T("PNG"),m_pImageBackground);
	m_nBackgroundWidth  = m_pImageBackground->GetWidth();
	m_nBackgroundHeight = m_pImageBackground->GetHeight();

	CString sPath = _T("res\\hd.png");
	ImageFromIDResource(sPath,m_pImagePic);
	//ImageFromIDResource(IDB_PNG_HD,_T("PNG"),m_pImagePic);
	m_nPicWidth  = m_pImagePic->GetWidth();
	m_nPicHeight = m_pImagePic->GetHeight();
}

void CGdiPlusDemoDlg::DrawBackground(HDC hDC)
{
	RECT rct;
	GetWindowRect(&rct);
	POINT ptWinPos={rct.left,rct.top};
	Graphics graph(hDC);

	Point points[] = { Point(0, 0), 
		Point(m_nBackgroundWidth, 0), 
		Point(0, m_nBackgroundHeight),
	};
	graph.DrawImage(m_pImageBackground, points, 3);
	graph.ReleaseHDC(hDC);
}

void CGdiPlusDemoDlg::DrawPic(HDC hDC)
{
	RECT rct;
	GetWindowRect(&rct);
	POINT ptWinPos={rct.left,rct.top};
	Graphics graph(hDC);

	int nHorOffset = 50;
	int nVerOffset = 50;

	Point points[] = { Point(nHorOffset, nVerOffset), 
		Point(nHorOffset+m_nPicWidth, nVerOffset), 
		Point(nHorOffset, nVerOffset+m_nPicHeight),
	};
	graph.DrawImage(m_pImagePic, points, 3);
	graph.ReleaseHDC(hDC);
}

BOOL CGdiPlusDemoDlg::ImageFromIDResource(UINT nID, LPCTSTR sTR, Image *&pImg)
{
	HINSTANCE hInst = AfxGetResourceHandle();
	HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type
	if (!hRsrc)
		return FALSE;

	// load resource into memory
	DWORD len = SizeofResource(hInst, hRsrc);
	BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
	if (!lpRsrc)
		return FALSE;

	// Allocate global memory on which to create stream
	HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
	BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
	memcpy(pmem,lpRsrc,len);
	IStream* pstm;
	CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);

	// load from stream
	pImg=Gdiplus::Image::FromStream(pstm);

	// free/release stuff
	GlobalUnlock(m_hMem);
	pstm->Release();
	FreeResource(lpRsrc);

	return TRUE;
}

BOOL CGdiPlusDemoDlg::ImageFromIDResource(CString sFilePathName, Image *&pImg)
{
	// load file into memory
	DWORD len = 0;
	HANDLE hFile;
	DWORD  size1,readbyte;
	hFile=CreateFile(sFilePathName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
	if(INVALID_HANDLE_VALUE == hFile)
	{
		return FALSE;
	}
	len=GetFileSize(hFile,&size1);
	if(0xFFFFFFFF == len)
	{
		CloseHandle(hFile);
		return FALSE;
	}

	// Allocate global memory on which to create stream
	HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
	BYTE* pmem = (BYTE*)GlobalLock(m_hMem);

	ReadFile(hFile,pmem,len,&readbyte,NULL);
	IStream* pstm;
	CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);

	// load from stream
	pImg=Gdiplus::Image::FromStream(pstm);

	// free/release stuff
	GlobalUnlock(m_hMem);
	pstm->Release();

	return TRUE;
}

工程
GdiPlus使用方法_第2张图片  GdiPlus使用方法_第3张图片  GdiPlus使用方法_第4张图片

运行效果
GdiPlus使用方法_第5张图片


源码下载


你可能感兴趣的:(C/C++程序开发)