过年回家,走之前留一个用GDI+实现的略缩图控件
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                过年回家,走之前留一个用GDI+实现的略缩图控件
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                
                            
                            
                            這是一個加載文件夾圖片略縮圖的控件,支持多種圖片格式~~用法也比較簡單 
(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??iter; 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?是一個CString變量,文件夾路徑
  
m_lstImg.m_strImageDir = strPath; m_lstImg.Load();
       
                            
                        
                        
                        (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??iter; 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?是一個CString變量,文件夾路徑
m_lstImg.m_strImageDir = strPath; m_lstImg.Load();
?
 
 
?
總結
以上是生活随笔為你收集整理的过年回家,走之前留一个用GDI+实现的略缩图控件的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: NW.js是什么?(cropper.js
- 下一篇: jdk8安装教程详解(JDK8下载安装教
