Introduction
CListImageCtrl
is MFC control derived from the CListCtrl
class. The control has an extended feature for loading thumbnail view to the List control. It has a drag and drop functionality to get the image files from the window explorer and draw the thumbnail view for that image file. Here I have simply added a function for drawing that thing.
Step by Step procedure for creating the thumbnail
To develop the thumbnail ListView control, see the below section for step by step operations.
Create the ListImage Project
- Create a New Project using the VC++ - MFC AppWizard (.exe).
- Select the Dialog based option in the wizard - Step 1.
- Finish the wizard.
Now the new project classes added to the workspace (You can see the class files from the fileView tab in Project Workspace tree.
Create the ListImage class for the thumbnail image
- Go to the ClassView tab, select the project name and add a new MFC class by clicking the right mouse button on it.
- Select CListCtrl as a base class for that.
- Now the new class will be created in the project workspace.
How to bind the class to the listcontrol?
- Select the Dialog form from the ResourceView.
- Click the right mouse button from the form dialog and select the ClassWizard from the popup menu.
- Now go to Member variable section select ListControl from the control list.
- Press the Add variable button to add a variable for the ListControl. Select the variable type as the new created class name(ClistImageCtrl or ur added class name) in the Add member variable form.
Enable the Drop file for List Control…
- Select the Dialog form from the ResourceView.
- Open the Property window for List Control.
- In that check the “Accept Files” check box from the Extended Styles.
Get the dropped files from the Explorer
- Select the ListImage class from the classview.
- Open the class wizard for that.
- Add WM_DROPFILES Message function.
- OnDropFiles() function will be automatically added to the class.
void CListImageCtrl::OnDropFiles(HDROP hDropInfo)
{
WORD wNumFilesDropped = DragQueryFile(hDropInfo, -1, NULL, 0);
CString firstFile="";
CFile Cf;
DWORD TmpVal;
char szText[MAX_PATH];
int kk=0;
int tTot=(int)wNumFilesDropped;
int m_TotCount;
for (WORD x = 0 ; x < wNumFilesDropped; x++)
{
kk++;
WORD wPathnameSize = DragQueryFile(hDropInfo, x, NULL, 0);
char * npszFile = (char *) LocalAlloc(LPTR, wPathnameSize += 1);
if (npszFile == NULL) continue;
DragQueryFile(hDropInfo, x, npszFile, wPathnameSize);
if (firstFile=="")
firstFile=npszFile;
CString nFileText;
CString nPath;
CString pItemText=npszFile;
CFile Cf;
int i=pItemText.ReverseFind('\\');
nFileText=pItemText.Mid(i+1);
nPath=pItemText.Left(i+1);
i=nFileText.Find("%");
if (i==-1)
{
i=pItemText.Find(_T(".jpg"),0);
if (i==-1)
i=pItemText.Find(_T(".jpeg"),0);
if (i==-1)
i=pItemText.Find(_T(".JPG"),0);
if (i==-1)
i=pItemText.Find(_T(".JPEG"),0);
if (i!=-1)
{
m_TotCount=GetItemCount();
InsertItem(m_TotCount,nFileText,0);
SetItemText(m_TotCount, 1, nPath);
DoEvents();
if (Cf.Open(pItemText,0,0)==TRUE)
{
TmpVal = Cf.GetLength();
wsprintf(szText, "%lu", TmpVal);
if (TmpVal>1024)
{
double kTmpVal=TmpVal;
double kdvTmp=kTmpVal/1024;
TmpVal=TmpVal/1024;
if (TmpVal>1024)
{
double dTmpVal=TmpVal;
double dvTmp=dTmpVal/1024;
CString szT=
ConvertDoubleToString(dvTmp) + _T(" MB");
wsprintf(szText, "%s", szT);
}
else
{
CString kszT=
ConvertDoubleToString(kdvTmp) + _T(" KB");
wsprintf(szText, "%s", kszT);
}
}
else
wsprintf(szText, "%lu BYTES", TmpVal);
SetItemText(m_TotCount, 2, szText);
}
Cf.Close();
HBITMAP bitm=LoadPicture(pItemText);
if (bitm!=NULL)
{
CBitmap* pImage = NULL;
pImage = new CBitmap();
pImage->Attach(bitm);
int imgP=m_imageList.Add(pImage,RGB(0,0,0));
SetItem(m_TotCount, 0, LVIF_IMAGE, NULL, imgP,0, 0, 0);
}
}
}
LocalFree(npszFile);
}
DragFinish(hDropInfo);
int result=GetItemCount();
SetItemState(result, LVIS_SELECTED |
LVIS_FOCUSED | LVIS_ACTIVATING,
LVIS_SELECTED | LVIS_FOCUSED | LVIS_ACTIVATING);
result--;
EnsureVisible(result, TRUE);
SetFocus();
SetRedraw(TRUE);
RedrawWindow(NULL,NULL);
CListCtrl::OnDropFiles(hDropInfo);
}
Creating Thumbnail image for the Picture file
- Add the LoadPicture function to the ListImage class.
HBITMAP CListImageCtrl::LoadPicture(CString mFile)
{
CString pFSize;
WCHAR wpath[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, mFile, -1, wpath, MAX_PATH);
IPicture* pPic;
OleLoadPicturePath(wpath, NULL, NULL, NULL, IID_IPicture,(LPVOID*)&pPic);
if (pPic==NULL) return NULL;
HBITMAP hPic = NULL;
pPic->get_Handle((UINT*)&hPic);
long nWidth=THUMWIDTH;
long nHeight=THUMHEIGHT;
long mWid,mHei;
pPic->get_Height(&mHei);
pPic->get_Width(&mWid);
HBITMAP hPicRet = (HBITMAP)CopyImage(hPic, IMAGE_BITMAP,
nWidth, nHeight , LR_COPYDELETEORG);
HBRUSH hBrushBorder=::CreateSolidBrush(RGB(192, 192, 192));
HBRUSH hBrushBk=::CreateSolidBrush(RGB(255, 255, 255));
RECT rcBorder;
rcBorder.left=rcBorder.top=0;
rcBorder.right=THUMWIDTH;
rcBorder.bottom=THUMHEIGHT;
const float fRatio=(float)THUMHEIGHT/THUMWIDTH;
int XDest, YDest, nDestWidth, nDestHeight;
const float fImgRatio=(float)mHei/mWid;
if(fImgRatio > fRatio)
{
nDestWidth=(THUMHEIGHT/fImgRatio);
XDest=(THUMWIDTH-nDestWidth)/2;
YDest=0;
nDestHeight=THUMHEIGHT;
}
else
{
XDest=0;
nDestWidth=THUMWIDTH;
nDestHeight=(THUMWIDTH*fImgRatio);
YDest=(THUMHEIGHT-nDestHeight)/2;
}
CClientDC cdc(this);
HDC hDC=::CreateCompatibleDC(cdc.m_hDC);
HBITMAP bm = CreateCompatibleBitmap(cdc.m_hDC, THUMWIDTH, THUMHEIGHT);
HBITMAP pOldBitmapImage = (HBITMAP)SelectObject(hDC,bm);
::FillRect(hDC, &rcBorder, hBrushBk);
::FrameRect(hDC, &rcBorder, hBrushBorder);
HBITMAP hBmReturn= (HBITMAP)::SelectObject(hDC, pOldBitmapImage);
CDC hdcSrc, hdcDst;
hdcSrc.CreateCompatibleDC(NULL);
hdcDst.CreateCompatibleDC(NULL);
CBitmap* hbmSrcT = (CBitmap*) hdcSrc.SelectObject(hPicRet);
CBitmap* hbmDstT = (CBitmap*) hdcDst.SelectObject(hBmReturn);
hdcDst.BitBlt(XDest,YDest,nDestWidth, nDestHeight, &hdcSrc,0,0,SRCCOPY);
pOldBitmapImage = (HBITMAP)SelectObject(hdcDst.m_hDC,bm);
DeleteDC(hDC);
DeleteObject(hBrushBorder);
DeleteObject(hBrushBk);
return pOldBitmapImage;
}