MFC提供的CWnd只有默认加载BMP文件的接口,对JPG等图像是不支持的,而实际中经常需要用到非BMP的图片,在VC中加载.JPG格式的图片,有两种方法,用流对象加载和用IPicture接口加载。
IPicture
*
m_picture;
OLE_XSIZE_HIMETRIC m_width;
OLE_YSIZE_HIMETRIC m_height;
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
CString m_filename(
"
D:\\009.jpg
"
);
//
文件名
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
CFile m_file(m_filename,CFile::modeRead );
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
//
获取文件长度
DWORD m_filelen
=
m_file.GetLength();
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
//
在堆上分配空间
HGLOBAL m_hglobal
=
GlobalAlloc(GMEM_MOVEABLE,m_filelen);
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
LPVOID pvdata
=
NULL
;
//
锁定堆空间,获取指向堆空间的指针
pvdata
=
GlobalLock(m_hglobal);
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
//
将文件数据读区到堆中
m_file.ReadHuge(pvdata,m_filelen);
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
IStream
*
m_stream;
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
GlobalUnlock(m_hglobal);
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
//
在堆中创建流对象
CreateStreamOnHGlobal(m_hglobal,
TRUE
,
&
m_stream);
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
//
利用流加载图像
OleLoadPicture(m_stream,m_filelen,
TRUE
,IID_IPicture,(LPVOID
*
)
&
m_picture);
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
m_picture
->
get_Width(
&
m_width);
m_picture
->
get_Height(
&
m_height);
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
CDC
*
dc
=
GetDC();
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
m_IsShow
=
TRUE
;
CRect rect;
GetClientRect(rect);
SetScrollRange(SB_VERT,
0
,(
int
)(m_height
/
26.45
)
-
rect.Height());
SetScrollRange(SB_HORZ,
0
,(
int
)(m_width
/
26.45
)
-
rect.Width());
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
m_picture
->
Render(
*
dc,
1
,
50
,(
int
)(m_width
/
26.45
),(
int
)(m_height
/
26.45
),
0
,m_height,m_width,
-
m_height,
NULL
);
以上代码是用创建流文件的方式加载,也可以加载.gif图片,但不能显示动画效果。
下面的代码则是用IPicture接口的方式来加载jpg图片(全屏显示图片)。
注意:这两段代码不能用在wince平台上,在wince上加载有另外的函数。
CString szFileName;
szFileName.Empty();
szFileName
=
"
D:\\84.jpg
"
;
IStream
*
pStm;
CFileStatus fstatus;
CFile file;
LONG
cb;
if
(file.Open(szFileName,CFile::modeRead)
&&
file.GetStatus(szFileName,fstatus)
&&
((cb
=
fstatus.m_size) !
=
-
1
))
{
HGLOBAL hGlobal
=
GlobalAlloc(GMEM_MOVEABLE,cb);
LPVOID pvData
=
NULL
;
if
(hGlobal !
=
NULL
)
{
pvData
=
GlobalLock(hGlobal);
if
(pvData !
=
NULL
)
{
file.ReadHuge(pvData,cb);
GlobalUnlock(hGlobal);
CreateStreamOnHGlobal(hGlobal,
TRUE
,
&
pStm);
}
}
}
//
HRESULT Render( HDC hdc,
//
渲染图像用的设备环境句柄
//
long
x,
//
在hdc上的水平坐标
//
long
y,
//
在hdc上的垂直坐标
//
long
cx,
//
图像宽度
//
long
cy,
//
图像高度
//
OLE_XPOS_HIMETRIC xSrc,
//
在源图像上的水平偏移
//
OLE_YPOS_HIMETRIC ySrc,
//
在源图像上的垂直偏移
//
OLE_XSIZE_HIMETRIC cxSrc,
//
在源图像上水平拷贝的数量
//
OLE_YSIZE_HIMETRIC cySrc,
//
在源图像上垂直拷贝的数量
//
LPCRECT prcWBounds
//
指向目标图元设备环境句柄的指针);
CComQIPtr
<
IPicture
>
m_picture;
HRESULT hr
=
OleLoadPicture(pStm,
0
,
false
,IID_IPicture,(void
**
)
&
m_picture);
long
a,b;
m_picture
->
get_Width(
&
a);
m_picture
->
get_Height(
&
b);
CSize sz(a,b);
CDC
*
pdc
=
GetDlgItem(IDC_STATIC)
->
GetDC();
//
CDC
*
pdc
=
GetDC();
//
pdc
->
HIMETRICtoDP(
&
sz);
CRect rect;
GetClientRect(rect);
//
GetDlgItem(IDC_STATIC)
->
GetClientRect(
&
rect);
m_picture
->
Render(
*
pdc,
0
,
0
,sz.cx,sz.cy,
0
,b,a,
-
b,
&
rect);
m_picture
->
Render(
*
pdc,rect.left,rect.top,rect.Width(),
rect.Height(),
0
,b,a,
-
b,
&
rect);
也可以用GDI+把图片转成.bmp文件再加载,在StdAfx.h中静态调用gdiplus.lib,即由编译系统完成对DLL的加载,应用程序结束时卸载DLL的编码。如下:
#ifndef ULONG_PTR
#define ULONG_PTR unsigned long*
#include "GdiPlus.h"
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib")
#endif
2、在类的头文件中定义,以下成员变量,用来初始化GDI+的使用和结束使用。
GdiplusStartupInput m_gdiplusStartupInput;
ULONG_PTR m_gdiplusToken;
3、在初始化函数中,初始化GDI+。如:在OnCreate()函数中加入初始化GDI+的函数:
GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);
4、对应的在OnDestroy()函数中加入结束GDI+使用的函数:
GdiplusShutdown(m_gdiplusToken);
接着,就可以使用GDI+了,要实现要求的内容很容易,方法如下:
写一个如下的方法:
HBITMAP ReturnHBITMAP(CString FileName)//FileName可能是bmp、dib、png、gif、jpeg/jpg、tiff、emf等文件的文件名
{
Bitmap tempBmp(FileName.AllocSysString()) ;
Color backColor;
HBITMAP HBitmap;
tempBmp.GetHBITMAP(backColor,&HBitmap);
return HBitmap;
}
在WM5.0+VC8.0的环境下,还可以COM(组件)的方式加载图片,这种方法能加载的图片的格式比较全(.jpg,.png,.gif),在Windows CE Tools\wce500\Windows Mobile 5.0 Pocket PC SDK\Samples\CPP\Win32\Imaging例子中,用这个COM可以加载皮肤,有兴趣的朋友可以试一下。