Home > COM, Windows API > Easy way to display Gif’s, Ico’s, JPEG’s and BMP’s on your window

Easy way to display Gif’s, Ico’s, JPEG’s and BMP’s on your window

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… 😉

// 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

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.

Advertisements
  1. Mahesh
    October 22, 2008 at 11:49 am

    Very useful article.. Thank you very much..
    Keep updating few more.. 🙂

  1. September 11, 2010 at 9:14 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: