Skip to main content
Email Password   helpLost your password?

Sample Image - ThumbViewer.jpg

Introduction

There are several image libraries and sources currently available. So I made my mind up to make a free Image Viewer using a free image library, and I got many free demo programs. I think a good image viewer must be able to show thumbnail images in a selected directory. I found some sources showing thumbnails, but they didn't support several formats, only BMP files. This thumbnail viewer is based on CxImage, so if there is an image format supported by CxImage, this viewer also supports that format.

Implementation

I want to show you the core part in this article. How to make a CListCtrl, CImageList, and then how to load images and attach that image to an ImageList.

1. Creating CListCtrl and CImageList

I used a CListView instead of CListCtrl, but you know that CListView uses CListCtrl internally. So overriding Create(...) will make your icon view CListCtrl initially. And then on OnInitialUpdate(), make ImageList which can support 24 bit color images and attach to CListCtrl.

return CListView::Create(lpszClassName, _T("ListView"),
  dwStyle|LVS_SHOWSELALWAYS|LVS_ALIGNTOP|LVS_ICON|LVS_SINGLESEL|
  LVS_AUTOARRANGE, rect, pParentWnd, nID, pContext);

....
m_ImageListThumb.Create(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, ILC_COLOR24, 0, 1);
 ListCtrl.SetImageList(&m_ImageListThumb, LVSIL_NORMAL);

2. Load Images and Insert Items

Create a Compatible DC and a Bitmap Handle. Stretch a loaded image to the Bitmap Handle and then attach it to CBitmap. Finally, replace CBitmap with an image in the ImageList.

unsigned __stdcall CThumbViewerView::LoadThumbNail(LPVOID lpParam)
{
 CThumbViewerView* pView=(CThumbViewerView*)lpParam;
 CThumbViewerDoc* pDoc=pView->GetDocument();

 CListCtrl& ListCtrl=pView->GetListCtrl();
 CImageList* pImgList=&pView->m_ImageListThumb;

 // reset our image list

 for(int i=0; i<pImgList->GetImageCount(); i++)
  pImgList->Remove(i); 

 // remove all items from list view

 ListCtrl.DeleteAllItems();

 pImgList->SetImageCount(pDoc->m_vFileName.size());

 char path[MAX_PATH];
 vector<CString>::iterator iter;
 
 // Set redraw to FALSE to avoid flickering during adding new items

 ListCtrl.SetRedraw(FALSE);
 int nIndex=0;
 for(iter=pDoc->m_vFileName.begin(); 
     iter!=pDoc->m_vFileName.end() && pView->m_bTerminate!=true; 
     iter++, nIndex++)
 {
          ListCtrl.InsertItem(nIndex, *iter, nIndex);
 }

 ListCtrl.SetRedraw(TRUE);
 ListCtrl.Invalidate();

 // Create Brushes for Border and BackGround

 HBRUSH hBrushBorder=::CreateSolidBrush(RGB(192, 192, 192));
 HBRUSH hBrushBk=::CreateSolidBrush(RGB(255, 255, 255));

 // Border Size

 RECT rcBorder;
 rcBorder.left=rcBorder.top=0;
 rcBorder.right=THUMBNAIL_WIDTH;
 rcBorder.bottom=THUMBNAIL_HEIGHT;

 const float fRatio=(float)THUMBNAIL_HEIGHT/THUMBNAIL_WIDTH;

 int XDest, YDest, nDestWidth, nDestHeight;
 nIndex=0;
 for(iter=pDoc->m_vFileName.begin(); 
     iter!=pDoc->m_vFileName.end() && pView->m_bTerminate!=true; 
     iter++, nIndex++)
 {
  // Load Image File

  sprintf(path, "%s\\%s", pDoc->m_strCurrentDirectory, *iter);

  int nImageType=pDoc->GetTypeFromFileName(path);
  if(nImageType==CXIMAGE_FORMAT_UNKNOWN)
   continue;

  CxImage image(path, nImageType);

  if(image.IsValid()==false)
   continue;

  // Calculate Rect to fit to canvas

  const float fImgRatio=(float)image.GetHeight()/image.GetWidth();
  if(fImgRatio > fRatio)
  {
   nDestWidth=THUMBNAIL_HEIGHT/fImgRatio;
   XDest=(THUMBNAIL_WIDTH-nDestWidth)/2;
   YDest=0;
   nDestHeight=THUMBNAIL_HEIGHT;
  }
  else
  {
   XDest=0;
   nDestWidth=THUMBNAIL_WIDTH;
   nDestHeight=THUMBNAIL_WIDTH*fImgRatio;
   YDest=(THUMBNAIL_HEIGHT-nDestHeight)/2;
  }

  CClientDC cdc(pView);
  HDC hDC=::CreateCompatibleDC(cdc.m_hDC);
  HBITMAP bm = CreateCompatibleBitmap(cdc.m_hDC, THUMBNAIL_WIDTH, 
                                      THUMBNAIL_HEIGHT);
  HBITMAP pOldBitmapImage = (HBITMAP)SelectObject(hDC,bm);
  // Draw Background

  ::FillRect(hDC, &rcBorder, hBrushBk);

  // Draw Image

  image.Stretch(hDC, XDest, YDest, nDestWidth, nDestHeight);

  // Draw Border

  ::FrameRect(hDC, &rcBorder, hBrushBorder);

  SelectObject(hDC, pOldBitmapImage);

  // Attach to Bitmap and Replace image in CImageList

  CBitmap bitmap;
  bitmap.Attach(bm);
  pImgList->Replace(nIndex, &bitmap, NULL);

  // Redraw only a current item for removing flickering and fast speed.

  ListCtrl.RedrawItems(nIndex, nIndex);

  // Release used DC and Object

  DeleteDC(hDC);
  DeleteObject(bm);
 }
 DeleteObject(hBrushBorder);
 DeleteObject(hBrushBk);

 ListCtrl.Invalidate();
 pView->m_bRunning=false;
 pView->m_bTerminate=false;

 _endthreadex( 0 );

 return 0;
}

Acknowledgment

You can download CxImage freely from here.

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
Generalhello, I came across one question. I need your help... Pin
cciill
7:42 5 Sep '09  
GeneralWhy can't I hide the VScroll in listctrl??? Pin
Sophia29
22:30 25 Nov '08  
GeneralDatagrid thumbnail images Pin
skyair
16:49 29 Jun '08  
GeneralHai Pin
Sivan Manimala
0:09 3 Jun '08  
GeneralPossible to only highlight name and not picture? Pin
alan93
11:09 29 May '08  
GeneralRe: Possible to only highlight name and not picture? Pin
DevoraNur
21:51 24 Oct '09  
GeneralRe: Possible to only highlight name and not picture? Pin
alan93
3:44 28 Oct '09  
General안녕하세요~ [modified] Pin
rider76
16:22 17 Mar '08  
Generalhow can do it Pin
thrudoor
0:27 28 Nov '07  
GeneralMore smooth Picture! Pin
OpenGL_VC
21:40 5 Apr '07  
GeneralRe: More smooth Picture! Pin
moah
21:58 14 May '07  
GeneralLINK : fatal error LNK1181: cannot open input file "./lib/cximagecrtu.lib" Pin
SKhokalay
0:46 7 Dec '06  
GeneralLINK : fatal error LNK1181: cannot open input file "./lib/cximagecrtu.lib" Pin
SKhokalay
0:51 7 Dec '06  
GeneralRe: LINK : fatal error LNK1181: cannot open input file "./lib/cximagecrtu.lib" Pin
cristitomi
0:32 5 Apr '07  
GeneralRe: LINK : fatal error LNK1181: cannot open input file "./lib/cximagecrtu.lib" Pin
Son Ji Seon
4:28 26 May '09  
QuestionProblems in adding a new bar. Pin
perhapszy
23:18 2 Aug '06  
AnswerRe: Problems in adding a new bar. Pin
moah
20:20 4 Aug '06  
GeneralRe: Problems in adding a new bar. Pin
perhapszy
23:40 7 Aug '06  
Questionlill more help plz Pin
tahinn
20:16 6 Jul '06  
AnswerRe: lill more help plz Pin
moah
8:07 8 Jul '06  
GeneralRe: lill more help plz Pin
tahinn
3:50 12 Jul '06  
QuestionI can't build with Visual C++ 8 (2005) Pin
Anderson Luís
18:34 5 Jul '06  
AnswerRe: I can't build with Visual C++ 8 (2005) Pin
moah
7:53 8 Jul '06  
GeneralRe: I can't build with Visual C++ 8 (2005) Pin
tdjdyq
20:26 23 Jul '08  
Questionshow only .bmp images Pin
tahinn
1:41 4 Jul '06  


Last Updated 27 Jan 2006 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009