📄 explorerlistview.cpp
字号:
// ExplorerListView.cpp : implementation file
//
#include "stdafx.h"
#include "CMyExplorer.h"
#include "ExplorerListView.h"
#include "ShellContextMenu.h"
#include "ExplorerTreeView.h"
#include "ShellFileOp.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CExplorerListView * g_ListView = NULL;
extern CExplorerTreeView * g_TreeView;
/////////////////////////////////////////////////////////////////////////////
// CExplorerListView
IMPLEMENT_DYNCREATE(CExplorerListView, CListView)
CExplorerListView::CExplorerListView()
{
m_pListCtrl = &GetListCtrl();
m_dViewType = LVS_LIST;
g_ListView = this;
}
CExplorerListView::~CExplorerListView()
{
// m_pListCtrl->SetImageList(NULL,LVSIL_SMALL);
// m_pListCtrl->SetImageList(NULL,LVSIL_NORMAL);
}
BEGIN_MESSAGE_MAP(CExplorerListView, CListView)
//{{AFX_MSG_MAP(CExplorerListView)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnBegindrag)
ON_WM_MENUSELECT()
ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_REFRESHFILES,OnRefreshList)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CExplorerListView drawing
void CExplorerListView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
/////////////////////////////////////////////////////////////////////////////
// CExplorerListView diagnostics
#ifdef _DEBUG
void CExplorerListView::AssertValid() const
{
CListView::AssertValid();
}
void CExplorerListView::Dump(CDumpContext& dc) const
{
CListView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CExplorerListView message handlers
int CExplorerListView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
//修改属性
ModifyStyle(0,LVS_EDITLABELS|LVS_SHOWSELALWAYS|LVS_AUTOARRANGE);
//设置菜单
SetListViewType(LVS_ICON);
//注册拖拽
m_ListTarget.Register(this);
//初始化系统图标列表
InitImageList();
if ( g_TreeView )
{
HTREEITEM hSelect = g_TreeView->m_pTreeCtrl->GetSelectedItem();
LPTREEPARAM ptrItem = (LPTREEPARAM)g_TreeView->m_pTreeCtrl->GetItemData(hSelect);
SetListContext(ptrItem->lpsf,ptrItem->lpidl);
}
return 0;
}
void CExplorerListView::OnDestroy()
{
CListView::OnDestroy();
// TODO: Add your message handler code here
}
void CExplorerListView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
NMITEMACTIVATE * nmia = (NMITEMACTIVATE*)pNMHDR;
CPoint point(nmia->ptAction);
int nCurItem = m_pListCtrl->HitTest(point);
if ( nCurItem==-1 )
return;
LPLISTPARAM pliParam = (LPLISTPARAM)m_pListCtrl->GetItemData(nCurItem);
if ( pliParam->uType>0 )
{
SHELLEXECUTEINFO si;
ZeroMemory(&si,sizeof(si));
si.cbSize = sizeof(si);
si.hwnd = GetSafeHwnd();
si.nShow = SW_SHOW;
si.lpIDList = (LPVOID)pliParam->lpidl;
si.fMask = SEE_MASK_INVOKEIDLIST;
ShellExecuteEx(&si);
}
else
{
// SetListContext(pliParam->lpsf,pliParam->lpidl);
g_TreeView->SetTreeContext(pliParam->lpsf,pliParam->lpidl);
}
*pResult = 0;
}
void CExplorerListView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
NMITEMACTIVATE * nmia = (NMITEMACTIVATE *) pNMHDR;
POSITION pos = m_pListCtrl->GetFirstSelectedItemPosition();
if ( pos==NULL )
{
//没选中时
return;
}
char * szPath = new char[MAX_PATH];
CStringArray sPathArray;
while (pos)
{
ZeroMemory(szPath,MAX_PATH);
int nItem = m_pListCtrl->GetNextSelectedItem(pos);
LPLISTPARAM pliParam =(LPLISTPARAM) m_pListCtrl->GetItemData(nItem);
SHGetPathFromIDList(pliParam->lpidl,szPath);
sPathArray.Add(szPath);
}
delete szPath;
CShellContextMenu scm;
scm.SetObjects(sPathArray);
CPoint point (nmia->ptAction);
m_pListCtrl->ClientToScreen(&point);
UINT idCommand = scm.ShowContextMenu(this, point);
switch( idCommand )
{
case 18: //chose delete
{
g_TreeView->SendMessage(WM_REFRESHFILES,(WPARAM)g_TreeView->m_hSelItem,0);
SendMessage(WM_REFRESHFILES,0,0);
break;
}
case 27: //chose paste
{
break;
}
}
*pResult = 0;
}
void CExplorerListView::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
g_TreeView->m_hMoveSrc = g_TreeView->m_hSelItem;
POSITION pos = m_pListCtrl->GetFirstSelectedItemPosition();
if ( pos==NULL )
return;
char * szSrc = new char[MAX_PATH];
CStringArray sDragArray;
while(pos)
{
int nItem = m_pListCtrl->GetNextSelectedItem(pos);
LPLISTPARAM pliItem = (LPLISTPARAM)m_pListCtrl->GetItemData(nItem);
ZeroMemory(szSrc,MAX_PATH);
SHGetPathFromIDList(pliItem->lpidl,szSrc);
sDragArray.Add(szSrc);
}
delete szSrc;
//创建拖拽数据源
int hgblSize = sizeof(DROPFILES);
for ( int i=0 ; i<sDragArray.GetSize() ; i++ )
{
hgblSize += (sDragArray.GetAt(i).GetLength()+1) * sizeof(_TCHAR);
}
hgblSize += sizeof(_TCHAR);
HGLOBAL hgblData = ::GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE,hgblSize);
if (hgblData == NULL)
return;
LPDROPFILES pDropFiles = (LPDROPFILES)GlobalLock(hgblData);
pDropFiles->pFiles = sizeof(DROPFILES);
pDropFiles->fWide = FALSE;
LPSTR pGlobalString = (LPSTR)(pDropFiles) + sizeof(DROPFILES);
for ( i=0 ; i<sDragArray.GetSize() ; i++ )
{
strcpy((char*)(pGlobalString), sDragArray.GetAt(i) );
pGlobalString += ( sDragArray.GetAt(i).GetLength()+1 ) * sizeof(_TCHAR);
}
pGlobalString[0] = _T('\0');
GlobalUnlock(hgblData);
COleDataSource *poleSourceObj = new COleDataSource;
poleSourceObj->CacheGlobalData(CF_HDROP,hgblData);
DROPEFFECT dropeffect = poleSourceObj->DoDragDrop();
*pResult = 0;
}
void CExplorerListView::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
LV_ITEM lvItem = pDispInfo->item;
LPLISTPARAM pliParam = (LPLISTPARAM)lvItem.lParam;
char * szSource = new char[MAX_PATH];
SHGetPathFromIDList(pliParam->lpidl,szSource);
LPTREEPARAM ptrParam = (LPTREEPARAM)g_TreeView->GetSelTreeData();
char * szDest = new char[MAX_PATH];
SHGetPathFromIDList(ptrParam->lpidl,szDest);
strcat(szDest,lvItem.pszText);
CShellFileOp op;
op.SetOperationFlags(FO_MOVE, this, FOF_NOCONFIRMMKDIR);
op.AddDestFile(szDest);
op.AddSourceFile(szSource);
BOOL bSuccess, bAPICalled = FALSE, bAborted = FALSE;
int nAPIReturn = 0;
bSuccess = op.Go ( &bAPICalled, &nAPIReturn, &bAborted );
if ( bSuccess && !bAborted )
{
g_TreeView->SendMessage(WM_REFRESHFILES,(WPARAM)g_TreeView->m_hSelItem,0);
*pResult = 1;
}
else
{
*pResult = 0;
}
}
long CExplorerListView::OnRefreshList(WPARAM wParam, LPARAM lParam)
{
if ( g_TreeView )
{
LPTREEPARAM ltrParam = (LPTREEPARAM)g_TreeView->GetSelTreeData();
SetListContext(ltrParam->lpsf,ltrParam->lpidl);
}
return 0;
}
BOOL CExplorerListView::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if ( pMsg->message==WM_RENDERFORMAT )
{
long l = pMsg->lParam;
}
if ( pMsg->message==WM_KEYDOWN )
{
HWND hWnd = this->GetSafeHwnd();
switch ( pMsg->wParam )
{
case 0x43: //Ctrl+C
{
short ctrl = GetKeyState(VK_CONTROL);
if ( HIBYTE(ctrl)!=0xFF )
break;
GetParent()->PostMessage(WM_COMMAND,MAKEWPARAM(0,ID_EDIT_COPY),0);
break;
}
case 0x58: //Ctrl+X
{
short ctrl = GetKeyState(VK_CONTROL);
if ( HIBYTE(ctrl)!=0xFF )
break;
GetParent()->PostMessage(WM_COMMAND,MAKEWPARAM(0,ID_EDIT_CUT),0);
break;
}
case 0x56: //Ctrl+V
{
short ctrl = GetKeyState(VK_CONTROL);
if ( HIBYTE(ctrl)!=0xFF )
break;
GetParent()->PostMessage(WM_COMMAND,MAKEWPARAM(0,ID_EDIT_PASTE),0);
break;
}
case 0x2e: //DEL
{
CShellFileOp op;
short lShift = GetKeyState(VK_LSHIFT);
short rShift = GetKeyState(VK_RSHIFT);
if ( HIBYTE(lShift)==0xFF || HIBYTE(rShift)==0xFF )
op.SetOperationFlags(FO_DELETE, this,NULL);
else
op.SetOperationFlags(FO_DELETE, this,FOF_ALLOWUNDO);
POSITION pos = m_pListCtrl->GetFirstSelectedItemPosition();
if ( pos==NULL )
return true;
char * szSrc = new char[MAX_PATH];
while(pos)
{
int nItem = m_pListCtrl->GetNextSelectedItem(pos);
LPLISTPARAM pliItem = (LPLISTPARAM)g_ListView->m_pListCtrl->GetItemData(nItem);
ZeroMemory(szSrc,MAX_PATH);
SHGetPathFromIDList(pliItem->lpidl,szSrc);
op.AddSourceFile(szSrc);
}
delete szSrc;
BOOL bSuccess, bAPICalled = FALSE, bAborted = FALSE;
int nAPIReturn = 0;
bSuccess = op.Go(&bAPICalled, &nAPIReturn, &bAborted);
//refresh
if ( bSuccess&&!bAborted )
{
g_TreeView->SendMessage(WM_REFRESHFILES,(WPARAM)g_TreeView->m_hSelItem,0);
g_ListView->SendMessage(WM_REFRESHFILES,0,0);
}
break;
}
}
}
if (pMsg->message==WM_DROPFILES)
{
short ctrl = HIWORD(pMsg->wParam);
return 0;
}
return CListView::PreTranslateMessage(pMsg);
}
//////////////////////////////////////////////////
// method
///////////////////////////////////////////////////
void CExplorerListView::InitImageList()
{
HIMAGELIST himlSmall;
HIMAGELIST himlLarge;
SHFILEINFO sfi;
himlSmall = (HIMAGELIST)SHGetFileInfo((LPCTSTR)_T("C:\\"),
0,
&sfi,
sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
himlLarge = (HIMAGELIST)SHGetFileInfo((LPCTSTR)_T("C:\\"),
0,
&sfi,
sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
if (himlSmall && himlLarge)
{
::SendMessage(GetSafeHwnd(), LVM_SETIMAGELIST, (WPARAM)LVSIL_SMALL,
(LPARAM)himlSmall);
::SendMessage(GetSafeHwnd(), LVM_SETIMAGELIST, (WPARAM)LVSIL_NORMAL,
(LPARAM)himlLarge);
}
}
void CExplorerListView::SetListContext(IShellFolder *psfParent, LPITEMIDLIST pidlParent)
{
// m_pListCtrl->DeleteAllItems();
DeleteAllItems();
IEnumIDList *peidl;
LPITEMIDLIST pidl, pidlAbs;
IShellFolder *psf = NULL;
HRESULT hr = psfParent->EnumObjects(NULL,SHCONTF_FOLDERS ,&peidl);
if ( NOERROR!=hr )
return;
while (NOERROR == hr)
{
hr = peidl->Next(1, &pidl, NULL);
if (hr == S_FALSE || pidl == NULL)
break;
pidlAbs = ConcatPidl(pidlParent,pidl);
psfParent->BindToObject(pidl, NULL, IID_IShellFolder, (void**)&psf);
SHFILEINFO sfi;
SHGetFileInfo((LPCTSTR)pidlAbs,
0,
&sfi,
sizeof(SHFILEINFO),
SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON|
SHGFI_DISPLAYNAME|SHGFI_ATTRIBUTES);
LVITEM lvItem;
memset(&lvItem,0,sizeof(lvItem));
lvItem.mask |= LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM ;
lvItem.iItem = m_pListCtrl->GetItemCount();
lvItem.iImage = sfi.iIcon;
lvItem.pszText = sfi.szDisplayName;
LPLISTPARAM pliParam = (LPLISTPARAM)m_pMalloc->Alloc(sizeof(LISTPARAM));
pliParam->lpsf = psf;
pliParam->lpidl = pidlAbs;
pliParam->uType = 0;
strcpy(pliParam->szName,sfi.szDisplayName);
lvItem.lParam = (LPARAM)pliParam;
m_pListCtrl->InsertItem(&lvItem);
m_pMalloc->Free(pidl);
}
peidl->Release(); //若不Release掉文件会处于被操作的状态
if ( g_TreeView )
{
//我的电脑的子项会得到文件和非文件两套
//过滤掉文件的项
if ( ComparePidls(g_TreeView->m_psfDesk, g_TreeView->m_pidlMyComputer, pidlParent) )
return;
}
hr = psfParent->EnumObjects(NULL,SHCONTF_NONFOLDERS ,&peidl);
if ( NOERROR!=hr )
return;
while (NOERROR == hr)
{
hr = peidl->Next(1, &pidl, NULL);
if (hr == S_FALSE || pidl == NULL)
break;
pidlAbs = ConcatPidl(pidlParent,pidl);
psfParent->BindToObject(pidl, NULL, IID_IShellFolder, (void**)&psf);
SHFILEINFO sfi;
SHGetFileInfo((LPCTSTR)pidlAbs,
0,
&sfi,
sizeof(SHFILEINFO),
SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_DISPLAYNAME);
LVITEM lvItem;
memset(&lvItem,0,sizeof(lvItem));
lvItem.mask |= LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM ;
lvItem.iItem = m_pListCtrl->GetItemCount();
lvItem.iImage = sfi.iIcon;
lvItem.pszText = sfi.szDisplayName;
LPLISTPARAM pliParam = (LPLISTPARAM)m_pMalloc->Alloc(sizeof(LISTPARAM));
pliParam->lpsf = psf;
pliParam->lpidl = pidlAbs;
pliParam->uType = 1;
strcpy(pliParam->szName,sfi.szDisplayName);
lvItem.lParam = (LPARAM)pliParam;
m_pListCtrl->InsertItem(&lvItem);
}
peidl->Release();
m_pListCtrl->SortItems(SortListView, (DWORD)this);
}
int CALLBACK CExplorerListView::SortListView(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
CListCtrl* pListCtrl = (CListCtrl*)lParamSort;
LPLISTPARAM pliParam1 = (LPLISTPARAM)lParam1;
LPLISTPARAM pliParam2 = (LPLISTPARAM)lParam2;
if ( pliParam1->uType==pliParam2->uType )
{
return strcmp(pliParam1->szName, pliParam2->szName);
}
else if (pliParam1->uType<pliParam2->uType)
{
return -1;
}
else
{
return 1;
}
}
int CExplorerListView::SetListViewType(DWORD viewType)
{
if ( m_dViewType==viewType )
return viewType;
int old = m_dViewType;
CMenu * pMainMenu = AfxGetApp()->GetMainWnd()->GetMenu();
CMenu * pMenu = pMainMenu->GetSubMenu(2);
switch(viewType)
{
case LVS_ICON:
pMenu->CheckMenuRadioItem(3,5,3,MF_BYPOSITION);
break;
case LVS_SMALLICON:
pMenu->CheckMenuRadioItem(3,5,4,MF_BYPOSITION);
break;
case LVS_LIST:
pMenu->CheckMenuRadioItem(3,5,5,MF_BYPOSITION);
break;
}
ModifyStyle(m_dViewType, viewType);
m_dViewType = viewType;
return old;
}
void CExplorerListView::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
{
CWnd::OnMenuSelect(nItemID, nFlags, hSysMenu);
}
void CExplorerListView::DeleteAllItems()
{
int nCount = m_pListCtrl->GetItemCount();
for ( int i=0 ; i<nCount ; i++ )
{
LPLISTPARAM pliParam = (LPLISTPARAM)m_pListCtrl->GetItemData(i);
m_pMalloc->Free(pliParam->lpidl);
m_pMalloc->Free(pliParam);
}
m_pListCtrl->DeleteAllItems();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -