GdiplusFlat(1)GDI+平面API:用GDI的思想进行GDI+编程

本文由CSDN用户zuishikonghuan所作,转载请注明出处:http://blog.csdn.net/zuishikonghuan/article/details/46982559

坚信GdiplusFlat比Gdiplus好!我要在资料匮乏的GdiplusFlat上打下一片天地!没有api文档?我去百度找,就算把那些其他不支持GDI+类的语言中用GdiplusFlat的例子翻出来看,头文件里函数和结构没有声明?我自己声明!实在不行?我把你们这些GdiplusFlat函数一个个从dll里load进来直接动态调用!!

GDI+(Gdiplus)想必大家都不陌生,MSDN给出的解释是

Windows GDI+ is a class-based API for C/C++ programmers. It enables applications to use graphics and formatted text on both the video display and the printer. Applications based on the Microsoft Win32 API do not access graphics hardware directly. Instead, GDI+ interacts with device drivers on behalf of applications. GDI+ is also supported by Microsoft Win64.

其实,这个GDI+是对GDI的进一步封装,GDI是Windows的图形设备接口,是以Win32API的形式提供的,完全是按照面向过程的思想使用的,而GDI+不一样,GDI+一开始就是提供的面向对象的编程方式,即提供的是GDI+类!在一个偶然的机会下,我知道了GDI+类的实现是调用的gdiplus.dll中的API,也就是说,GDI+是有API版本的,那么这个API版本,就是GdiplusFlat(GDI+平面API)!

这是微软的解释:

Windows GDI+ exposes a flat API that consists of about 600 functions, which are implemented in Gdiplus.dll and declared in Gdiplusflat.h. The functions in the GDI+ flat API are wrapped by a collection of about 40 C++ classes. It is recommended that you do not directly call the functions in the flat API. Whenever you make calls to GDI+, you should do so by calling the methods and functions provided by the C++ wrappers. Microsoft Product Support Services will not provide support for code that calls the flat API directly.

注意:如果使用GDI+平面API,微软不提供产品支持!!甚至这些平面API都没有文档化!!MSDN只是给了声明和简单说明

但这么做的意义无疑是巨大的,那就是GDI的思想进行GDI+编程,不知道其他人怎么想,反正我学了GDI后不愿意使用GDI+的模式编程,同时GDI+明显偏向MFC,对于用惯了C++的Win32SDK编程的我,实在是不敢恭维。而GDI+平面API,也就是GdiplusFlat,他无疑回归了Win32的怀抱,而且GDI+类是对GDI+平面API的抽象和封装无疑用GDI+类的程序效率不及GDI+平面API
下面,看看如何使用GdiplusFlat编程GDI+平面API

第一步:创建一个Win32工程,进入stdafx.h,删除一下代码
#define WIN32_LEAN_AND_MEAN             //  从 Windows 头文件中排除极少使用的信息

如果愿意也可以把这个删除:
#include "targetver.h"

将工程主文件中的所有内容删除,改为:
#include "stdafx.h"
#include <Windows.h>//windows头文件
#include <gdiplus.h>//GDI+头文件
#include <gdiplusflat.h>//GDI+Flat头文件
#pragma comment(lib,"gdiplus.lib")//这个非常重要
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
	_In_opt_ HINSTANCE hPrevInstance,
	_In_ LPTSTR    lpCmdLine,
	_In_ int       nCmdShow)
{

}

为什么说这个#pragma comment(lib,"gdiplus.lib")非常重要呢?因为我们是调用GDI+的API,不bird那什么难用的GDI+类,但是那些函数就算自己声明了,编译时会出错,至于说原因,愿意研究的可以看看我写的这篇文章 http://blog.csdn.net/zuishikonghuan/article/details/46375803中介绍的简单编译原理知识(红字)

然后开启GDI+
想必大家都知道应该用Gdiplus命名空间里的GdiplusStartupInput,但是那是GDI+用的,不是GDI+Flat用的!!
我们自己定义一个GdiplusStartupInput!用C和Win32的最基本的数据类型!不鸟那GDI+类!!
typedef struct _GdiplusStartupInput{
	unsigned int GdiplusVersion;
	unsigned int DebugEventCallback;
	BOOL SuppressBackgroundThread;
	BOOL SuppressExternalCodecs;
}GdiplusStartupInput;

然后就是调用GdiplusStartup,还是没有!好, 我们自己声明出来,只要gdiplus.dll中有的API, 因为连接了gdiplus.lib,就不信不能用!!
extern "C" int WINAPI GdiplusStartup(int* token,GdiplusStartupInput *input,int *output);

 注意三点:
1。调用约定WINAPI不能少,至于说为什么,32位Win32API都是标准调用!不加标准调用编译出来的符号不一样没法和gdiplus.lib连接,同时就算动态调用dll里的API不加标准调用会出现堆栈错误。
2。不要用那些GDI+类的东西!只用C和Win32的最基本的数据类型!
3。extern "C"不能少,不然C++不采用标准函数符号修饰约定。

然后就可以用了
int token;
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
	_In_opt_ HINSTANCE hPrevInstance,
	_In_ LPTSTR    lpCmdLine,
	_In_ int       nCmdShow)
{
	GdiplusStartupInput StartupInput;
	StartupInput.GdiplusVersion = 1;
	GdiplusStartup(&token, &StartupInput,NULL);
}

然后就是关闭了, 一样,我们自己声明
extern "C" void WINAPI GdiplusShutdown(int token);
完整代码:
#include "stdafx.h"
#include <Windows.h>
#include <gdiplus.h>
#include <gdiplusflat.h>
#pragma comment(lib,"gdiplus.lib")//very important

typedef struct _GdiplusStartupInput{
	unsigned int GdiplusVersion;
	unsigned int DebugEventCallback;
	BOOL SuppressBackgroundThread;
	BOOL SuppressExternalCodecs;
}GdiplusStartupInput;

extern "C" int WINAPI GdiplusStartup(int* token,GdiplusStartupInput *input,int *output);
extern "C" void WINAPI GdiplusShutdown(int token);

int token;
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
	_In_opt_ HINSTANCE hPrevInstance,
	_In_ LPTSTR    lpCmdLine,
	_In_ int       nCmdShow)
{
	//GDI+开启
	GdiplusStartupInput StartupInput = {0};
	StartupInput.GdiplusVersion = 1;
	GdiplusStartup(&token, &StartupInput,NULL);
	//在这里尽情地GDI+Flat编程吧
	//GDI+关闭
	GdiplusShutdown(token);//可以把这个写在消息循环后面,程序退出就销毁,或者在不需要GDI+时调用,比如GDI+窗口的WM_DESTROY消息里调用
}

下面我会逐步讲GDI+Flat编程!相信比GDI+更棒!!



你可能感兴趣的:(windows,Win32,GDI+,gdiplus)