📄 dirlistview.cpp
字号:
// First, make sure it's the list of a DirView.
CDirListView *pView = (CDirListView *)pDropList->GetParent();
ASSERT(pView);
if(!pView->IsKindOf(RUNTIME_CLASS(CDirListView)))
{
ASSERT(0);
return;
}
char szLabel[256];
LV_ITEM lvi;
ZeroMemory (&lvi, sizeof (LV_ITEM));
lvi.iItem = m_nDragIndex;
lvi.mask = LVIF_IMAGE | LVIF_TEXT;
lvi.pszText = szLabel;
lvi.cchTextMax = 255;
// get item that was dragged
VERIFY (m_List.GetItem (&lvi));
// Get the destination.
CString cszDest;
if(m_nDropIndex >= 0)
cszDest = pView->GetDestination(m_nDropIndex);
else
cszDest = pView->GetCurrentDirectory();
// Get the source.
int iSrcArray = (int)m_List.GetItemData(m_nDragIndex);
CString cszSrc;
cszSrc = CString(m_cFileArray.GetFullName(iSrcArray));
if(cszDest.GetLength() > 0)
{
if(cszDest.GetAt(cszDest.GetLength() - 1) != _T('\\'))
cszDest += _T('\\');
}
cszDest += CString(m_pFileSystem->GetSubPath(cszSrc));
// Get the source and destination machines.
CString cszSrcMachine = GetMachineName();
CString cszDstMachine = pView->GetMachineName();
// If we've done a right-drag, show the menu.
if(m_bDragShowMenu)
{
// Get the frame.
CWnd *pWnd = GetParent();
if(!pWnd) // Splitter
return;
pWnd = pWnd->GetParent();
if(!pWnd) // MDI child
return;
CMDIFrameWnd *pMDIFrame = ((CMDIChildWnd *)pWnd)->GetMDIFrame();
if(!pMDIFrame)
return;
ASSERT(pMDIFrame->IsKindOf(RUNTIME_CLASS(CMainFrame)));
CMainFrame *pMainFrame = (CMainFrame *)pMDIFrame;
pMainFrame->SetRightDragInfo(cszSrcMachine, cszSrc,
cszDstMachine, cszDest);
pMainFrame->SendMessage(WM_RDROP_REFLECT, (WPARAM)(&m_List), 0);
return;
}
// Get the app.
COscarApp *pApp = (COscarApp *)AfxGetApp();
ASSERT(pApp);
if (pApp->TransferFile(cszSrc, cszSrcMachine, // Physically move the file.
cszDest, cszDstMachine) == 2)
{
// It was a successful local-local transfer. We can
// update the GUI ourselves.
// delete the original item (move operation)
VERIFY (m_List.DeleteItem (m_nDragIndex));
// Update the tree if necessary.
if(m_pFileSystem->IsDirectory(cszDest))
{
// Get the tree.
CDirSplitter *pDirSplitter = (CDirSplitter *)GetParent();
ASSERT(pDirSplitter);
CDirTreeView *pTree = (CDirTreeView *)pDirSplitter->GetPane(0, 0);
pTree->DisplayTree(NULL);
pTree->SetSelPath(m_strPath);
}
}
}
void CDirListView::OnItemDblClk(NMHDR *pMessageHeader,
LRESULT *pResult)
{
int iSel;
// Get selected (or focused) item
iSel = m_List.GetNextItem(-1, LVNI_ALL | LVNI_SELECTED);
if(iSel == -1)
iSel = m_List.GetNextItem(-1, LVNI_ALL | LVNI_FOCUSED);
if(iSel > -1)
{
int iArray;
CString strPath; // We have to save a copy; the
// original may be freed when
// changing directories
iArray = (int)m_List.GetItemData(iSel);
strPath = CString(m_cFileArray.GetFullName(iArray));
ExecuteFile(strPath);
}
*pResult = (LRESULT)(TRUE);
return;
}
BOOL CDirListView::DisplayList(LPCTSTR strPath, BOOL bForceUpdate)
{
// Display the DirTree with the Rootname e.g. C:\
// if Rootname == NULL then Display all Drives on this PC
// First, we need the system-ImageList
// No redundancies
if(!bForceUpdate)
{
if(m_strPath == CString(strPath) ||
m_strPath + CString(_T("\\")) == CString(strPath))
return FALSE;
}
CString strCheckLen = strPath;
if(strCheckLen.GetLength() == 0)
return FALSE;
m_strPath = strPath;
// Stop any ongoing directory updates.
// This must be here; we're about to modify
// memory used by the update thread.
StopUpdateIcons(TRUE);
m_List.DeleteAllItems();
m_cFileArray.Clear();
if ( !GetSysImgList() )
return FALSE;
if(m_strPath.Right(1) != '\\')
m_strPath += "\\";
if(!m_bAllowReload) return FALSE;
DisplayPath(strPath);
return TRUE;
}
/////////////////////////////////////////////////
BOOL CDirListView::GetSysImgList()
/////////////////////////////////////////////////
{
SHFILEINFO shFinfo;
HIMAGELIST hImgList = NULL;
int i;
for(i = 0; i < 2; i++)
{
if(i == 0)
hImgList = (HIMAGELIST)SHGetFileInfo( "C:\\",
0, &shFinfo, sizeof( shFinfo ),
SHGFI_SYSICONINDEX | SHGFI_SMALLICON );
else
hImgList = (HIMAGELIST)SHGetFileInfo( "C:\\",
0, &shFinfo, sizeof( shFinfo ),
SHGFI_SYSICONINDEX | SHGFI_LARGEICON );
if ( !hImgList )
{
m_strError = "Cannot retrieve the Handle of SystemImageList!";
return FALSE;
}
if(CImageList::FromHandlePermanent(hImgList) != NULL)
{
// We've already taken the system image list and attached an
// object to it; steal the object
m_pImgList[i] = CImageList::FromHandlePermanent(hImgList);
}
else
{
m_pImgList[i] = new CImageList;
if ( !m_pImgList[i]->Attach( hImgList ) )
{
m_strError = "Cannot Attach SystemImageList-Handle";
return FALSE;
}
m_bOwnsImgList[i] = true;
// Now get the shared folder and unknown icon.
COscarApp *pApp = (COscarApp *)AfxGetApp();
// Get the icon image directory.
CString cszImageDir = pApp->m_cszProgDirectory + _T("\\images\\");
// The shared folders.
if(SHGetFileInfo( cszImageDir + _T("sfolder.ico"), 0, &shFinfo,
sizeof( shFinfo ), SHGFI_ICON | SHGFI_SMALLICON ))
pApp->m_nShareFolderIcon[SFI_CLOSED] = shFinfo.iIcon;
else
pApp->m_nShareFolderIcon[SFI_CLOSED] = 0;
if(SHGetFileInfo( cszImageDir + _T("sfoldero.ico"), 0, &shFinfo,
sizeof( shFinfo ), SHGFI_ICON | SHGFI_SMALLICON ))
pApp->m_nShareFolderIcon[SFI_OPEN] = shFinfo.iIcon;
else
pApp->m_nShareFolderIcon[SFI_OPEN] = 0;
// The unknown files.
if(SHGetFileInfo( cszImageDir + _T("snknw.ico"), 0, &shFinfo,
sizeof( shFinfo ), SHGFI_ICON | SHGFI_SMALLICON ))
pApp->m_nUnknownIcon[SFI_CLOSED] = shFinfo.iIcon;
else
pApp->m_nUnknownIcon[SFI_CLOSED] = 0;
// The shared folders.
if(SHGetFileInfo( cszImageDir + _T("lsfolder.ico"), 0, &shFinfo,
sizeof( shFinfo ), SHGFI_ICON | SHGFI_LARGEICON ))
pApp->m_nShareFolderIcon[SFI_LARGE] = shFinfo.iIcon;
else
pApp->m_nShareFolderIcon[SFI_LARGE] = 0;
// The unknown files.
if(SHGetFileInfo( cszImageDir + _T("lnknw.ico"), 0, &shFinfo,
sizeof( shFinfo ), SHGFI_ICON | SHGFI_LARGEICON ))
pApp->m_nUnknownIcon[SFI_LARGE] = shFinfo.iIcon;
else
pApp->m_nUnknownIcon[SFI_LARGE] = 0;
}
if(i == 0)
m_List.SetImageList( m_pImgList[i], LVSIL_SMALL );
else
m_List.SetImageList( m_pImgList[i], LVSIL_NORMAL );
}
return TRUE;
}
void CDirListView::DisplayPath(LPCTSTR strPath)
{
CString strPathFiles = strPath;
BOOL bFind;
// Show the wait cursor.
CWaitCursor waitCursor;
if(strPathFiles.CompareNoCase(_T("C:\\Recycled")) == 0)
strPathFiles = m_pFileSystem->GetRecycleDirectory();
if(strPathFiles.Right(1) != "\\")
strPathFiles += "\\";
strPathFiles += "*.*";
bFind = m_pFileSystem->FindFile(strPathFiles);
CWaitCursor wait;
while ( bFind )
{
bFind = m_pFileSystem->FindNextFile();
if(!m_pFileSystem->IsDots())
AddItem( m_pFileSystem->GetFilePath() );
}
// Start the new update.
UpdateIcons();
return;
}
int CDirListView::AddItem(LPCTSTR strPath)
{
// Adding the Item to the ListCtrl with the current Icons
int iArrayIndex;
CString cszPath = strPath;
// Don't allow blank paths.
if(cszPath.GetLength() < 1)
return -1;
// Make sure we don't add the Recycle Bin; this causes complications
// (for now)
if(m_pFileSystem->IsRecycleBin(cszPath))
return -1;
iArrayIndex = m_cFileArray.Add(cszPath);
// That's all we need to do; the parallel Update thread will
// actually insert the file.
return iArrayIndex;
}
LPCTSTR CDirListView::GetSubPath(LPCTSTR strPath)
{
//
// getting the last SubPath from a PathString
// e.g. C:\temp\readme.txt
// the result = readme.txt
static CString strTemp;
int iPos;
strTemp = strPath;
if ( strTemp.Right(1) == '\\' )
strTemp.SetAt( strTemp.GetLength() - 1, '\0' );
iPos = strTemp.ReverseFind( '\\' );
if ( iPos != -1 )
strTemp = strTemp.Mid( iPos + 1);
return (LPCTSTR)strTemp;
}
LPCTSTR CDirListView::GetCurrentDirectory()
{
return (LPCTSTR)m_strPath;
}
LPCTSTR CDirListView::GetFilePath(int iIndex)
{
ASSERT(iIndex >= 0);
if(iIndex < 0) return NULL;
int iArray = (int)m_List.GetItemData(iIndex);
return m_cFileArray.GetFullName(iArray);
}
int CDirListView::SelectedID()
{
int iSel;
// Get selected item
iSel = m_List.GetNextItem(-1, LVNI_ALL | LVNI_SELECTED);
return iSel;
}
void CDirListView::AllowReload(BOOL bAllow)
{
m_bAllowReload = bAllow;
}
CString CDirListView::GetDestination(int iIndex)
{
int iDstArray = (int)m_List.GetItemData(iIndex);
CString cszDest;
cszDest = CString(m_cFileArray.GetFullName(iDstArray));
return cszDest;
}
CString CDirListView::GetMachineName()
{
CWnd *pWnd = GetParent();
if(!pWnd) // Splitter
return _T("");
pWnd = pWnd->GetParent();
if(!pWnd) // MDI child
return _T("");
CChildFrame *pMDI = (CChildFrame *)pWnd;
return pMDI->GetMachineName();
}
BOOL CDirListView::SelectEdit(LPCTSTR czFile)
{
if(!czFile) return FALSE;
CString cszFile = czFile;
for(int i = 0; i < m_List.GetItemCount(); i++)
{
CString cszPath = GetFilePath(i);
if(cszPath.CompareNoCase(cszFile) == 0)
{
// Select the file.
VERIFY (m_List.SetItemState(i, LVIS_SELECTED, LVIF_STATE));
// Open the edit.
VERIFY (m_List.EnsureVisible(i, FALSE));
return (m_List.EditLabel(i) != NULL);
}
}
return FALSE;
}
int CDirListView::GetViewType()
{
return m_iViewType;
}
int CDirListView::GetArrangeType()
{
return m_iSortType;
}
void CDirListView::OnRButtonUp(UINT nFlags, CPoint point)
{
if (m_bDragging)
{
// release mouse capture
VERIFY (::ReleaseCapture ());
m_bDragging = FALSE;
// end dragging
VERIFY (m_pDragImage->DragLeave (GetDesktopWindow ()));
m_pDragImage->EndDrag ();
CPoint pt (point);
ClientToScreen (&pt);
// get the CWnd pointer of the window that is under the mouse cursor
CWnd* pDropWnd = WindowFromPoint (pt);
ASSERT (pDropWnd);
// if window is CTreeCtrl
if (pDropWnd->IsKindOf (RUNTIME_CLASS (CTreeCtrl)) && m_hDropItem)
DropItemOnTree ((CTreeCtrl*)pDropWnd);
// if window is CListCtrl
else if (pDropWnd->IsKindOf (RUNTIME_CLASS (CListCtrl)))
DropItemOnList ((CListCtrl*)pDropWnd);
}
CView::OnRButtonUp(nFlags, point);
}
void CDirListView::OnBeginRDrag(NMHDR * pnmhdr, LRESULT * pResult)
{
// save the index of the item being dragged in m_nDragIndex
m_nDragIndex = ((NM_LISTVIEW *)pnmhdr)->iItem;
POINT pt;
pt.x = 8;
pt.y = 8;
// create a drag image
if(m_pDragImage)
delete m_pDragImage;
m_pDragImage = m_List.CreateDragImage (m_nDragIndex, &pt);
ASSERT (m_pDragImage);
// changes the cursor to the drag image (DragMove() is still required in
// OnMouseMove())
IMAGEINFO imgInfo;
VERIFY (m_pDragImage->GetImageInfo(0, &imgInfo) );
m_cCursorOffset.x = imgInfo.rcImage.right / 4;
m_cCursorOffset.y = imgInfo.rcImage.bottom / 6;
VERIFY (m_pDragImage->BeginDrag (0, CPoint (m_cCursorOffset.x, m_cCursorOffset.y)));
VERIFY (m_pDragImage->DragEnter (GetDesktopWindow (), ((NM_LISTVIEW *)pnmhdr)->ptAction));
// set dragging flag
m_bDragging = TRUE;
m_bDragShowMenu = TRUE;
m_hDropItem = NULL;
m_nDropIndex = -1;
m_pDropWnd = &m_List;
// capture all mouse messages
SetCapture ();
}
BOOL CDirListView::BrushRefresh()
{
// Loop over all items in the view, removing any that don't exist.
for(int i = 0; i < m_List.GetItemCount(); i++)
{
CString cszPath = GetFilePath(i);
ASSERT(m_pFileSystem);
if(m_pFileSystem->GetFileModificationTime(cszPath) == 0)
{
// Delete this item; it's moved.
m_List.DeleteItem(i);
i -= 1;
}
}
return TRUE;
}
BOOL CDirListView::DownloadFile(LPCTSTR czName)
{
// Get the app.
COscarApp *pApp = (COscarApp *)AfxGetApp();
ASSERT(pApp);
ASSERT(m_pFileSystem);
// Find the transfer destination.
CSettingsArchive *pArchive = pApp->GetArchive();
ASSERT(pArchive);
CString cszDownloadDir = pArchive->m_arch1.czDownloadDir;
// Set the destination file name.
CString cszDest;
cszDest = m_pFileSystem->GetSubPath(czName);
if(cszDownloadDir.GetLength() < 1) return FALSE;
if(cszDownloadDir.GetAt(cszDownloadDir.GetLength() - 1) != _T('\\'))
cszDownloadDir += _T('\\');
cszDest = cszDownloadDir + cszDest;
// Get the source.
CString cszSrc = czName;
// Get the source and destination machines.
CString cszSrcMachine = GetMachineName();
CString cszDstMachine = _T("127.0.0.1");
// Send the transfer to the app.
return (pApp->TransferFile(cszSrc, cszSrcMachine,
cszDest, cszDstMachine) > 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -