项目中遇到显示整个文件夹图片缩略图的问题,采用CListCtrl和CImageList解决,两种方案:
一、图片实际大小和CImagelist设定图片大小是一致的;
二、图片实际大小要小于CImageList设定的大小,也就是需要实现任意大小的缩略图。
备注: 实现垂直滚动条: 资源属性对话框设置 将控件属性Alignment设置为 Top
对话框添加CListCtrl和CImageList, CListCtrl风格设置为ICON风格
解决方案一:
头文件
#pragma once
#include "afxcmn.h"
#define THUMBNAIL_WIDTH 50
#define THUMBNAIL_HEIGHT 50
// CDialogModelList 对话框
class CDialogModelList : public CDialog
{
DECLARE_DYNAMIC(CDialogModelList)
public:
CDialogModelList(CWnd* pParent = NULL); // 标准构造函数
virtual ~CDialogModelList();
// 对话框数据
enum { IDD = IDD_DIALOG_LIST };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
CListCtrl m_listCtlModel;
CImageList m_imgListModel;
//vector<CString> m_fileNameList;
CArray<CString, CString> m_fileNameArray;
CString m_Dir;
virtual BOOL OnInitDialog();
void DrawThumbnails();
};
源文件
// DialogModelList.cpp : 实现文件
#include "stdafx.h"
#include "3DSymbolLibNew.h"
#include "DialogModelList.h"
#include "afxdialogex.h"
#include <io.h>
#include <vector>
//#include <Bitmap.h>
// CDialogModelList 对话框
IMPLEMENT_DYNAMIC(CDialogModelList, CDialog)
CDialogModelList::CDialogModelList(CWnd* pParent /*=NULL*/)
: CDialog(CDialogModelList::IDD, pParent)
{
}
CDialogModelList::~CDialogModelList()
{
}
void CDialogModelList::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_MODEL, m_listCtlModel);
}
BEGIN_MESSAGE_MAP(CDialogModelList, CDialog)
ON_WM_CREATE()
END_MESSAGE_MAP()
// CDialogModelList 消息处理程序
BOOL CDialogModelList::OnInitDialog()
{
CDialog::OnInitDialog();
// 获取文件夹下所有指定类型文件
m_Dir = "C:\\Documents and Settings\\Administrator\\桌面\\行政等级组符号";
_finddata_t fileDir;
char* dir= new char[m_Dir.GetLength()+ strlen("\\*.bmp")] ;//"d:\\temp\\*.*";
sprintf(dir, m_Dir+"\\*.bmp");
long lfDir;
int fileNum = 0;
//vector<CString> fileName;
if((lfDir = _findfirst(dir,&fileDir))==-1l)
printf("No file is found\n");
else{
printf("file list:\n");
do{
printf("%s\n",fileDir.name);
m_fileNameArray.Add(fileDir.name);
++fileNum;
}while( _findnext( lfDir, &fileDir ) == 0 );
}
_findclose(lfDir);
// 填充ClistCtrl 和CimageList
m_listCtlModel.SetExtendedStyle(LVS_ALIGNTOP|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
//m_listCtlModel.SetIconSpacing(CSize(80, 80)); //set pictures spacing
m_imgListModel.Create(50,50, ILC_COLOR32 |ILC_MASK , m_fileNameArray.GetSize(), m_fileNameArray.GetSize());
m_listCtlModel.SetImageList(&m_imgListModel, LVSIL_NORMAL);
DrawThumbnails();
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
void CDialogModelList::DrawThumbnails()
{
CBitmap * bitmap;
bitmap = new CBitmap[m_fileNameArray.GetSize()];
HBITMAP hbitmap;
for(int i = 0; i < m_fileNameArray.GetSize(); i++)
{
CFile f;
CFileException e;
if(!f.Open(m_fileNameArray.GetAt(i), CFile::modeRead, &e))
{
CString m_FileName = m_Dir+ "\\" + m_fileNameArray.GetAt(i)/*m_FileName*/;
hbitmap = (HBITMAP)LoadImage(NULL, m_FileName, IMAGE_BITMAP, 0, 0,
LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE);
}else
{
f.Close();
/*hbitmap = (HBITMAP)LoadImage(NULL,IDR_MAINFRAME,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE|LR_LOADFROMFILE);*/
MessageBox("没有图片");
}
bitmap[i].Attach(hbitmap);
int a = m_imgListModel.Add(&bitmap[i], RGB(0, 128, 128));
m_listCtlModel.InsertItem(a,m_fileNameArray.GetAt(i),a);
}
}
解决方案二(显示任意大小缩略图,采用GDI+):
步骤一:
修改函数DrawThumbnails为
CBitmap* pImage = NULL;
HBITMAP hBmp = NULL;
POINT pt;
CString strPath;
int i;
// no images
if (m_fileNameArray.IsEmpty())
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 = 6;
// hold the window update to avoid flicking
m_listCtlModel.SetRedraw(FALSE);
// reset our image list
for (i = 0; i<m_imgListModel.GetImageCount(); i++)
m_imgListModel.Remove(i);
// remove all items from list view
if (m_listCtlModel.GetItemCount() != 0)
m_listCtlModel.DeleteAllItems();
// set the size of the image list
m_imgListModel.SetImageCount(m_fileNameArray.GetSize());
i = 0;
// draw the thumbnails
for(int i = 0; i < m_fileNameArray.GetSize(); i++)
{
// load the bitmap
strPath.Format(TEXT("%s\\%s"), m_Dir, m_fileNameArray.GetAt(i));
USES_CONVERSION;
Bitmap img( A2W(strPath) );
Bitmap* pThumbnail = static_cast<Bitmap*>(img.GetThumbnailImage(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, NULL, NULL));
int H = img.GetHeight();
// attach the thumbnail bitmap handle to an CBitmap object
pThumbnail->GetHBITMAP(/*NULL*/Color(255,255,255), &hBmp);
pImage = new CBitmap();
pImage->Attach(hBmp);
// add bitmap to our image list
m_imgListModel.Replace(i, pImage, NULL);
// put item to display
// set the image file name as item text
m_listCtlModel.InsertItem(i, m_fileNameArray.GetAt(i), i);
get current item position
//m_listCtlModel.GetItemPosition(i, &pt);
shift the thumbnail to desired position
//pt.x = nGap + i*(THUMBNAIL_WIDTH + nGap);
//m_listCtlModel.SetItemPosition(i, pt);
//i++;
delete pImage;
delete pThumbnail;
}
// let's show the new thumbnails
m_listCtlModel.SetRedraw();
步骤二:
在stdafx.h中添加
#include <gdiplus.h> //GDI+声明,可以GDI/GDI+混合使用
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;
步骤三:
初始化GDI+,在应用程序中添加以下代码
CMyApp: public CWinApp
{ …………
ULONG_PTR m_gdiplusToken;
…………
};
BOOL CMyApp::InitInstance() //在这个函数中添加
{ //初始化GID+
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup( &m_gdiplusToken,&gdiplusStartupInput,NULL );
}
int CMobilePCApp::ExitInstance() //释放GDI+调用,这个函数需要自己写。别忘了声明。
{
GdiplusShutdown( m_gdiplusToken );
return CWinApp::ExitInstance();
}
参考 http://hi.baidu.com/2bdcaonima/item/e92981f25ca1630bc6dc452a