0
点赞
收藏
分享

微信扫一扫

过年回家,走之前留一个用GDI+实现的略缩图控件


这是一个加载文件夹图片略缩图的控件,支持多种图片格式~~用法也比较简单


过年回家,走之前留一个用GDI+实现的略缩图控件_file



(1)、源代码


//头文件ListImageCtrl.h  

#pragma once

#include <vector>



//note:need GDI+



// ListImageCtrl.h : header file



class CListImageCtrl : public CListCtrl

{

// Construction

public:

CListImageCtrl();



// Attributes

public:

void CreateColumn();

//

BOOL GetImageFileNames();// gather the image file names

void DrawThumbnails();// draw the thumbnails in list control

void Load(); //start load files

void Clear(); //clear list



// Operations

public:

CStringm_strImageDir;

CImageListm_ImageListThumb;// image list holding the thumbnails

std::vector<CString> m_VectorImageNames;// vector holding the image names

intm_nSelectedItem;

BOOL m_bHorz;



// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CListImageCtrl)

//}}AFX_VIRTUAL



// Implementation

public:

virtual ~CListImageCtrl();



// Generated message map functions

protected:

//{{AFX_MSG(CListImageCtrl)

afx_msg void OnDropFiles(HDROP hDropInfo);

//}}AFX_MSG



DECLARE_MESSAGE_MAP()

};





// ListImageCtrl.cpp : implementation file

//



#include "stdafx.h"

#include "Medical.h"

#include "ListImageCtrl.h"



#define THUMBNAIL_WIDTH 90

#define THUMBNAIL_HEIGHT 90



void DoEvents(void);



/

// CListImageCtrl



CListImageCtrl::CListImageCtrl()

{

m_strImageDir = _T("");

m_bHorz = FALSE;

}



CListImageCtrl::~CListImageCtrl()

{

}





BEGIN_MESSAGE_MAP(CListImageCtrl, CListCtrl)

//{{AFX_MSG_MAP(CListImageCtrl)

ON_WM_DROPFILES()

//}}AFX_MSG_MAP

END_MESSAGE_MAP()



/

// CListImageCtrl message handlers



// This funtion is used to load the Window dropped files into the listview



void CListImageCtrl::OnDropFiles(HDROP hDropInfo)

{

WORD wNumFilesDropped = DragQueryFile(hDropInfo, -1, NULL, 0);



CString firstFile(_T(""));

int kk=0;

int tTot=(int)wNumFilesDropped;



// show hour glass cursor

BeginWaitCursor();



for (WORD x = 0 ; x < wNumFilesDropped; x++)

{

kk++;

// Get the number of bytes required by the file's full pathname

WORD wPathnameSize = DragQueryFile(hDropInfo, x, NULL, 0);

TRACE1("wPathnameSize=%d,\n",wPathnameSize);



// Allocate memory to contain full pathname & zero byte

wPathnameSize +=1;

TCHAR * npszFile = (TCHAR *) LocalAlloc(LPTR, sizeof(TCHAR)*wPathnameSize); //注意分配的内存大小



// If not enough memory, skip this one

if (npszFile == NULL) continue;

DragQueryFile(hDropInfo, x, npszFile, wPathnameSize);



if (firstFile=="")

firstFile=npszFile;



CString strExt;

CString nFileText;

CString pItemText=npszFile;



TRACE1("%s\n",pItemText);



int i=pItemText.ReverseFind('\\');

nFileText = pItemText.Mid(i+1);

m_strImageDir = pItemText.Left(i+1);



strExt = pItemText.Right(3);

TRACE1("strExt=%s\n",strExt);



if ( (strExt.CompareNoCase( TEXT("bmp") ) == 0) ||

(strExt.CompareNoCase( TEXT("jpg") ) == 0) ||

(strExt.CompareNoCase( TEXT("gif") ) == 0) ||

(strExt.CompareNoCase( TEXT("tif") ) == 0) ||

(strExt.CompareNoCase( TEXT("png") ) == 0) )

{

// save the image file name, not the path

m_VectorImageNames.push_back(nFileText);

}



// clean up

LocalFree(npszFile);

}



// Free the memory block containing the dropped-file information

DragFinish(hDropInfo);



if(!m_VectorImageNames.empty())

DrawThumbnails();



SetFocus();

SetItemState(0, LVIS_SELECTED | LVS_ICON | LVS_AUTOARRANGE, LVIS_SELECTED | LVIS_FOCUSED | LVIS_ACTIVATING);

EndWaitCursor();



CListCtrl::OnDropFiles(hDropInfo);

}





void CListImageCtrl::CreateColumn()

{

InsertColumn(0,_T("Filename"),LVCFMT_LEFT,125,-1);

InsertColumn(1,_T("Path"),LVCFMT_LEFT,125,-1);

InsertColumn(2,_T("Size"),LVCFMT_LEFT,75,-1);



HIMAGELIST hScreens = ImageList_Create(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, ILC_COLOR32 /*| ILC_MASK*/ , 0, 1);

m_ImageListThumb.Attach(hScreens);

m_nSelectedItem = 0;



// load the starting bitmap ("Loading..." and "Corrupt file")

// CBitmap dummy;

// dummy.LoadBitmap(IDB_BITMAP1);

// m_ImageListThumb.Add(&dummy, RGB(0, 0, 0));



SetImageList(&m_ImageListThumb, LVSIL_NORMAL);

SetImageList(&m_ImageListThumb, LVSIL_SMALL);



}



// this function is used to enable the system messages

// this is mainly used to display the multiple images dropped on the list control



void DoEvents(void)

{

MSG Symsg;



while(PeekMessage(&Symsg,NULL,0,0,PM_REMOVE))

{

TranslateMessage(&Symsg);

DispatchMessage(&Symsg);

}

}



BOOL CListImageCtrl::GetImageFileNames()

{

CStringstrExt;

CStringstrName;

CStringstrPattern;

BOOLbRC = TRUE;



HANDLEhFind = NULL;

WIN32_FIND_DATAFindFileData;

std::vector<CString>VectorImageNames;



if ( m_strImageDir[m_strImageDir.GetLength() - 1] == TCHAR('\\') )

strPattern.Format( TEXT("%s*.*"), m_strImageDir );

else

strPattern.Format( TEXT("%s\\*.*"), m_strImageDir );



hFind = ::FindFirstFile(strPattern, &FindFileData);// strat search

if (hFind == INVALID_HANDLE_VALUE)

{

LPVOID msg;

::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,

NULL,

GetLastError(),

MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

(LPTSTR)&msg,

0,

NULL);

MessageBox((LPTSTR)msg, CString((LPCSTR)IDS_TITLE), MB_OK|MB_ICONSTOP);

::LocalFree(msg);

return FALSE;

}



// filter off the system files and directories

if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&

!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) &&

!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) &&

!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY))

{

// test file extension

strName = FindFileData.cFileName;

strExt = strName.Right(3);



if ( (strExt.CompareNoCase( TEXT("bmp") ) == 0) ||

(strExt.CompareNoCase( TEXT("jpg") ) == 0) ||

(strExt.CompareNoCase( TEXT("gif") ) == 0) ||

(strExt.CompareNoCase( TEXT("tif") ) == 0) ||

(strExt.CompareNoCase( TEXT("png") ) == 0) )

{

// save the image file name

VectorImageNames.push_back(strName);

}

}



// loop through to add all of them to our vector

while (bRC)

{

bRC = ::FindNextFile(hFind, &FindFileData);

if (bRC)

{

// filter off the system files and directories

if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&

!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) &&

!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) &&

!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY))

{

// test file extension

strName = FindFileData.cFileName;

strExt = strName.Right(3);



if ( (strExt.CompareNoCase( TEXT("bmp") ) == 0) ||

(strExt.CompareNoCase( TEXT("jpg") ) == 0) ||

(strExt.CompareNoCase( TEXT("gif") ) == 0) ||

(strExt.CompareNoCase( TEXT("tif") ) == 0) ||

(strExt.CompareNoCase( TEXT("png") ) == 0) )

{

// save the image file name

VectorImageNames.push_back(strName);

}

}

}

else

{

DWORD err = ::GetLastError();

if (err != ERROR_NO_MORE_FILES)

{

LPVOID msg;

::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,

NULL, err,

MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

(LPTSTR)&msg, 0, NULL);

MessageBox((LPTSTR)msg, CString((LPCSTR)IDS_TITLE), MB_OK|MB_ICONSTOP);

::LocalFree(msg);

::FindClose(hFind);

return FALSE;

}

}

} // end of while loop



// close the search handle

::FindClose(hFind);



// update the names, if any

if ( !VectorImageNames.empty() )

{

// reset the image name vector

m_VectorImageNames.clear();

m_VectorImageNames = VectorImageNames;

return TRUE;

}



return FALSE;

}



void CListImageCtrl::DrawThumbnails()

{

CStringstrPath;

inti;



// no images

if (m_VectorImageNames.empty())

return;



// set the length of the space between thumbnails

// you can also calculate and set it based on the length of your list control

int nGap = 40;



// hold the window update to avoid flicking

SetRedraw(FALSE);



// reset our image list

for (i = 0; i < m_ImageListThumb.GetImageCount(); i++)

m_ImageListThumb.Remove(i);



// remove all items from list view

if (this->GetItemCount() != 0)

this->DeleteAllItems();



// set the size of the image list

m_ImageListThumb.SetImageCount(m_VectorImageNames.size());

i = 0;



// draw the thumbnails

std::vector<CString>::iterator

for (iter = m_VectorImageNames.begin(); iter != m_VectorImageNames.end(); iter++)

{

HBITMAP hbmReturn = NULL;

Bitmap *bmPhoto = NULL;

CBitmap Bmp1;



// load the bitmap

strPath.Format( TEXT("%s\\%s"), m_strImageDir, *iter );



Bitmap img( strPath.AllocSysString() );



int sourceWidth = img.GetWidth();

int sourceHeight = img.GetHeight();



int destX, destY, destWidth, destHeight;

const float fRatio=(float)THUMBNAIL_HEIGHT/THUMBNAIL_WIDTH;

const float fImgRatio=(float)sourceHeight/sourceWidth;



if(fImgRatio > fRatio)

{

destWidth=(THUMBNAIL_HEIGHT/fImgRatio);

destX=(THUMBNAIL_WIDTH-destWidth)/2;

destY=0;

destHeight=THUMBNAIL_HEIGHT;

}

else

{

destX=0;

destWidth=THUMBNAIL_WIDTH;

destHeight=(THUMBNAIL_WIDTH*fImgRatio);

destY=(THUMBNAIL_HEIGHT-destHeight)/2;

}



//check out very small image

if ((sourceHeight < THUMBNAIL_HEIGHT) && (sourceWidth < THUMBNAIL_WIDTH))

{

destWidth=sourceWidth;

destHeight=sourceHeight;

destX=(THUMBNAIL_WIDTH-destWidth)/2;

destY=(THUMBNAIL_HEIGHT-destHeight)/2;

}



bmPhoto = new Bitmap( THUMBNAIL_WIDTH, THUMBNAIL_WIDTH , PixelFormat32bppRGB );

bmPhoto->SetResolution( img.GetHorizontalResolution(), img.GetVerticalResolution() );



Graphics *grPhoto = Graphics::FromImage( bmPhoto );

Color colorW(255, 255, 255, 255);

Gdiplus::Pen pen(Color(200,192,192,192));

grPhoto->Clear( colorW );

grPhoto->SetInterpolationMode( InterpolationModeHighQualityBilinear );

grPhoto->DrawImage( &img, Rect(destX, destY, destWidth, destHeight) );

grPhoto->DrawRectangle(&pen,Gdiplus::Rect(0,0,THUMBNAIL_WIDTH-1,THUMBNAIL_HEIGHT-1)); //draw border



bmPhoto->GetHBITMAP( colorW, &hbmReturn );



Bmp1.Attach( hbmReturn );

m_ImageListThumb.Replace( i, &Bmp1, NULL );

//int imgP=m_ImageListThumb.Add(&Bmp1,RGB(0,0,0));



InsertItem(i, m_VectorImageNames[i],i); //Link to the added listview item



delete grPhoto;

delete bmPhoto;

Bmp1.Detach();

DeleteObject( hbmReturn );

i++;



}



// let's show the new thumbnails

SetRedraw();

}



void CListImageCtrl::Load()

{

// TODO: Add your control notification handler code here

UpdateData(TRUE);



// validate image directory

if (m_strImageDir.IsEmpty())

{

MessageBox(CString((LPCSTR)IDS_DIR_ERROR), CString((LPCSTR)IDS_TITLE), MB_OK|MB_ICONSTOP);

return;

}



// show hour glass cursor

BeginWaitCursor();



// get the names of bitmap files

if ( !GetImageFileNames() )

{

EndWaitCursor();

return;

}



// draw thumbnail images in list control

DrawThumbnails();



// draw the selected image in its full size

//DrawSelectedImage();



// if this was a shortcut, we need to expand it to the target path

SetItemState(0, LVIS_SELECTED | LVS_ICON | LVS_AUTOARRANGE, LVIS_SELECTED | LVIS_FOCUSED | LVIS_ACTIVATING);

SetFocus();



RedrawWindow(NULL,NULL);



EndWaitCursor();



}



void CListImageCtrl::Clear()

{

// hold the window update to avoid flicking

SetRedraw(FALSE);



// reset our image list

for (int i = 0; i < m_ImageListThumb.GetImageCount(); i++)

m_ImageListThumb.Remove(i);



// remove all items from list view

if (this->GetItemCount() != 0)

this->DeleteAllItems();



m_strImageDir = _T("");



m_VectorImageNames.clear();



SetRedraw();



}



(2)、用法




1、在界面上放一个ListCtrl控件,设置View属性为ICON,Accept files属性TRUE,然后关联一个变量,如CListImageCtrl  m_lstImg;


2、在 BOOL CXXXDlg::OnInitDialog()初始化控件,一个语句就可以了m_lstImg.CreateColumn();


3、加载略缩图方法可以拖拽图片到控件,也可以这样加载


//strPath




m_lstImg.m_strImageDir = strPath;

m_lstImg.Load();

 

 


举报

相关推荐

0 条评论