Самый "официальный" способ. Появился вместе с OLE32 и работает до сих пор. Функции OleLoadPicture(Ex) и OleLoadPicturePath умеют загружать картинки в формате BMP, GIF, JPEG, ICO, WMF, и EMF:
#include <olectl.h>
HRESULT Load(LPCTSTR szFile) {
CComPtr<IStream> pStream;
// Load the file to a memory stream
HRESULT hr = FileToStream(szFile, &pStream);
if (SUCCEEDED(hr)) {
// Decode the picture
hr = ::OleLoadPicture(
pStream, // [in] Pointer to the stream that contains picture's data
0, // [in] Number of bytes read from the stream (0 == entire)
true, // [in] Loose original format if true
IID_IPicture, // [in] Requested interface
(void**)&m_pPicture // [out] IPictire object on success
);
}
return hr;
}
HRESULT DrawImg(HDC hdc, const RECT& rcBounds) {
if (m_pPicture) {
// Get the width and the height of the picture
long hmWidth = 0, hmHeight = 0;
m_pPicture->get_Width(&hmWidth);
m_pPicture->get_Height(&hmHeight);
// Convert himetric to pixels
int nWidth = MulDiv(hmWidth, ::GetDeviceCaps(hdc, LOGPIXELSX), HIMETRIC_INCH);
int nHeight = MulDiv(hmHeight, ::GetDeviceCaps(hdc, LOGPIXELSY), HIMETRIC_INCH);
// Display the picture using IPicture::Render
return m_pPicture->Render(
hdc, // [in] Handle of device context on which to render the image
rcBounds.left, // [in] Horizontal position of image in hdc
rcBounds.top, // [in] Vertical position of image in hdc
rcBounds.right - rcBounds.left, // [in] Horizontal dimension of destination rect.
rcBounds.bottom - rcBounds.top, // [in] Vertical dimension of destination rect.
0, // [in] Horizontal offset in source picture
hmHeight, // [in] Vertical offset in source picture
hmWidth, // [in] Amount to copy horizontally in source picture
– hmHeight, // [in] Amount to copy vertically in source picture
&rcBounds // [in, optional] Pointer to position of destination for a metafile hdc
);
}
return E_UNEXPECTED;
}
Достоинства:
правильно работает с прозрачными картинками.
Недостатки: не поддерживает анимированный GIF (см. также CPicturEx). Не поддерживает PNG.
Способ 2 (GDI+)
Недостаток ::LoadImage с лихвой исправили в GDI+. Объект Gdiplus::Image умеет загружать картинки в формате bmp, gif, jpeg, png, TIFF, EXIF, WMF, и EMF:
#include <gdiplus.h>
HRESULT Load(LPCTSTR szFile) {
USES_CONVERSION;
// Create new Gdiplus::Image object
m_pImage = new Gdiplus::Image(T2CW(szFile));
ATLASSERT(m_pImage);
// Check for success
if (Gdiplus::Ok == m_pImage->GetLastStatus) return S_OK;
Достоинства: понимает множество форматов, в том числе анимированный GIF, правильно работает с прозрачными картинками.
Недостатки: На сегодняшний момент реализован только в WindowsXP. Хотя простое копирование gdiplus.dll в system32 делает ее доступной, как минимум, в Windows2000. Скорее всего, в обозримом будущем ожидаются версии и для Win9x.
Способ 3 (IImgCtx)
Не так давно Майкрософт предоставила заголовочные и библиотечные файлы к объекту ImgCtx, появившемуся еще в internet explorer 4.0. Он умеет заргужать картинки в формате BMP, GIF, JPEG, ICO, WMF, EMF, PNG, XBM, ICO, TIFF и, возможно, некоторых других: