对话框加载PNG背景图片

首先,在stdafx.h文件中,添加以下代码,引用GDI+库。

/*----------------GDI+----------------*/
#include
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;
/*------------------------------------*/

然后,在CXXXApp的类定义中,声明变量。

class CHighSpeedGrabApp : public CWinApp

{

public:

ULONG_PTR m_gdiplusToken;

... ... ... ...

}

BOOL CXXXApp::InitInstance()

{

Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

... ... ... ...

}

int CXXXApp::ExitInstance()
{
Gdiplus::GdiplusShutdown(m_gdiplusToken);

... ... ... ...

}

然后,在CXXXDlg的类定义中,声明变量。

class CXXXDlg : public CDialogEx

{

public:

Gdiplus::Image* m_pPngBg;   // 背景位图资源PNG

... ... ... ...

}


#include "AdvEdit.h"

... ... ... ...

// 添加消息映射ON_WM_ERASEBKGND()

BOOL CXXXDlg::OnEraseBkgnd(CDC* pDC)

{
// TODO: 在此添加消息处理程序代码和/或调用默认值
// 客户区加载背景图片,方法一
CRect rect;
GetClientRect(&rect);
CImage image;
image.Load(_T("./Images/背景png.png"));
image.Draw(pDC->m_hDC,0,0,rect.Width(),rect.Height());


// 客户区加载背景图片,方法二
if(CAdvEdit::G_ImageFromIDResource(MAKEINTRESOURCE(IDR_BACK), _T("PNG"), m_pPngBg))
{
if (m_pPngBg == NULL)
{
return FALSE;
}

CRect rect;
this->GetClientRect(&rect);
int nWidth  = m_pPngBg->GetWidth();
int nHeight = m_pPngBg->GetHeight();


// 初始化GDI+以及graphics
Gdiplus::Graphics graphics(pDC->m_hDC);
CDC MemDc;
// 将图像绘制在(x,y)处,根据分辨率自动缩放,所得的显示图片的长宽与源图像可能不一致。
graphics.DrawImage(m_pPngBg, rect.left, rect.top, rect.Width(), rect.Height());
MemDc.CreateCompatibleDC(pDC);
CBitmap bitMemMap;
bitMemMap.CreateCompatibleBitmap(pDC, nWidth, nHeight);
MemDc.SelectObject(&bitMemMap);
MemDc.BitBlt(rect.left, rect.top, nWidth, nHeight, &MemDc, 0, 0, SRCCOPY);
bitMemMap.DeleteObject();
MemDc.DeleteDC(); 
}


return TRUE;

}

头文件AdvEdit.h

namespace CAdvEdit

{

static bool G_ImageFromIDResource(LPCTSTR pName, LPCTSTR pType, Gdiplus::Image* &m_pBitmap)
{
HGLOBAL m_hBuffer = NULL;
// 计算机函数。该函数确定指定模块中指定类型和名称的资源所在位置。
// 如果函数运行成功,那么返回值为指向被指定资源信息块的句柄。
// 为了获得这些资源,将这个句柄传递给LoadResource函数。
// 如果函数运行失败,则返回值为NULL。
// 若想获得更多错误信息,请调用GetLastError函数。
HRSRC hResource = ::FindResource(NULL, pName, pType);
if (!hResource)
return false;
// 返回指定资源的字节数大小。
DWORD imageSize = ::SizeofResource(NULL, hResource);
if (!imageSize)
return false;
// 先装载指定资源到全局存储器。
// 然后,锁定资源并得到资源在内存中的第一个字节的指针。
const void* pResourceData = ::LockResource(::LoadResource(NULL, hResource));
if (!pResourceData)
return false;
// Windows API函数。该函数从堆中分配一定数目的字节数。
m_hBuffer  = ::GlobalAlloc(GMEM_MOVEABLE, imageSize);
if (m_hBuffer)
{
// 锁定内存中指定的内存块,并返回一个地址值,令其指向内存块的起始处。
void* pBuffer = ::GlobalLock(m_hBuffer);
if (pBuffer)
{
// 将一块内存的数据从一个位置复制到另一个位置。
CopyMemory(pBuffer, pResourceData, imageSize);


IStream* pStream = NULL;
// 指定内存创建流对象。
// 如果函数创建流对象成功则返回S_OK。
if (::CreateStreamOnHGlobal(m_hBuffer, FALSE, &pStream) == S_OK)
{
m_pBitmap = Gdiplus::Bitmap::FromStream(pStream);
pStream->Release();
if (m_pBitmap)

if (m_pBitmap->GetLastStatus() == Gdiplus::Ok)
return true;


delete m_pBitmap;
m_pBitmap = NULL;
}
}
// 解除锁定的内存块,使指向该内存块的指针无效。
// GlobalLock锁定的内存,一定要用GlobalUnlock解锁。
::GlobalUnlock(m_hBuffer);
}
// 释放指定的全局内存块。
::GlobalFree(m_hBuffer);
m_hBuffer = NULL;
}
return false;
}

... ... ... ...

}

你可能感兴趣的:(C/C++编程)