⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dirlistview.cpp

📁 c++系统开发实例精粹内附的80例源代码 环境:windows2000,c++6.0
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////
// FileFury
// Copyright (c) 2000 Tenebril Incorporated
// All rights reserved.
//
// This source code is governed by the Tenebril open source
// license (http://www.tenebril.com/developers/opensource/license.html)
//
// For more information on this and other open source applications,
// visit the Tenebril OpenSource page:
//       http://www.tenebril.com/developers/opensource
//
//////////////////////////////////////////////////////////////////////

// listview.cpp : implementation file
//

#include "stdafx.h"
//#include "mfcdrag.h"
#include "resource.h"

#include "Oscar.h"
#include "DirListView.h"
#include "DirTreeView.h"
#include "DirSplitter.h"

#include "MainFrm.h"
#include "ChildFrm.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDirListView

IMPLEMENT_DYNCREATE(CDirListView, CView)

CDirListView::CDirListView()
{
	m_pDragImage = NULL;
	m_strPath = "";
	m_pImgList[0] = m_pImgList[1] = NULL;
	m_bOwnsImgList[0] = m_bOwnsImgList[1] = false;
	m_iViewType = 0;
	m_iIconStyle = SHGFI_LARGEICON;
	m_iSortType = 0;                          // By name
	m_bHasFormattedColumns = FALSE;

	AllowReload(FALSE);
}

CDirListView::~CDirListView()
{
	// Make sure we stop any working child threads.
	StopUpdateIcons(TRUE);

	if(m_pDragImage)
		delete m_pDragImage;

	for(int i = 0; i < 2; i++)
	{
		if(m_bOwnsImgList[i] && m_pImgList[i])
		{
			m_pImgList[i]->Detach();
			delete m_pImgList[i];
			m_pImgList[i] = NULL;
		}
	}
}


BEGIN_MESSAGE_MAP(CDirListView, CView)
	//{{AFX_MSG_MAP(CDirListView)
	ON_WM_CREATE()
	ON_WM_SIZE()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_RBUTTONUP()
	//}}AFX_MSG_MAP
	ON_NOTIFY (LVN_BEGINDRAG, IDI_LIST, OnBeginDrag)
	ON_NOTIFY (LVN_BEGINRDRAG, IDI_LIST, OnBeginRDrag)
	ON_NOTIFY (NM_DBLCLK, IDI_LIST, OnItemDblClk)
	ON_NOTIFY (LVN_ENDLABELEDIT, IDI_LIST, OnEndLabelEdit)
	ON_NOTIFY (LVN_KEYDOWN, IDI_LIST, OnKeyDown)
	ON_NOTIFY (NM_RCLICK, IDI_LIST, OnRClick)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CDirListView drawing

void CDirListView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
}

/////////////////////////////////////////////////////////////////////////////
// CDirListView diagnostics

#ifdef _DEBUG
void CDirListView::AssertValid() const
{
	CView::AssertValid();
}

void CDirListView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDirListView message handlers

int CDirListView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// create CListCtrl
	VERIFY (m_List.Create (WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS | 
		LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_SINGLESEL, 
			CRect (0, 0, 0, 0), this, IDI_LIST));

	// Use the parent's filesystem
	CDirSplitter *pDirSplitter = (CDirSplitter *)GetParent();
	m_pFileSystem = pDirSplitter->m_pFileSystem;

	return 0;
}

void CDirListView::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
	// resize list to fill the whole view
	m_List.MoveWindow (0, 0, cx, cy);
}

// this function is called in response to an LVN_BEGINDRAG
void CDirListView::OnBeginDrag (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 = 10;  // 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 information.
	m_bDragging = TRUE;
	m_bDragShowMenu = FALSE;
	m_hDropItem = NULL;
	m_nDropIndex = -1;
	m_pDropWnd = &m_List;

	// Capture all mouse messages.
	SetCapture();
}

void CDirListView::OnMouseMove(UINT nFlags, CPoint point) 
{
	CView::OnMouseMove(nFlags, point);

	if (m_bDragging)
	{
		CPoint pt (point);
		int iNewDrop;
		HTREEITEM hNewDrop;

		pt.x -= m_cCursorOffset.x;
		pt.y -= m_cCursorOffset.y;

		ClientToScreen (&pt);
		// move the drag image
		VERIFY (m_pDragImage->DragMove (pt));

		// get the CWnd pointer of the window that is under the mouse cursor
		CWnd* pDropWnd = WindowFromPoint (pt);
		ASSERT (pDropWnd);
		// if we drag outside current window
		if (pDropWnd != m_pDropWnd)
		{
			// turn off hilight for drop target in tree control
			if (m_hDropItem)
			{
				((CTreeCtrl*)m_pDropWnd)->SelectDropTarget (NULL);
				m_hDropItem = NULL;
			}
			// turn off hilight for drop target in list control
			if (m_nDropIndex != -1)
			{
				CListCtrl* pList = (CListCtrl*)m_pDropWnd;
				VERIFY (pList->SetItemState (m_nDropIndex, 0, LVIS_DROPHILITED));
				// redraw item
				VERIFY (pList->RedrawItems (m_nDropIndex, m_nDropIndex));
				VERIFY (m_pDragImage->DragShowNolock (FALSE));
				pList->UpdateWindow ();
				VERIFY (m_pDragImage->DragShowNolock (TRUE));
				m_nDropIndex = -1;
			}
		}

		// save current window pointer
		m_pDropWnd = pDropWnd;

		// convert from screen coordinates to drop target client coordinates
		pDropWnd->ScreenToClient (&pt);

		// if window is CTreeCtrl
		if (pDropWnd->IsKindOf (RUNTIME_CLASS (CTreeCtrl)))
		{			
			UINT uFlags;
			// get the item that is below cursor
			hNewDrop = ((CTreeCtrl*)pDropWnd)->HitTest (pt, &uFlags);

			if(hNewDrop != m_hDropItem)
			{
				m_hDropItem = hNewDrop;

				// highlight it
				VERIFY (m_pDragImage->DragShowNolock (FALSE));
				((CTreeCtrl*)pDropWnd)->SelectDropTarget (m_hDropItem);
				VERIFY (m_pDragImage->DragShowNolock (TRUE));
			}
		}
		else if (pDropWnd->IsKindOf (RUNTIME_CLASS (CListCtrl)))
		{	
			UINT uFlags;
			CListCtrl* pList = (CListCtrl*)pDropWnd;
			CDirListView *pListView = (CDirListView *)pDropWnd->GetParent();

			// get the item that is below cursor
			iNewDrop = ((CListCtrl*)pDropWnd)->HitTest (pt, &uFlags);
			if(iNewDrop != m_nDropIndex)
			{
				// turn off hilight for previous drop target
				pList->SetItemState (m_nDropIndex, 0, LVIS_DROPHILITED);
				// redraw previous item
				pList->RedrawItems (m_nDropIndex, m_nDropIndex);

				if(pListView->ShouldHighlight(iNewDrop))
				{
					m_nDropIndex = iNewDrop;

					// highlight it
					pList->SetItemState (m_nDropIndex, LVIS_DROPHILITED, 
						LVIS_DROPHILITED);
					// redraw item
					pList->RedrawItems (m_nDropIndex, m_nDropIndex);
				}
				else
					m_nDropIndex = -1;

				VERIFY (m_pDragImage->DragShowNolock (FALSE));
				pList->UpdateWindow ();
				VERIFY (m_pDragImage->DragShowNolock (TRUE));
			}
		}
	}
}

void CDirListView::OnLButtonUp(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::OnLButtonUp(nFlags, point);
}

void CDirListView::OnRClick(NMHDR *pMessageHeader, 
							LRESULT *pResult)
{
	*pResult = 0;

	// Reflect so the parent can display the menus

	CWnd *pWnd = GetParent();
	if(!pWnd)                    // Splitter
		return;
	pWnd = pWnd->GetParent();
	if(!pWnd)                    // MDI child
		return;

	CMDIFrameWnd *pMDIFrame = ((CMDIChildWnd *)pWnd)->GetMDIFrame();
	if(!pMDIFrame)
		return;

	pMDIFrame->SendMessage(WM_RBUTTON_REFLECT, (WPARAM)(&m_List), 0);

	return;
}

// this function drops an item from a CListCtrl onto a CTreeCtrl
void CDirListView::DropItemOnTree (CTreeCtrl* pDropTree)
{
	ASSERT(pDropTree);

	// remove hilight from drop target
	pDropTree->SelectDropTarget (NULL);

	// Make sure we have a drop target.
	if(!m_hDropItem)
		return;

	// Make sure it's the tree of a DirView.
	CDirTreeView *pView = (CDirTreeView *)pDropTree->GetParent();
	ASSERT(pView);
	if(!pView->IsKindOf(RUNTIME_CLASS(CDirTreeView)))
	{
		ASSERT(0);
		return;
	}

	char szLabel[256];
	LV_ITEM lvi;

	ZeroMemory (&lvi, sizeof (LV_ITEM));
	lvi.iItem		= m_nDragIndex;
	lvi.mask		= TVIF_IMAGE | TVIF_TEXT;
	lvi.pszText		= szLabel;
	lvi.cchTextMax	= 255;
	// get item that was dragged
	VERIFY (m_List.GetItem (&lvi));

	// physically move the file
	int iSrcArray = (int)m_List.GetItemData(m_nDragIndex);
	CString cszSrc, cszDest;

	cszSrc = CString(m_cFileArray.GetFullName(iSrcArray));
	cszDest = pView->GetFullPath(m_hDropItem) + cszDest + CString(_T("\\"))
		+ 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;
	}

	// Physically move the file.
	TRACE(cszSrcMachine + _T(": ") + cszSrc + _T("\n"));
	TRACE(cszDstMachine + _T(": ") + cszDest + _T("\n"));

	COscarApp *pApp = (COscarApp *)AfxGetApp();
	ASSERT(pApp);
	if (pApp->TransferFile(cszSrc, cszSrcMachine,
			cszDest, cszDstMachine) == 2)
	{
		// delete the original item (move operation)
		VERIFY (m_List.DeleteItem (m_nDragIndex));

		// Update the tree.
		pView->AddItem(m_hDropItem, cszDest);
	}
}

void CDirListView::OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LV_DISPINFO FAR* pDispInfo = (LV_DISPINFO FAR *)pNMHDR;
	int iItem = pDispInfo->item.iItem;
	int iArray = (int)m_List.GetItemData(iItem);
	CString Temp;

	*pResult = 0;

	// If the user didn't change the name, we get NULL as the new
	// name; we must handle this case appropriately
	if(!pDispInfo->item.pszText)
		return;
	Temp = CString(pDispInfo->item.pszText);
	if(Temp.GetLength() == 0)
		return;

	// Physically move the file or directory
	CString OldFileName, NewFileName;

	OldFileName = GetFilePath(iItem);
	NewFileName = m_strPath;
	if(NewFileName.GetAt(NewFileName.GetLength() - 1) != _T('\\'))
		NewFileName = NewFileName + CString(_T("\\"));

	NewFileName = NewFileName + CString(pDispInfo->item.pszText);

	if(m_pFileSystem->MoveFile(OldFileName, NewFileName))
	{
		*pResult = 1;

		// Update the internals
		m_cFileArray.SetFullName(iArray, NewFileName);

		// If it's a directory, update the tree view.
		if(m_pFileSystem->IsDirectory(NewFileName))
		{
			CDirSplitter *pDirSplitter = (CDirSplitter *)GetParent();
			ASSERT(pDirSplitter);
			CDirTreeView *pTree = (CDirTreeView *)pDirSplitter->GetPane(0, 0);
			ASSERT(pTree);
			pTree->ReplaceDirectory(OldFileName, NewFileName);
		}
	}

	return;
}

void CDirListView::OnKeyDown(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LV_KEYDOWN FAR *lParam = (LV_KEYDOWN FAR *)pNMHDR;

	ASSERT(lParam);

	WORD wKey = lParam->wVKey;

	if(wKey == 46)     // Delete.
	{
		// Get the selected file.
		int iSel = SelectedID();
		if(iSel >= 0)
		{
			CString cszFileName = GetFilePath(iSel);

			// Store whether the file is a directory.
			BOOL bIsDir = m_pFileSystem->IsDirectory(cszFileName);

			// Delete the sucker.
			ASSERT(m_pFileSystem);
			if(m_pFileSystem->DeleteFile(cszFileName))
			{
				// Update the GUI.

				// TODO: Make this faster.
				CDirSplitter *pDirSplitter = (CDirSplitter *)GetParent();
				ASSERT(pDirSplitter);
				pDirSplitter->Refresh(FALSE);
				if(bIsDir)
				{
					CDirTreeView *pTreeView = 
						(CDirTreeView *)pDirSplitter->GetPane(0, 0);
					ASSERT(pTreeView);

					pTreeView->RemoveDirectory(cszFileName);
				}
			}
		}

		*pResult = 1;
	}
	else
	{
		// Default handlers.
		CView::OnKeyDown((UINT)wKey, (UINT)1, 0);
	}

	return;
}

// this function drops an item from a CListCtrl to a CListCtrl 
void CDirListView::DropItemOnList (CListCtrl* pDropList)
{
	ASSERT(pDropList);

	// unhilite the drop target
	if(m_nDropIndex >= 0)
		pDropList->SetItemState (m_nDropIndex, 0, LVIS_DROPHILITED);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -