www.pudn.com > 完整的FTP客户端ftpwanderersrc.zip > FTPListView.cpp
/****************************************************************/
/* */
/* FtpListView.cpp */
/* */
/* Implementation of the CFtpListView class. */
/* */
/* Programmed by Pablo van der Meer */
/* Copyright Pablo Software Solutions 2002 */
/* http://www.pablovandermeer.nl */
/* */
/* Last updated: 24 june 2002 */
/* */
/****************************************************************/
#include "stdafx.h"
#include "FtpWanderer.h"
#include "MainFrm.h"
#include "FtpWandererDoc.h"
#include "FtpListView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BOOL g_bSortAscending;
IMPLEMENT_DYNCREATE(CFtpListView, CListView)
BEGIN_MESSAGE_MAP(CFtpListView, CListView)
//{{AFX_MSG_MAP(CFtpListView)
ON_WM_CREATE()
ON_NOTIFY_REFLECT_EX(LVN_ENDLABELEDIT, OnEndlabeledit)
ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClick)
ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnDeleteitem)
ON_NOTIFY_REFLECT(LVN_BEGINLABELEDIT, OnBeginlabeledit)
ON_WM_SIZE()
ON_WM_CTLCOLOR()
ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
ON_WM_DROPFILES()
ON_NOTIFY_REFLECT(LVN_ODCACHEHINT, OnOdcachehint)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFtpListView construction/destruction
CFtpListView::CFtpListView()
{
m_nSortedCol = 0;
g_bSortAscending = TRUE;
m_bEditMode = FALSE;
m_bSearching = FALSE;
}
CFtpListView::~CFtpListView()
{
}
/********************************************************************/
/* */
/* Function name : OnDraw */
/* Description : Called by the framework to render an image of */
/* the document */
/* */
/********************************************************************/
void CFtpListView::OnDraw(CDC* pDC)
{
CFtpWandererDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
}
/********************************************************************/
/* */
/* Function name : OnInitialUpdate */
/* Description : Called by the framework after the view is first */
/* attached to the document, but before the view is */
/* initially displayed. */
/* */
/********************************************************************/
void CFtpListView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
// TODO: You may populate your ListView with items by directly accessing
// its list control through a call to GetListCtrl().
DragAcceptFiles();
}
/********************************************************************/
/* */
/* Function name : GetDocument */
/* Description : Get a pointer to the view抯 document. */
/* */
/********************************************************************/
#ifdef _DEBUG
CFtpWandererDoc* CFtpListView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFtpWandererDoc)));
return (CFtpWandererDoc*)m_pDocument;
}
#endif //_DEBUG
/********************************************************************/
/* */
/* Function name : OnStyleChanged */
/* Description : View style has been changed. */
/* */
/********************************************************************/
void CFtpListView::OnStyleChanged(int nStyleType, LPSTYLESTRUCT lpStyleStruct)
{
//TODO: add code to react to the user changing the view style of your window
}
/********************************************************************/
/* */
/* Function name : OnCreate */
/* Description : Called when window needs to be created. */
/* */
/********************************************************************/
int CFtpListView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListView::OnCreate(lpCreateStruct) == -1)
return -1;
GetListCtrl().ModifyStyle(0, LVS_EDITLABELS);
// column initialization
GetListCtrl().InsertColumn(0, "Name", LVCFMT_LEFT, 180);
GetListCtrl().InsertColumn(1, "Size", LVCFMT_RIGHT, 100);
GetListCtrl().InsertColumn(2, "Type", LVCFMT_LEFT, 100);
GetListCtrl().InsertColumn(3, "Created", LVCFMT_LEFT, 100);
// GetListCtrl().InsertColumn(4, "Attributes", LVCFMT_LEFT, 100);
// do not take ownership of the imagelist!
GetListCtrl().ModifyStyle(0, LVS_SHAREIMAGELISTS);
InitListViewImageLists();
return 0;
}
/********************************************************************/
/* */
/* Function name : OnBeginlabeledit */
/* Description : */
/* */
/********************************************************************/
void CFtpListView::OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
m_bEditMode = TRUE;
*pResult = 0;
}
/********************************************************************/
/* */
/* Function name : OnEndlabeledit */
/* Description : */
/* */
/********************************************************************/
BOOL CFtpListView::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
m_bEditMode = FALSE;
// route notification to CMainFrame !
return FALSE;
}
/********************************************************************/
/* */
/* Function name : AddItem */
/* Description : */
/* */
/********************************************************************/
int CFtpListView::AddItem(int nIndex, CFtpFileFind *pFileFind)
{
// Allocate a new ITEMINFO structure and initialize it with information about the item.
ITEMINFO* pItem;
try
{
pItem = new ITEMINFO;
}
catch(CMemoryException* e)
{
e->Delete();
return -1;
}
pItem->strFileName = pFileFind->GetFileName();
pItem->nFileSize = pFileFind->GetLength();
pFileFind->GetLastWriteTime(&pItem->ftLastWriteTime);
pItem->bIsDirectory = pFileFind->IsDirectory();
pItem->strType = pItem->bIsDirectory ? "Folder" : GetTypeName(pItem->strFileName);
int nImage = GetIconIndex(pItem->strFileName, pItem->bIsDirectory);
// Add the item to the list view.
LV_ITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
lvi.iItem = nIndex;
lvi.iSubItem = 0;
lvi.iImage = nImage;
lvi.pszText = LPSTR_TEXTCALLBACK;
lvi.lParam = (LPARAM) pItem;
return GetListCtrl().InsertItem(&lvi);
}
/********************************************************************/
/* */
/* Function name : AddNewFolder */
/* Description : Add new folder entry */
/* */
/********************************************************************/
int CFtpListView::AddNewFolder(int nIndex, LPCTSTR lpszFolder)
{
// Allocate a new ITEMINFO structure and initialize it with information about the item.
ITEMINFO* pItem;
try
{
pItem = new ITEMINFO;
}
catch(CMemoryException* e)
{
e->Delete();
return -1;
}
pItem->strFileName = lpszFolder;
pItem->nFileSize = 0;
SYSTEMTIME systemTime;
GetSystemTime(&systemTime);
::SystemTimeToFileTime(&systemTime, &pItem->ftLastWriteTime);
pItem->bIsDirectory = TRUE;
pItem->strType = "Folder";
int nImage = GetIconIndex(pItem->strFileName, pItem->bIsDirectory);
// Add the item to the list view.
LV_ITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
lvi.iItem = nIndex;
lvi.iSubItem = 0;
lvi.iImage = nImage;
lvi.pszText = LPSTR_TEXTCALLBACK;
lvi.lParam = (LPARAM) pItem;
return GetListCtrl().InsertItem(&lvi);
}
/********************************************************************/
/* */
/* Function name : AddNewFile */
/* Description : Add new file entry */
/* */
/********************************************************************/
int CFtpListView::AddNewFile(int nIndex, LPCTSTR lpszFileName, DWORD dwFileSize)
{
int nCount = GetListCtrl().GetItemCount();
for(int i=0; iDelete();
return -1;
}
pItem->strFileName = lpszFileName;
pItem->nFileSize = dwFileSize;
SYSTEMTIME systemTime;
GetSystemTime(&systemTime);
::SystemTimeToFileTime(&systemTime, &pItem->ftLastWriteTime);
pItem->bIsDirectory = FALSE;
pItem->strType = GetTypeName(pItem->strFileName);;
int nImage = GetIconIndex(pItem->strFileName, pItem->bIsDirectory);
// Add the item to the list view.
LV_ITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
lvi.iItem = nIndex;
lvi.iSubItem = 0;
lvi.iImage = nImage;
lvi.pszText = LPSTR_TEXTCALLBACK;
lvi.lParam = (LPARAM) pItem;
return GetListCtrl().InsertItem(&lvi);
}
/********************************************************************/
/* */
/* Function name : FreeItemMemory */
/* Description : Free memory that was allocated for list item. */
/* */
/********************************************************************/
void CFtpListView::FreeItemMemory()
{
int nCount = GetListCtrl().GetItemCount();
if(nCount)
{
for(int i=0; iitem.mask & LVIF_TEXT)
{
ITEMINFO* pItem =(ITEMINFO*) pDispInfo->item.lParam;
switch(pDispInfo->item.iSubItem)
{
case 0: // File name
::lstrcpy(pDispInfo->item.pszText, pItem->strFileName);
break;
case 1: // File size
if (pItem->bIsDirectory)
{
::lstrcpy(pDispInfo->item.pszText, "");
}
else
{
::lstrcpy(pDispInfo->item.pszText, FormatSize(pItem->nFileSize));
}
break;
case 2: // File type
::lstrcpy(pDispInfo->item.pszText, pItem->strType);
break;
case 3: // Date and time
CTime time(pItem->ftLastWriteTime);
BOOL pm = FALSE;
int nHour = time.GetHour();
if(nHour == 0)
nHour = 12;
else
if(nHour == 12)
pm = TRUE;
else
if(nHour > 12)
{
nHour -= 12;
pm = TRUE;
}
string.Format(_T("%d/%0.2d/%0.2d(%d:%0.2d%c)"),
time.GetMonth(), time.GetDay(), time.GetYear() % 100,
nHour, time.GetMinute(), pm ? _T('p') : _T('a'));
::lstrcpy(pDispInfo->item.pszText, string);
break;
}
}
*pResult = 0;
}
/********************************************************************/
/* */
/* Function name : OnColumnClick */
/* Description : */
/* */
/********************************************************************/
void CFtpListView::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView =(NM_LISTVIEW*) pNMHDR;
// User clicked on header using left mouse button
if(pNMListView->iSubItem == m_nSortedCol)
g_bSortAscending = !g_bSortAscending;
else
g_bSortAscending = TRUE;
m_nSortedCol = pNMListView->iSubItem;
GetListCtrl().SortItems(CompareFunc, pNMListView->iSubItem);
*pResult = 0;
}
/********************************************************************/
/* */
/* Function name : CompareFunc */
/* Description : */
/* */
/********************************************************************/
int CALLBACK CFtpListView::CompareFunc(LPARAM lParam1, LPARAM lParam2,LPARAM lParamSort)
{
ITEMINFO* pItem1 =(ITEMINFO*) lParam1;
ITEMINFO* pItem2 =(ITEMINFO*) lParam2;
int nResult;
switch(lParamSort)
{
case 0: // File name
if (pItem1->bIsDirectory && !pItem2->bIsDirectory)
return (g_bSortAscending ? -1 : 1);
if (!pItem1->bIsDirectory && pItem2->bIsDirectory)
return (g_bSortAscending ? 1 : -1);
nResult = pItem1->strFileName.CompareNoCase(pItem2->strFileName);
break;
case 1: // File size
if (pItem1->bIsDirectory && !pItem2->bIsDirectory)
return (g_bSortAscending ? -1 : 1);
if (!pItem1->bIsDirectory && pItem2->bIsDirectory)
return (g_bSortAscending ? 1 : -1);
nResult = pItem1->nFileSize - pItem2->nFileSize;
break;
case 2: // type
if (pItem1->bIsDirectory && !pItem2->bIsDirectory)
return -1;
if (!pItem1->bIsDirectory && pItem2->bIsDirectory)
return 1;
nResult = pItem1->strType.CompareNoCase(pItem2->strType);
break;
case 3: // Date and time
nResult = ::CompareFileTime(&pItem1->ftLastWriteTime, &pItem2->ftLastWriteTime);
break;
}
return (g_bSortAscending ? nResult : -nResult);
}
/********************************************************************/
/* */
/* Function name : GetTypeName */
/* Description : */
/* */
/********************************************************************/
char* CFtpListView::GetTypeName(CString strPath)
{
SHFILEINFO sfi;
memset(&sfi, 0, sizeof(sfi));
static char lpBuff[MAX_PATH];
lpBuff[0] = char ('\0');
SHGetFileInfo(strPath, 0, &sfi, sizeof(sfi), SHGFI_TYPENAME);
lstrcpy(lpBuff, sfi.szTypeName);
if (lpBuff[0] == char('\0'))
{
int nDotIdx = strPath.ReverseFind('.');
int nBSIdx = strPath.ReverseFind('\\');
if (nDotIdx > nBSIdx)
{
strPath = strPath.Mid(nDotIdx+1);
strPath.MakeUpper();
lstrcpy (lpBuff, strPath + ' ');
}
lstrcat (lpBuff, _T("File"));
}
return lpBuff;
}
/********************************************************************/
/* */
/* Function name : FormatSize */
/* Description : Format size, the way explorer diplays it */
/* */
/********************************************************************/
char* CFtpListView::FormatSize(DWORD dwSizeLow, DWORD dwSizeHigh)
{
static char szBuff[100];
unsigned __int64 nFileSize = ((unsigned __int64)(((DWORD)(dwSizeLow)) |
((unsigned __int64)((DWORD)(dwSizeHigh))) << 32));
unsigned __int64 kb = 1;
if (nFileSize > 1024)
{
kb = nFileSize / 1024;
if (nFileSize % 1024)
kb++;
}
// make it a string
_ui64tot(kb, szBuff, 10);
// add thousand seperators
int nLength = lstrlen(szBuff);
if (nLength > 3)
{
LPCTSTR ptr = szBuff;
ptr += (nLength-1);
char szTemp[100];
LPTSTR ptrTemp = szTemp;
for(int i=0; ibIsDirectory;
}
/********************************************************************/
/* */
/* Function name : GetFileSize */
/* Description : Get size of selected file */
/* */
/********************************************************************/
DWORD CFtpListView::GetFileSize(int nItem)
{
return ((ITEMINFO*)GetListCtrl().GetItemData(nItem))->nFileSize;
}
/********************************************************************/
/* */
/* Function name : GetLastWriteTime */
/* Description : */
/* */
/********************************************************************/
FILETIME CFtpListView::GetLastWriteTime(int nItem)
{
return ((ITEMINFO*)GetListCtrl().GetItemData(nItem))->ftLastWriteTime;
}
/********************************************************************/
/* */
/* Function name : OnDeleteitem */
/* Description : Delete allocated item data */
/* */
/********************************************************************/
void CFtpListView::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
delete(ITEMINFO*) GetListCtrl().GetItemData(pNMListView->iItem);
*pResult = 0;
}
/********************************************************************/
/* */
/* Function name : Sort */
/* Description : Call sort function */
/* */
/********************************************************************/
void CFtpListView::Sort(int nCol)
{
GetListCtrl().SortItems(CompareFunc, (nCol != -1) ? nCol : m_nSortedCol);
}
/********************************************************************/
/* */
/* Function name : InitListViewImageLists */
/* Description : Use system imagelist for the file icons */
/* */
/********************************************************************/
BOOL CFtpListView::InitListViewImageLists()
{
HIMAGELIST himlSmall;
HIMAGELIST himlLarge;
SHFILEINFO sfi;
himlSmall = (HIMAGELIST) SHGetFileInfo ((LPCSTR) "C:\\",
0, &sfi, sizeof (SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
himlLarge = (HIMAGELIST) SHGetFileInfo ((LPCSTR) "C:\\",
0, &sfi, sizeof (SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
if (himlSmall && himlLarge)
{
::SendMessage(GetListCtrl().m_hWnd, LVM_SETIMAGELIST, (WPARAM)LVSIL_SMALL, (LPARAM)himlSmall);
::SendMessage(GetListCtrl().m_hWnd, LVM_SETIMAGELIST, (WPARAM)LVSIL_NORMAL, (LPARAM)himlLarge);
return TRUE;
}
return FALSE;
}
/********************************************************************/
/* */
/* Function name : SetFileName */
/* Description : Set filename (after renaming) */
/* */
/********************************************************************/
void CFtpListView::SetFileName(int nIndex, LPCTSTR lpszFileName)
{
((ITEMINFO*)GetListCtrl().GetItemData(nIndex))->strFileName = lpszFileName;
GetListCtrl().SetItemText(nIndex, 0, lpszFileName);
}
/********************************************************************/
/* */
/* Function name : IsEditing */
/* Description : Is listview in edit mode ? */
/* */
/********************************************************************/
BOOL CFtpListView::IsEditing()
{
return m_bEditMode;
}
/********************************************************************/
/* */
/* Function name : PreTranslateMessage */
/* Description : Prevent accelerator keys to be executed while */
/* in edit mode. */
/* */
/********************************************************************/
BOOL CFtpListView::PreTranslateMessage(MSG* pMsg)
{
if(m_bEditMode)
{
if((pMsg->message >= WM_KEYFIRST) && (pMsg->message <= WM_KEYLAST))
{
TranslateMessage(pMsg);
DispatchMessage(pMsg);
return TRUE;
}
}
return CListView::PreTranslateMessage(pMsg);
}
/********************************************************************/
/* */
/* Function name : ActivateAnimation */
/* Description : Switch search on/off. */
/* */
/********************************************************************/
void CFtpListView::ActivateAnimation(BOOL bOn)
{
if (bOn)
{
// control is already created
if (IsWindow(m_AnimateCtrl.m_hWnd))
return;
CRect rc;
GetClientRect(rc);
// create animation control
if (m_AnimateCtrl.Create(WS_CHILD | ACS_CENTER | ACS_TRANSPARENT | ACS_AUTOPLAY, rc, this, 88))
{
// switch off redraw of listview to prevent flickering
GetListCtrl().SetRedraw(FALSE);
// load animation
m_AnimateCtrl.Open(IDR_AVI3);
// show animation
m_AnimateCtrl.ShowWindow(SW_SHOW);
m_bSearching = TRUE;
}
}
else
{
m_bSearching = FALSE;
if (IsWindow(m_AnimateCtrl.m_hWnd))
{
// stop animation
m_AnimateCtrl.Stop();
// hide animation
m_AnimateCtrl.ShowWindow(SW_HIDE);
// switch on redraw of listview
GetListCtrl().SetRedraw(TRUE);
// destroy animation control
m_AnimateCtrl.PostMessage(WM_CLOSE);
}
}
}
/********************************************************************/
/* */
/* Function name : OnSize */
/* Description : If search animation is active resize it. */
/* */
/********************************************************************/
void CFtpListView::OnSize(UINT nType, int cx, int cy)
{
CListView::OnSize(nType, cx, cy);
if (IsWindow(m_AnimateCtrl.m_hWnd))
{
m_AnimateCtrl.MoveWindow(0, 0, cx, cy);
Invalidate();
UpdateWindow();
}
}
/********************************************************************/
/* */
/* Function name : OnCtlColor */
/* Description : Make search animation look good. */
/* */
/********************************************************************/
HBRUSH CFtpListView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CListView::OnCtlColor(pDC, pWnd, nCtlColor);
UINT id = pWnd->GetDlgCtrlID();
// change background color of animation
if (id == 88)
{
pDC->SetBkColor(GetSysColor(COLOR_WINDOW));
return (HBRUSH)GetSysColorBrush(COLOR_WINDOW);
}
return hbr;
}
/********************************************************************/
/* */
/* Function name : OnRclick */
/* Description : Show context menu. */
/* */
/********************************************************************/
void CFtpListView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult)
{
CMenu menu;
POINT pt;
GetCursorPos(&pt);
// get selected item
int nIndex = GetListCtrl().GetNextItem(-1, LVNI_ALL | LVNI_SELECTED);
if (nIndex != -1)
{
if (IsDirectory(nIndex))
menu.LoadMenu(MAKEINTRESOURCE(IDR_FOLDERPOPUP));
else
menu.LoadMenu(MAKEINTRESOURCE(IDR_FILEPOPUP));
}
else
{
menu.LoadMenu(MAKEINTRESOURCE(IDR_LISTPOPUP));
}
menu.GetSubMenu(0)->TrackPopupMenu(0, pt.x, pt.y, AfxGetMainWnd(), NULL);
*pResult = 0;
}
/********************************************************************/
/* */
/* Function name : OnDropFiles */
/* Description : Files have been dropped on the listview. */
/* */
/********************************************************************/
void CFtpListView::OnDropFiles(HDROP hDropInfo)
{
char szFileName[_MAX_PATH];
// determine how many files are dropped
UINT nCount = DragQueryFile(hDropInfo, -1, NULL, 0);
for(UINT i=0; i < nCount; i++)
{
// get the filename
DragQueryFile(hDropInfo, i, szFileName, _MAX_PATH);
CString strDropName = szFileName;
// check if it a directory
if ((GetFileAttributes(szFileName) & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
{
// enumerate directory structure and add everything to queue
CStringArray strFileNames;
CString strFileName, strSize, strPath, strDestination;
RecursiveFileList(szFileName, strFileNames);
// queue all found files
for (int i = 0; i < strFileNames.GetSize(); i++)
{
AfxExtractSubString(strFileName, strFileNames.GetAt(i), 0, '|');
AfxExtractSubString(strPath, strFileNames.GetAt(i), 1, '|');
// fix path
int nPos = strDropName.ReverseFind('\\');
if (nPos != -1)
{
strDropName = strDropName.Left(nPos+1);
}
strDestination = strPath;
int nLength = strDropName.GetLength();
strDestination = strDestination.Mid(nLength);
strDestination.Replace('\\', '/');
((CMainFrame *)AfxGetMainWnd())->UploadFile(strPath + "\\" + strFileName, strDestination + "/" + strFileName);
}
}
else
{
int nPos = strDropName.ReverseFind('\\');
if (nPos != -1)
{
((CMainFrame *)AfxGetMainWnd())->UploadFile(strDropName, strDropName.Mid(nPos+1));
}
}
}
CListView::OnDropFiles(hDropInfo);
}
/********************************************************************/
/* */
/* Function name : RecursiveFileList */
/* Description : Recursively walk through directory to be able to */
/* upload complete directory structure. */
/* */
/********************************************************************/
void CFtpListView::RecursiveFileList(LPCTSTR lpszPath, CStringArray &strFileNameArray)
{
CFileFind fileFind;
CStringArray strDirectoryArray;
// add directory (without filename), so we can create the directory structure later
CString strFileName;
strFileName.Format("|%s", lpszPath);
strFileNameArray.Add(strFileName);
BOOL bContinue = fileFind.FindFile(CString(lpszPath) + "\\*.*");
if (!bContinue)
{
// the directory is empty; just close up and return.
fileFind.Close();
return;
}
// add all files in lpszPath
while (bContinue)
{
bContinue = fileFind.FindNextFile();
if (fileFind.IsDots())
continue;
if (fileFind.IsDirectory())
{
strDirectoryArray.Add(fileFind.GetFileName());
}
else
{
strFileName.Format("%s|%s", fileFind.GetFileName(), lpszPath);
strFileNameArray.Add(strFileName);
}
}
fileFind.Close();
// get contains of directories
for (int i = 0; i < strDirectoryArray.GetSize(); i++)
{
RecursiveFileList(CString(lpszPath) + "\\" + strDirectoryArray.GetAt(i), strFileNameArray);
}
}
void CFtpListView::OnOdcachehint(NMHDR* pNMHDR, LRESULT* pResult)
{
NMLVCACHEHINT* pCacheHint = (NMLVCACHEHINT*)pNMHDR;
// TODO: Add your control notification handler code here
*pResult = 0;
}