当前位置:C++技术网 > 精选软件 > 一句代码搞定GDI+的环境初始化和环境释放

一句代码搞定GDI+的环境初始化和环境释放

更新时间:2016-06-30 21:55:53浏览次数:1+次

    最近要改进MFC下的direct ui框架,需要用GDI+来实现基础的画图工作,替换GDI,目的是GDI+经过了良好的封装,基础的一些工作都做的比较不错,可以快速做出满意的效果。
    在文章《GDI+初次使用完全介绍和踩坑跳坑说明》中,这是介绍了初次使用GDI+会遇到的很多问题,并都详细做了解释。说句实话,虽然GDI+功能强大,但是每次想到使用GDI+的时候,脑子里总是浮现要添加头文件,导入lib之类的。想想就有点退却。比较老的版本的VS还没有自带GDI+库,所以更是头痛。那么对于没有自带GDI+库的问题,你用VS2008以及以上版本的VS,都是有的,所以这不是问题了。而使用GDI+的准备工作和清理工作,难免让人还是有点不舒服。如果每次写代码都要写这些代码,是有点不爽的。
    所以,我决定用一个简单的类包装下。那么以后,只要在程序中创建一个静态的对象,然后就不用管环境了。
    GDI+环境包装类的代码如下:
//头文件GDIPlusUse.h:
#pragma once
#include <Windows.h>
#include <gdiplus.h>
#pragma comment(lib,"gdiplus.lib")
using namespace Gdiplus;
class CGDIPlusUse
{
public:
    CGDIPlusUse();
    ~CGDIPlusUse();

    ULONG_PTR m_gdiplusToken;//当做句柄来理解
};

//源文件GDIPlusUse.cpp:
#include "stdafx.h"
#include "GDIPlusUse.h"
CGDIPlusUse::CGDIPlusUse()
{
    GdiplusStartupInput gdiplusStartupInput;//初始化结构体
    GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput,NULL);
}
CGDIPlusUse::~CGDIPlusUse()
{
    GdiplusShutdown(m_gdiplusToken);
}

    代码就这么多。但是在使用的时候就方便多了。使用方法就是,将这个类放在项目里,然后在使用GDI+前创建一个静态的对象即可。代码如下:
#include "GDIPlusUse.h"
static CGDIPlusUse gdiplusenv;

    这个静态对象名称是什么都无所谓,只要放在使用GDI+代码使用之前的地方,就可以了。什么初始化的,什么释放环境的,什么提前释放了环境导致内存读写错误,都不存在了。
    因为是静态对象,在创建对象的时候初始化环境,在对象析构的时候释放环境。静态对象的析构是发生在程序结束的时候,所以很好的满足我们的需要。我们不用像书中所说的,在程序实例创建的时候,写一段初始化代码,在结束的时候,写释放的代码。分散比较多的话,给心理造成了负担。
    我们只处理最基本的初始化,如果你程序有更多的需求,而且是全局的,也可以加入到这个类里来。这是简化代码,优化代码结构,提高代码质量的一种做法。虽然代码不多,起的作用是很大的。你再也不用担心GDI+这些环境问题了。
    下面是我使用的GDI+显示图片的代码:
void Ctmp_gdiplusDlg::OnBnClickedOk()
{
    Graphics graphics(::GetDC(AfxGetMainWnd()->m_hWnd));
    
    //使用静态方法加载图片
    Image * pImg = Image::FromFile(L"D:/1.png");
    graphics.DrawImage(pImg,0,0);
    //使用对象加载图片
    Image img(L"D:/1.gif");
    graphics.DrawImage(&img,pImg->GetWidth()+10,0);
}

    下面是效果图:

GDI绘制png透明图片,效果很好,不过不直接支持GIF图片

【GDI+直接支持显示PNG透明图片,不过不直接支持GIF图片】