VC6使用GdiPlus绘制png图片

                                          效果图


1 配置Gdiplus

    (1)下载GDI+ for VC6.0 SDK 文件,下载地址  http://pan.baidu.com/s/1pKFEGC7  
   
    (2)新建一个VC6的工程(win32 application).选择典型的hello world.

    (3)把压缩包内“复制里面的内容到VC6工程目录下”文件夹内的内容复制到工程目录下.

    (4)打开自动生成的cpp文件.

    (5)在cpp最前面添加代码:(引用头文件和库,使用GdiPlus命名空间)
#pragma comment(linker, "/subsystem:windows")
#include<windows.h>
#define ULONG_PTR unsigned long
#include "gdiplus/GdiPlus.h"
#pragma comment(lib, "GdiPlus.lib")
using namespace Gdiplus;

    (6)添加两个全局变量(Global Variables),一个是要显示的png,一个是背景图(在上面的下载地址里有这两个图片)
      Image *g_png1;
      Image *g_back1;



    (7)找到WinMain函数,在MyRegisterClass(hInstance);后面添加三行.用于GdiPlus的初始化.
	GdiplusStartupInput gdiplusstartupinput;
	ULONG_PTR gdiplustoken;
	GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);
    (8)在WinMain函数的return之前添加一行,用于关闭程序时GdiPlus的资源回收.
        GdiplusShutdown(gdiplustoken);

2 修改WM_PAINT消息的处理

    (1)找到WndProc函数,在开头的声明部分添加:
	//使用双缓冲防止屏幕闪烁
	HDC hdc_buffer;//缓冲的DC
	HBITMAP m_hSurface;//缓冲的位图


    (2)找到WndProc函数,在switch (message) 的case WM_PAINT:下添加以下代码:
	hdc = BeginPaint(hWnd, &ps);//开始绘图
	hdc_buffer = CreateCompatibleDC(NULL);//创建一个空的DC
	m_hSurface = CreateCompatibleBitmap(hdc, WINDOWS_WIDTH, WINDOWS_HEIGHT);//创建一个与屏幕大小相同的空图片,宽和高可以自己设置
	SelectObject(hdc_buffer, m_hSurface);//选择对象
	OnPaint(hdc_buffer);//这个OnPAINT是自己写的函数
	BitBlt(hdc, 0, 0, 1024, 768, hdc_buffer, 0, 0, SRCCOPY);
	EndPaint(hWnd, &ps);//结束绘画
	DeleteObject(m_hSurface);//释放内存
	DeleteObject(hdc_buffer);//释放内存
	InvalidateRect(hWnd, NULL, FALSE);//重绘所有区域 这样一结束绘图就又会收到系统的WM_PAINT消息 所以一直在重绘
	break;

    (3)添加自己的OnPaint函数
//  FUNCTION:  OnPaint(HDC hdc)
//
//	CREATED BY YOURSELF
//
//	PURPOSE:Paint on the hdc
//
void OnPaint(HDC hdc){
	static double i2;//0-15计数用的 图片中一共有16个子图片
	static double dPos;
	Graphics graphics(hdc);
	graphics.DrawImage(g_back1,0, 0, 0, 0, 800, 600, UnitPixel);//画背景
	graphics.DrawImage(g_png1,(int)dPos, 200, ((int)i2 % 4) * 32, 2 * 32, 32, 32, UnitPixel);//画png
	//参数为 Image* image,INT x,INT y,INT srcx,INT srcy,INT srcwidth,INT srcheight,Unit srcUnit)

	i2=i2+0.04;
	if (i2>15)i2=0;
	dPos+=0.35 ;
	if (dPos > WINDOWS_WIDTH) dPos =0;
}

    (4)编译-运行就OK啦~







附:完整代码(在VC6可直接编译运行(需要配置好环境))


// win32.cpp : Defines the entry point for the application.
//

#define IDI_WIN32	            107
#define IDI_SMALL				108
#define IDC_WIN32	            109

#pragma comment(linker, "/subsystem:windows")
#include <string>
#include <stdlib.h>
#include<windows.h>


#define ULONG_PTR unsigned long
#include "gdiplus/GdiPlus.h"


#pragma comment(lib, "GdiPlus.lib")

using namespace Gdiplus;


#define MAX_LOADSTRING 100
#define WINDOWS_WIDTH 400
#define WINDOWS_HEIGHT 300


//ULONG_PTR        m_gdiplusToken;

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];								// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];								// The title bar text

Image *g_png1;
Image *g_back1;

// Foward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
//LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM);



int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{

	MSG msg;

	MyRegisterClass(hInstance);
	//	Initialize GdiPlus
	GdiplusStartupInput gdiplusstartupinput;
	ULONG_PTR gdiplustoken;
	GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}

	//hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WIN32);

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0)) 
	{
		//if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
	//	{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
	//	}

	}
	GdiplusShutdown(gdiplustoken);

	return msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage is only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			=   LoadIcon(hInstance, (LPCTSTR)IDI_WIN32);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW);//Grey Color
	wcex.lpszMenuName	=(LPCSTR)IDC_WIN32;
	wcex.lpszClassName	= "WIN32";
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HANDLE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;


   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow("WIN32", "win32", WS_OVERLAPPEDWINDOW,
      400, 300, WINDOWS_WIDTH, WINDOWS_HEIGHT, NULL, NULL, hInstance, NULL);


   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNCTION:  OnPaint(HDC hdc)
//
//	CREATED BY YOURSELF
//
//	PURPOSE:Paint on the hdc
//
void OnPaint(HDC hdc){
	static double i2;//0-15计数用的 图片中一共有16个子图片
	static double dPos;
	Graphics graphics(hdc);
	graphics.DrawImage(g_back1,0, 0, 0, 0, 800, 600, UnitPixel);//画背景
	graphics.DrawImage(g_png1,(int)dPos, 200, ((int)i2 % 4) * 32, 2 * 32, 32, 32, UnitPixel);//画png
	//Image* image,INT x,INT y,INT srcx,INT srcy,INT srcwidth,INT srcheight,Unit srcUnit)

	i2=i2+0.04;
	if (i2>15)i2=0;
	dPos+=0.35 ;
	if (dPos > WINDOWS_WIDTH) dPos =0;
}


//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;


	PAINTSTRUCT ps;
	HDC hdc;
	
	//使用双缓冲防止屏幕闪烁
	HDC hdc_buffer;//缓冲的DC
	HBITMAP m_hSurface;//缓冲的位图

//	LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

	switch (message) 
	{
		case WM_CREATE:
			g_png1 = new Image(L"1.png", FALSE);//载入png
			g_back1 = new Image(L"back.png", FALSE);//载入背景
			break;
			
		case WM_COMMAND:
			
			wmId    = LOWORD(wParam); 
			wmEvent = HIWORD(wParam); 

			switch (wmId){
			case 1:
			default:
			   return DefWindowProc(hWnd, message, wParam, lParam);
			}
			break;
		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);//开始绘图
			// TODO: Add any drawing code here...


			hdc_buffer = CreateCompatibleDC(NULL);//创建一个空的DC
			m_hSurface = CreateCompatibleBitmap(hdc, WINDOWS_WIDTH, WINDOWS_HEIGHT);//创建一个与屏幕大小相同的空图片
			SelectObject(hdc_buffer, m_hSurface);//选择对象
			
			OnPaint(hdc_buffer);//这个OnPAINT是自己写的函数
			BitBlt(hdc, 0, 0, 1024, 768, hdc_buffer, 0, 0, SRCCOPY);

			EndPaint(hWnd, &ps);//结束绘画

			DeleteObject(m_hSurface);//释放内存
			DeleteObject(hdc_buffer);//释放内存

			InvalidateRect(hWnd, NULL, FALSE);//重绘所有区域 这样一结束绘图就又会收到系统的WM_PAINT消息 所以一直在重绘

			
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_INITDIALOG:
				return TRUE;

		case WM_COMMAND:
			if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
			{
				EndDialog(hDlg, LOWORD(wParam));
				return TRUE;
			}
			break;
	}
    return FALSE;
}




Visual C++6.0使用GDI+的一般方法 1. 载解压GDI+开发包; 2. 正确设置include & lib 目录; 3. stdafx.h 添加: #ifndef ULONG_PTR #define ULONG_PTR unsigned long* #endif #include 4. 程序中添加GDI+的包含文件gdiplus.h以及附加的类库gdiplus.lib。 通常gdiplus.h包含文件添加在应用程序的stdafx.h文件中,而gdiplus.lib可用两种进行添加: 第一种是直接在stdafx.h文件中添加下列语句: #pragma comment( lib, "gdiplus.lib" ) 另一种方法是: 在VC.net中添加库文件在:项目菜单->属性->链接器->输入 举个例子: (1)在应用程序项目的应用类中,添加一个成员变量,如下列代码: ULONG_PTR m_gdiplusToken; 其中,ULONG_PTR是一个DWORD数据类型,该成员变量用来保存GDI+被初始化后在应用程序中的GDI+标识,以便能在应用程序退出后,引用该标识来调用Gdiplus:: GdiplusShutdown来关闭GDI+。 (2)在应用类中添加ExitInstance的重载,并添加下列代码用来关闭GDI+: int CGDITestApp::ExitInstance() { Gdiplus::GdiplusShutdown(m_gdiplusToken); return CWinApp::ExitInstance(); } (3)在应用类的InitInstance函数中添加GDI+的初始化代码: 注意:下面这些GDI+的初始化代码必须放在m_pMainWnd->UpdateWindow();之前。 CWinApp::InitInstance(); Gdiplus::GdiplusStartupInput gdiplusStartupInput; Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL); (4)在需要绘图的窗口或视图类中添加GDI+绘制代码。 下面分别就单文档和基于对话框应用程序为例,说明使用GDI+的一般过程和方法。 1. 在单文档应用程序中使用GDI+ 在上面的过程中,我们就是以一个单文档应用程序Ex_GDIPlus作为示例的。下面列出第4步所涉及的代码: void CGDITestView::OnDraw(CDC* pDC) { CGDITestDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here usingnamespace Gdiplus; Graphics graphics(pDC->m_hDC); Pen newPen(Color(255,0,0),3); HatchBrush newBrush(HatchStyleCross,Color(255,0,255,0),Color(255,0,0,255));//创建一个填充画刷,前景色为绿色,背景色为蓝色 graphics.DrawRectangle(&newPen,50,50,100,60);// 在(50,50)处绘制一个长为100,高为60的矩形 graphics.FillRectangle(&newBrush,50,50,100,60); // 在(50,50)处填充一个长为100,高为60的矩形区域 } 编译并运行,结果如图:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值