博客首页 注册 建议与交流 排行榜 加入友情链接
推荐 投诉 搜索: 帮助

Ryanliang

发掘潜力 创造价值
Ryanliang.cublog.cn
Thumbnails Viewer using ListCtrl

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.

Collapse
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

  • Ver. 1.0  15, Sep. 2003
    • First release.
  • Ver. 1.1  24, Mar. 2005
    • Fixed crashing when changing a directory fast.
    • Supports Unicode option using preprocessor _UNICODE.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

moah


Youngjin Kim lives in South Korea. I'm interested in every part of Computer Science, cause it has not been long time since graduate a University.
But now I'm working and researching on Pattern Recognition. Using that trying to recognize a Handwriting Prints. Korean and Chinese are my interesting Research Part.
Occupation: Web Developer
Location: Korea, Republic Of Korea, Republic Of

Other popular Combo & List Boxes articles:

Add this article to:
Article Top
Rate this Article for us!   Poor
Excellent
FAQ FAQ  Noise Tolerance Search Search comments 
  Layout   Per page    
newNew Message Msgs 1 to 25 of 129 (Total in Forum: 129) (Refresh) FirstPrevNext
Subject   Author  Date 
General 안녕하세요~ [modified] member rider76 21:22 17 Mar '08  
General how can do it member thrudoor 5:27 28 Nov '07  
General More smooth Picture! member OpenGL_VC 2:40 6 Apr '07  
General Re: More smooth Picture! member moah 2:58 15 May '07  
General LINK : fatal error LNK1181: cannot open input file "./lib/cximagecrtu.lib" member SKhokalay 5:46 7 Dec '06  
General LINK : fatal error LNK1181: cannot open input file "./lib/cximagecrtu.lib" member SKhokalay 5:51 7 Dec '06  
General Re: LINK : fatal error LNK1181: cannot open input file "./lib/cximagecrtu.lib" member cristitomi 5:32 5 Apr '07  
Question Problems in adding a new bar. member perhapszy 4:18 3 Aug '06  
Answer Re: Problems in adding a new bar. member moah 1:20 5 Aug '06  
General Re: Problems in adding a new bar. member perhapszy 4:40 8 Aug '06  
Question lill more help plz member tahinn 1:16 7 Jul '06  
Answer Re: lill more help plz member moah 13:07 8 Jul '06  
General Re: lill more help plz member tahinn 8:50 12 Jul '06  
Question I can't build with Visual C++ 8 (2005) member Anderson Luís 23:34 5 Jul '06  
Answer Re: I can't build with Visual C++ 8 (2005) member moah 12:53 8 Jul '06  
Question show only .bmp images member tahinn 6:41 4 Jul '06  
Answer Re: show only .bmp images member moah 0:46 5 Jul '06  
General Re: show only .bmp images member tahinn 9:17 5 Jul '06  
Question CFormView member Karl Bahr 16:05 29 Jun '06  
Answer Re: CFormView member moah 20:50 29 Jun '06