加入图片

步骤简要如下:

1. 创建ClmageList 对象,指定图片的宽度和高度

2. CImageList 对象传递给CListCtrl 对象

3.ClistCtrl 增加item 时,将图片ID 和文字一起传入

具体代码如下:

ListImage.cpp 代码如下

// ListImage.cpp : implementation file
//

#include "stdafx.h"
#include "practise.h"
#include "ListImage.h"
#define THUMWIDTH 75
#define THUMHEIGHT 55

// ListImage dialog

IMPLEMENT_DYNAMIC(ListImage, CDialog)

ListImage::ListImage(CWnd* pParent /*=NULL*/)
 : CDialog(ListImage::IDD, pParent)
{

}

ListImage::~ListImage()
{
}

void ListImage::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 DDX_Control(pDX, IDC_LIST1, m_List);
 DDX_Control(pDX, IDC_EDIT2, m_edit2);
}


BEGIN_MESSAGE_MAP(ListImage, CDialog)
 ON_BN_CLICKED(IDC_BUTTON1, &ListImage::OnBnClickedButton1)
 ON_BN_CLICKED(IDOK, &ListImage::OnBnClickedOk)
END_MESSAGE_MAP()


// ListImage message handlers
BOOL ListImage::OnInitDialog()
{
 CDialog::OnInitDialog();

 // TODO: Add extra initialization here

 return TRUE;  // return TRUE unless you set the focus to a control
 // EXCEPTION: OCX Property Pages should return FALSE
}
void ListImage::OnBnClickedButton1()
{
 // TODO: Add your control notification handler code here
 //
文件对话框  

 CString FilePath;
 CFileDialog FileDialog(true, _T(""), _T(""), OFN_EXPLORER,  
  _T("
所有文件(*.*)|*.*||"), this);  

 // 显示对话框  
 if(FileDialog.DoModal() == IDOK)  
 {  
  FilePath = FileDialog.GetPathName();  
  int g=FilePath.ReverseFind('//');
  FilePath=FilePath.Left(g+1);
  m_edit2.SetWindowText(FilePath);

 }  
 else
 {
  return;
 }
 //
清楚m_ImageList 对象和m_List
 if (m_ImageList!=NULL)
 {
  for(int kk=0;kk<m_ImageList.GetImageCount();kk++)
   m_ImageList.Remove(kk);
  m_List.DeleteAllItems();
 }
 else
 {
  m_ImageList.Create(THUMWIDTH,THUMHEIGHT,   ILC_COLORDDB|ILC_MASK,   20,   1);    
  m_List.SetImageList(&m_ImageList, LVSIL_NORMAL);
  m_List.SetImageList(&m_ImageList, LVSIL_SMALL);
 }
 m_List.SetRedraw(false);
 CString   strDir=FilePath+_T("*.*");
 //strDir.Format("%s%s",FilePath,L"*.*");
 //_T("D://happiness//
风景桌面//*.*"); 
 
 int   i=0,cn=0,j=0;  
 SHFILEINFO   finfo;  
 CString fileName;
 CString filePath2;
 HANDLE hFind;
 WIN32_FIND_DATA fd ;
 hFind=::FindFirstFile((LPCTSTR)strDir,&fd);
 if(hFind==INVALID_HANDLE_VALUE)return;
 do  
 {      
  if ( !wcscmp(fd.cFileName, _T("."))  || !wcscmp(fd.cFileName, _T("..")))continue;
  if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)continue;
  fileName=fd.cFileName;
  filePath2=FilePath+fileName;
  i=fileName.Find(_T(".jpg"),0);
  //
加载jpg,jpeg,gif 格式的图片
  if (i==-1)
   i=fileName.Find(_T(".jpeg"),0);
  if (i==-1)
   i=fileName.Find(_T(".JPG"),0);
  if (i==-1)
   i=fileName.Find(_T(".JPEG"),0);
  if (i==-1)
   i=fileName.Find(_T(".gif"),0);
  if (i==-1)
   i=fileName.Find(_T(".GIF"),0);
  if (i==-1)
   i=fileName.Find(_T(".BMP"),0);
  if (i==-1)
   i=fileName.Find(_T(".bmp"),0);
  if (i!=-1)
  {
   //Creating thumbnail image for the file
   HBITMAP bitm=LoadPicture(filePath2);
   if (bitm!=NULL)
   {

    CBitmap*    pImage = NULL;
    pImage = new CBitmap();  
    pImage->Attach(bitm);
    int imgP=m_ImageList.Add(pImage,RGB(0,0,0));
    //Link to the added listview item
    m_List.InsertItem(cn,fileName,imgP);
   }
  }
  //
加载icon 图片
  i=fileName.Find(_T(".ico"),0);
  if (i==-1)
   i=fileName.Find(_T(".ICO"),0);
  if (i==-1)
   i=fileName.Find(_T(".rc"),0);
  if (i==-1)
   i=fileName.Find(_T(".rc2"),0);
  if (i!=-1)
  {
   ::SHGetFileInfo(filePath2,0,&finfo,sizeof(SHFILEINFO),SHGFI_ICON);  
   m_ImageList.Add(finfo.hIcon);//
加入图标 
   m_List.InsertItem(cn,fileName,cn);  
  } 
  cn++;  
 }while(::FindNextFile(hFind,&fd));
 FindClose(hFind);
 m_List.SetRedraw(true);
 Invalidate();
 UpdateWindow();
}


HBITMAP ListImage::LoadPicture(CString mFile)
{
 CString pFSize;
 WCHAR wpath[MAX_PATH];
// MultiByteToWideChar(CP_ACP, 0,lpszBuf, -1, wpath, MAX_PATH);
 IPicture* pPic;
 OleLoadPicturePath(T2OLE((LPTSTR)(LPCTSTR)mFile), 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);

 // Create Brushes for Border and BackGround
 HBRUSH hBrushBorder=::CreateSolidBrush(RGB(192, 192, 192));
 HBRUSH hBrushBk=::CreateSolidBrush(RGB(255, 255, 255));

 // Border Size
 RECT rcBorder;
 rcBorder.left=rcBorder.top=0;
 rcBorder.right=THUMWIDTH;
 rcBorder.bottom=THUMHEIGHT;

 const float fRatio=(float)THUMHEIGHT/THUMWIDTH;

 int XDest, YDest, nDestWidth, nDestHeight;
 // Calculate Rect to fit to canvas
 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);
 // Draw Background
 ::FillRect(hDC, &rcBorder, hBrushBk);

 // Draw Border
 ::FrameRect(hDC, &rcBorder, hBrushBorder);

 HBITMAP hBmReturn= (HBITMAP)::SelectObject(hDC, pOldBitmapImage);

 CDC hdcSrc, hdcDst;

 hdcSrc.CreateCompatibleDC(NULL);
 hdcDst.CreateCompatibleDC(NULL);

 // Load the bitmaps into memory DC
 CBitmap* hbmSrcT = (CBitmap*) hdcSrc.SelectObject(hPicRet);
 CBitmap* hbmDstT = (CBitmap*) hdcDst.SelectObject(hBmReturn);

 // This call sets up the mask bitmap.
 hdcDst.BitBlt(XDest,YDest,nDestWidth, nDestHeight, &hdcSrc,0,0,SRCCOPY);
 //hdcDst.StretchBlt(XDest,YDest,nDestWidth, nDestHeight, &hdcSrc,0,0,48,48,SRCCOPY);

 pOldBitmapImage = (HBITMAP)SelectObject(hdcDst.m_hDC,bm);

 // Release used DC and Object
 DeleteDC(hDC);
 DeleteObject(hBrushBorder);
 DeleteObject(hBrushBk);

 return pOldBitmapImage;

}

void ListImage::OnBnClickedOk()
{
 // TODO: Add your control notification handler code here
 OnOK();
}
----------------------------------------------------------------------------------------------------

ListImage.h 代码如下

#pragma once
#include "afxcmn.h"
#include "afxwin.h"


// ListImage dialog

class ListImage : public CDialog
{
 DECLARE_DYNAMIC(ListImage)

public:
 ListImage(CWnd* pParent = NULL);   // standard constructor
 virtual ~ListImage();
 CImageList m_ImageList;
 HBITMAP ListImage::LoadPicture(CString mFile);

// Dialog Data
 enum { IDD = IDD_DIALOG1 };

protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
 virtual BOOL OnInitDialog();
 DECLARE_MESSAGE_MAP()
public:
 afx_msg void OnBnClickedButton1();
 CListCtrl m_List;
 CEdit m_edit2;
 afx_msg void OnBnClickedOk();
};

 

  CXXXApp::InitInstance()
使用 ASSERT(AfxOleInit() != FALSE ); //Initialize COM libraries
m_List.SetBkImage("c:/background2.bmp");
m_List.SetTextBkColor(CLR_NONE); //
设置背景透明

首先将你的 CListCtrl 风格设置为ICON 风格

CImageList   m_ImageList;

CListCtrl     m_list;

m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);

m_list.SetIconSpacing(CSize(140, 130));      //set pictures spacing

//wide of picture is 120,height is 90

m_ImageList.Create(120,90,ILC_COLORDDB|ILC_COLOR32,1,1);

m_list.SetImageList(&m_ImageList,LVSIL_NORMAL);      //CImageList associates CListCtrl

// 此处用 GDI+,

Bitmap bmp( 文件的相对或绝路径 );                 // 传入图片路径

int sourceWidth = 120;                                             // 获得图片宽度, 这个120 和创建的120 保持相同。

int sourceHeight = bmp.GetHeight();                   // 获得图片宽度                                    

if(sourceHeight>120)              / / m_ImageList.Create(120 ) 有很大关系,如果小于设

                          // 定的宽度,图片将无法显示。

{

     sourceHeight=120;

}

else

{

     sourceHeight=bmp.GetHeight();

}

Bitmap* pThumbnail = (Bitmap*)bmp.GetThumbnailImage(sourceWidth , sourceHeight , NULL, NULL); // 设定缩略图的大小

HBITMAP hBmp;

pThumbnail->GetHBITMAP(Color(255,255,255),&hBmp);

CBitmap *pImage = CBitmap::FromHandle(hBmp);          // 转换成 CBitmap 格式位图

_wsplitpath(*photo_iter ,drive,dir,fname,ext );

wcscpy_s(itemName,fname);

wcscat_s(itemName,ext);

int a=m_imageList.Add(pImage,RGB(255,255, 255));

m_pictureList.InsertItem(a,itemName,a);                // itemName, 你自己设法得到图片片的名字。名字会显示在图片下面。

// 这里要注意,一定要用 InsertItem(a,itemName,a); 之前的 m_list 不需要在 insert(I,_T(””)); 更不需要 setItemText(item,subItem,Text), 这可能会导致插入相同的图片。

顺便说下 GDI 这个鬼东西,不懂原理,直接说应用。会用的高手见笑。 VS2008 自带了 gdi+ ,不需要下载。

1 .声明头文件,在 stdafx 中,或者能被你编译到其他地方都可以。

#include <gdiplus.h>               //GDI+ 声明,可以 GDI/GDI+ 混合使用

#pragma comment(lib, "gdiplus.lib")

using namespace Gdiplus;

2 .初始化 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();

}

当时这样做了后,我的 GDI+ 还是不能用,添加图片时候 Bitmap bmp( 文件的相对或绝路径 ); bmp 这个东西无效,里面有个空指针的东西,可见 GDI+ 并没有初始化。后来先,初始化 GDI+ 这段代码没有执行到。好了,那就把初始化的代码放到可以执行到的地方。

在主对话框的 InitInstance() 中添加

     // 初始化 GID+

     GdiplusStartupInput gdiplusStartupInput;       

     GdiplusStartup( &m_gdiplusToken,&gdiplusStartupInput,NULL );

好了, GDI+ 可以使用了,可以添加缩略图了。截图一张。

每行图片的数量随窗口大小自动排列。按下面设置属性。

CListCtrl 属性
Alignment
设置为 top
Auto Arrage
设置为 True.

如有疑问,请留言。

//ClimageList 无效的原因 1 creare 的大小; 2 ,如果是被重写的类,在 drawItem 重新绘制,不能在关联 CImageList

.h
CListCtrlCl             m_dataStatisticsList;
CImageList              m_DataImageList;

.cpp

        m_DataImageList.Create(44,30,ILC_COLOR24,2,2);
//bmp.Attach(tempBitmap);
bmp.LoadBitmap(IDB_CONTACT);
int a=m_DataImageList.Add(&bmp,RGB(255,255,255));
int b=m_DataImageList.GetImageCount();

m_dataStatisticsList.SetImageList(&m_DataImageList,LVSIL_SMALL);
for(int i=0;i<5;i++)
{
     m_dataStatisticsList.InsertItem(i,_T(""),0); //0
CImageList 的第一个图标。
}


分析:在 m_DataImageList.Add(&bmp,RGB(255,255,255)); 之后,得到的 CImageList 的元素数量 b 还为 0 ,原因可能在于 m_DataImageList.Create(44,30,ILC_COLOR24,2,2); 前两个参数图片的宽度和长度大于了图片本身,就会 add 失败。

add 成功后, b 将成为 1 但是 m_dataStatisticsList.InsertItem(i,_T(""),0); 还不见图片,插入的文字倒是没有问题。 这个原因在于 m_dataStatisticsList 是一个被重写的类 CListCtrlCl 的对象。在 CListCtrlCl 中的 drawItem 没有绘出图片。

 

 

CListCtrl MFC 的控件,所以只支持 HBITMAP 图片,这是我们可以将 iplimage* 转化成 HBITMAP;

   // 变量声明部分; // /// ///

   CListCtrl m_list;

   CImageList* m_pImgList;

   /// 初始化,将 bitmap 关联到 listctrl // //

   m_pImgList=new CImageList;

   m_pImgList->Create (200,200,ILC_COLOR32,20,20);// 前两个参数是设置图象大小的

   m_pImgList->SetBkColor(RGB(125,125,0));

   m_list.SetImageList(m_pImgList,0);// 将设置的位图列表选入 ListView 中去

   /// 打开对话框添加图片 // /// /

    char m_szFilter[] = "bmp files(*.bmp)|*.bmp|jpg files(*.jpg)|*.jpg|png files(*.png)|*.png|tiff files(*.tiff)|*.tiff|All files(*.*)|*.*||";

   CFileDialog fd(TRUE,NULL,NULL,OFN_FILEMUSTEXIST|OFN_HIDEREADON LY|OFN_ALLOWMULTISELECT,

   m_szFilter);

   BOOL nResult = (fd.DoModal() == IDOK) ? TRUE : FALSE;

   if (!nResult) // 点击 cancel

   {

   return;

   }

   // 把文件名称放到 CStringList

   POSITION pos = fd.GetStartPosition();

   while (pos)

   {

   CString currentFileName = fd.GetNextPathName(pos);

   //m_picNameList.AddTail(fileName);

   /* 显示位图文件 */

   HBITMAP hBitmap;

   CBitmap pBitmap;

   m_list.InsertItem(m_picNum, currentFileName, m_picNum);

   IplImage* image, *pImgGray;

   image = cvLoadImage(currentFileName,1); //IplImage2Bitmap

   hBitmap = IplImage2Bitmap(image);

   pBitmap.Attach ( hBitmap );

   m_pImgList->Add (&pBitmap, RGB(0,0,0));

   DeleteObject(hBitmap);

   pImgGray = cvCreateImage(cvGetSize(image),image->depth,1);

   cvCvtColor(image,pImgGray,CV_RGB2GRAY);

   m_lImgsList.push_back(pImgGray);

   cvReleaseImage( );

   // 增加图片数量

   m_picNum++;

   }

   // 删除 listctrl 中的图片 // ///

   // 获取被删除图片的位置

   POSITION pos = m_list.GetFirstSelectedItemPosition();

   if(pos == NULL)

   {

   // MessageBox(" 请选择一项在删除 !"," 提示 ",MB_ICONINFORMATION);

   return;

   }

   int currentIndex = m_list.GetNextSelectedItem(pos);

   m_list.DeleteItem(currentIndex);

   // 重画被删图片以后的项目

   //BOOL b = m_pImgList->Remove(currentIndex);

   m_list.RedrawItems(currentIndex, m_picNum);

   // 减少一张图片

   m_picNum--;

   // 注: clistctrl Auto Arrange 属性设为 ture ,这样,在删除图片的时候可以刷新(用后面的图像填充当前位置)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值