首页 > 其他分享 >过年回家,走之前留一个用GDI+实现的略缩图控件

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

时间:2022-12-13 18:02:33浏览次数:43  
标签:控件 CompareNoCase 缩图 TEXT CListImageCtrl strExt GDI VectorImageNames THUMBNAIL


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


过年回家,走之前留一个用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();

 

 


标签:控件,CompareNoCase,缩图,TEXT,CListImageCtrl,strExt,GDI,VectorImageNames,THUMBNAIL
From: https://blog.51cto.com/u_15911341/5934959

相关文章

  • 图片浏览控件。。
    代码暂时不上传。看看图片得了、图片可以进行各种操作......
  • Gdiplus-Lock up your bits
    TheBitmapclassprovidesthe LockBits andcorresponding UnlockBits methodswhichenableyoutofixaportionofthebitmappixeldataarrayinmemory,acc......
  • 改变ComboBox控件的高度
      非常简单, CComboBox*  pCtl =(CComboBox*)GetDlgItem(IDC_CBCOLORPICKER);  pCtl->SendMessage(CB_SETITEMHEIGHT,(WPARAM)-1,(LPARAM)18);  //改变控件本......
  • GDI+不同的地方
    研究了GDI+处理图像的地方,发现它一些与众不同的地方,被它坑了一天。。。。。   1、GDI+的像素的原点默认你在左下角的,所以读取像素的顺序是从最低一行开始的(bottom-l......
  • BreadCrumb控件
      BreadCrumb控件,如上图所示,即面包屑导航控件,类似于TreeCtrl,但不是一次显示所有的Item,VC++2010可以编译通过,稍微修改一下其他的也可以编译,源samplecode//m_Breadc......
  • GDIPlus灰度化图像
    将RGB彩色图像转为8位的索引颜色先定义一个宏//Greyscaleconversion#defineGREY(r,g,b)(BYTE)(((WORD)r*77+(WORD)g*150+(WORD)b*29)>>8//#defineGREY......
  • Winform DevExpress控件库(三) 使用NavBarControl控件定制导航栏
    NavBarControl控件:主要作用是制作包含多个选项组并且每个组里包含多个子选项的导航栏;位于工具箱->Navigation&Layout(导航栏与布局类控件)在工具箱输入名称NavBarControl......
  • WTL for MFC Programmers, Part IX - GDI Classes, Common Dialogs, and Utility Clas
    WTLforMFCProgrammers,PartIX-GDIClasses,CommonDialogs,andUtilityClasses Downloaddemoproject-157KBContentsIntroductionGDIWrap......
  • Element组件:el-date-picker日期选择控件少一天的问题
    在使用el-data-picker时,选择的日期和存入的日期差了一天。这个是由于element-ui中时间控件的默认时间为国际标准时间,因此与北京时间差8个小时,且value-format格式错误。正......
  • QT中LineEdit TextEdit PlainTextEdit 这三个控件有什么区别,分别用在什么情况下呢。
    QT中LineEdit、TextEdit、PlainTextEdit这三个控件区别为:输入内容不同、用途不同、限制行数不同。一、输入内容不同1、LineEdit:LineEdit的输入内容为单行文本输入。2、T......