Here is a function that does this! You only have to call this function with an image file, (gif, jpeg, jpg, bmp, ico) and a window handle onto which picture is to be painted. This is originally from MSDN but I modified it slightly to make it into one function… 😉
[sourcecode language=’cpp’]// This function loads a file into an IStream.
void LoadPictureFile( LPCTSTR szFile, HWND hWnd )
{
LPPICTURE gpPicture = 0;
// open file
HANDLE hFile = CreateFile(szFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
_ASSERTE(INVALID_HANDLE_VALUE != hFile);
// get file size
DWORD dwFileSize = GetFileSize(hFile, NULL);
_ASSERTE(-1 != dwFileSize);
LPVOID pvData = NULL;
// alloc memory based on file size
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
_ASSERTE(NULL != hGlobal);
pvData = GlobalLock(hGlobal);
_ASSERTE(NULL != pvData);
DWORD dwBytesRead = 0;
// read file and store in global memory
BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);
_ASSERTE(FALSE != bRead);
GlobalUnlock(hGlobal);
CloseHandle(hFile);
LPSTREAM pstm = NULL;
// create IStream* from global memory
HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm);
_ASSERTE(SUCCEEDED(hr) && pstm);
// Create IPicture from image file
if (gpPicture)
gpPicture->Release();
hr = ::OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID *)&gpPicture);
_ASSERTE(SUCCEEDED(hr) && gpPicture);
pstm->Release();
/** Painting part added to make it into one function **/
// Retrieve dc
HDC hdc = GetDC( hWnd );
long hmWidth = 0;
long hmHeight = 0;
gpPicture->get_Width(&hmWidth);
gpPicture->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);
RECT rc;
GetClientRect(hWnd, &rc);
// display picture using IPicture::Render
gpPicture->Render(hdc, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, &rc);
ReleaseDC( hWnd, hdc );
gpPicture->Release();
/** End Painting Part **/
}// End LoadPictureFile[/sourcecode]
It’s not a good idea to put painting stuff in one function, since painted image will get erased when window is moved or resized. Ideally painting stuff should be in the WM_PAINT handler, so I leave that part to you.
Very useful article.. Thank you very much..
Keep updating few more.. 🙂
Pingback: LPPICTURE and painting to a control.