CListCtrl和CImageList配合显示缩略图

项目中遇到显示整个文件夹图片缩略图的问题,采用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

猜你喜欢

转载自blog.csdn.net/zishuiyi/article/details/20360589
今日推荐