📄 bcgpshelllist.cpp
字号:
{
return sfi.szTypeName;
}
break;
case BCGPShellList_ColumnSize:
case BCGPShellList_ColumnModified:
if (SHGetPathFromIDList (pItem->pidlFQ, szPath))
{
CFileStatus fs;
if (CFile::GetStatus (szPath, fs))
{
CString str;
if (iColumn == 1)
{
if ((fs.m_attribute & (CFile::directory | CFile ::volume)) == 0)
{
OnFormatFileSize ((long)fs.m_size, str);
}
}
else
{
OnFormatFileDate (fs.m_mtime, str);
}
return str;
}
}
break;
default:
ASSERT (FALSE);
break;
}
return _T("");
}
//***************************************************************************************
int CBCGPShellList::OnGetItemIcon (int /*iItem*/, LPBCGCBITEMINFO pItem)
{
ASSERT_VALID (this);
ASSERT (pItem != NULL);
SHFILEINFO sfi;
int iIcon = -1;
if (SHGetFileInfo ((LPCTSTR)pItem->pidlFQ, 0, &sfi, sizeof (sfi),
SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_LINKOVERLAY))
{
iIcon = sfi.iIcon;
}
return iIcon;
}
//***************************************************************************************
int CBCGPShellList::OnCompareItems (LPARAM lParam1, LPARAM lParam2, int iColumn)
{
ASSERT_VALID (this);
LPBCGCBITEMINFO pItem1 = (LPBCGCBITEMINFO)lParam1;
LPBCGCBITEMINFO pItem2 = (LPBCGCBITEMINFO)lParam2;
ASSERT (pItem1 != NULL);
ASSERT (pItem2 != NULL);
SHFILEINFO sfi1;
SHFILEINFO sfi2;
TCHAR szPath1 [MAX_PATH];
TCHAR szPath2 [MAX_PATH];
CFileStatus fs1;
CFileStatus fs2;
int nRes = 0;
switch (iColumn)
{
case BCGPShellList_ColumnName:
{
HRESULT hr = pItem1->pParentFolder->CompareIDs (0,
pItem1->pidlRel,
pItem2->pidlRel);
if (FAILED (hr))
{
return 0;
}
nRes = (short) SCODE_CODE (GetScode (hr));
}
break;
case BCGPShellList_ColumnType:
if (SHGetFileInfo ((LPCTSTR)pItem1->pidlFQ, 0, &sfi1, sizeof(sfi1), SHGFI_PIDL | SHGFI_TYPENAME) &&
SHGetFileInfo ((LPCTSTR)pItem2->pidlFQ, 0, &sfi2, sizeof(sfi2), SHGFI_PIDL | SHGFI_TYPENAME))
{
nRes = lstrcmpi (sfi1.szTypeName, sfi2.szTypeName);
}
break;
case BCGPShellList_ColumnSize:
case BCGPShellList_ColumnModified:
if (SHGetPathFromIDList (pItem1->pidlFQ, szPath1) &&
CFile::GetStatus (szPath1, fs1))
{
if (SHGetPathFromIDList (pItem2->pidlFQ, szPath2) &&
CFile::GetStatus (szPath2, fs2))
{
if (iColumn == BCGPShellList_ColumnSize)
{
nRes = fs1.m_size < fs2.m_size ? -1 :
fs1.m_size > fs2.m_size ? 1 : 0;
}
else
{
nRes = fs1.m_mtime < fs2.m_mtime ? -1 :
fs1.m_mtime > fs2.m_mtime ? 1 : 0;
}
}
else
{
nRes = 1;
}
}
else
{
nRes = -1;
}
break;
}
return nRes;
}
//****************************************************************************************
void CBCGPShellList::OnSetColumns ()
{
#define COLUMN_ITEMS 4
const TCHAR* szName [COLUMN_ITEMS] =
{
_T("名称"),
_T("大小"),
_T("类型"),
_T("修改日期"),
};
for (int iColumn = 0; iColumn < COLUMN_ITEMS; iColumn++)
{
int nFormat = (iColumn == BCGPShellList_ColumnSize) ?
LVCFMT_RIGHT : LVCFMT_LEFT;
int nWidth = (iColumn == BCGPShellList_ColumnName) ? 200 : 100;
InsertColumn (iColumn, szName [iColumn], nFormat, nWidth, iColumn);
}
}
//***************************************************************************************
void CBCGPShellList::PreSubclassWindow()
{
CBCGPListCtrl::PreSubclassWindow();
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState ();
if (pThreadState->m_pWndInit == NULL)
{
if (!InitList ())
{
ASSERT(FALSE);
}
}
}
//***************************************************************************************
BOOL CBCGPShellList::InitList ()
{
if (g_pShellManager == NULL)
{
TRACE0("You need to initialize CBCGShellManager first\n");
return FALSE;
}
ModifyStyle (0, LVS_SHAREIMAGELISTS);
//------------------
// Set shell images:
//------------------
SetImageList (CImageList::FromHandle (GetShellImageList (TRUE)), LVSIL_NORMAL);
SetImageList (CImageList::FromHandle (GetShellImageList (FALSE)), LVSIL_SMALL);
//-------------
// Add columns:
//-------------
OnSetColumns ();
if (m_psfCurFolder == NULL)
{
//-----------------
// Display desktop:
//-----------------
BCGCBITEMINFO info;
if (SUCCEEDED (SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOP, &info.pidlFQ)))
{
DisplayFolder (&info);
g_pShellManager->FreeItem (info.pidlFQ);
}
}
return TRUE;
}
//***************************************************************************************
void CBCGPShellList::OnFormatFileSize (long lFileSize, CString& str)
{
str.Empty ();
if (lFileSize == 0)
{
str = _T("0");
}
else
{
lFileSize = lFileSize / 1024 + 1;
str.Format (_T("%ld"), lFileSize);
//-------------------------------------
// Convert number to the system format:
//-------------------------------------
TCHAR szNumOut [256];
GetNumberFormat (LOCALE_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, str,
NULL, szNumOut, 255);
str = szNumOut;
//----------------------------------
// Truncate trailing fractal digits:
//----------------------------------
TCHAR szDec [10];
GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, szDec, 10);
int nDecLen = lstrlen (szDec);
if (nDecLen > 0)
{
for (int i = str.GetLength () - nDecLen - 1; i >= 0; i--)
{
if (str.Mid (i, nDecLen) == szDec)
{
str = str.Left (i);
break;
}
}
}
}
str += _T(" KB");
}
//******************************************************************************************
void CBCGPShellList::OnFormatFileDate (const CTime& tmFile, CString& str)
{
COleDateTime dateFile (tmFile.GetTime ());
str = dateFile.Format ();
}
//***************************************************************************************
void CBCGPShellList::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
{
ASSERT_VALID (this);
ASSERT_VALID (g_pShellManager);
ASSERT (g_pShellManager->m_pBCGMalloc != NULL);
if (m_pContextMenu2 != NULL)
{
return;
}
if (!m_bContextMenu)
{
Default ();
return;
}
if (m_psfCurFolder == NULL)
{
return;
}
UINT nSelItems = GetSelectedCount ();
int nClickedItem = -1;
if (point.x == -1 && point.y == -1)
{
//--------------------------------------------------------
// Keyboard, show menu for the currently selected item(s):
//--------------------------------------------------------
if (nSelItems == 0)
{
return;
}
}
else
{
//--------------------------
// Clicked on specifed item:
//--------------------------
LVHITTESTINFO lvhti;
lvhti.pt = point;
ScreenToClient(&lvhti.pt);
lvhti.flags = LVHT_NOWHERE;
HitTest (&lvhti);
if ((lvhti.flags & LVHT_ONITEM) == 0)
{
//-----------------------------------
// Click ouside of items, do nothing
//-----------------------------------
return;
}
nClickedItem = lvhti.iItem;
}
LPITEMIDLIST* pPidls = (LPITEMIDLIST*)
g_pShellManager->m_pBCGMalloc->Alloc (sizeof(LPITEMIDLIST) * nSelItems);
ASSERT (pPidls != NULL);
//------------------------
// Get the selected items:
//------------------------
LVITEM lvItem;
ZeroMemory(&lvItem, sizeof(lvItem));
lvItem.mask = LVIF_PARAM;
LPBCGCBITEMINFO pClickedInfo = (LPBCGCBITEMINFO)lvItem.lParam;
if (nClickedItem >= 0)
{
//-------------------------------------------
// Put the item clicked on first in the list:
//-------------------------------------------
lvItem.iItem = nClickedItem;
if (GetItem (&lvItem))
{
pClickedInfo = (LPBCGCBITEMINFO)lvItem.lParam;
pPidls [0] = pClickedInfo->pidlRel;
}
}
int nCurItem = -1;
for (UINT i = nClickedItem >= 0 ? 1 : 0; i < nSelItems; i++)
{
nCurItem = GetNextItem (nCurItem, LVNI_SELECTED);
if (nCurItem != nClickedItem)
{
lvItem.iItem = nCurItem;
if (GetItem (&lvItem))
{
LPBCGCBITEMINFO pInfo = (LPBCGCBITEMINFO)lvItem.lParam;
pPidls [i] = pInfo->pidlRel;
if (pClickedInfo == NULL)
{
pClickedInfo = pInfo;
}
}
}
else
{
i--;
}
}
if (pPidls [0] == NULL)
{
g_pShellManager->m_pBCGMalloc->Free (pPidls);
return;
}
IContextMenu* pcm;
HRESULT hr = m_psfCurFolder->GetUIObjectOf (GetSafeHwnd (),
nSelItems,
(LPCITEMIDLIST*)pPidls,
IID_IContextMenu,
NULL,
(LPVOID*)&pcm);
if (SUCCEEDED (hr))
{
hr = pcm->QueryInterface (IID_IContextMenu2, (LPVOID*)&m_pContextMenu2);
if (SUCCEEDED (hr))
{
HMENU hPopup = CreatePopupMenu ();
if (hPopup != NULL)
{
hr = m_pContextMenu2->QueryContextMenu(hPopup, 0, 1, 0x7fff, CMF_NORMAL | CMF_EXPLORE);
if (SUCCEEDED(hr))
{
UINT idCmd = TrackPopupMenu (hPopup,
TPM_LEFTALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON,
point.x,
point.y,
0,
GetSafeHwnd (),
NULL);
if (idCmd != 0)
{
BOOL bIsFolder = FALSE;
if (nSelItems == 1 &&
idCmd == ::GetMenuDefaultItem (hPopup, FALSE, 0))
{
//-----------------------------------------------------
// If specified element is a folder, try to display it:
//-----------------------------------------------------
ULONG ulAttrs = SFGAO_FOLDER;
m_psfCurFolder->GetAttributesOf (1,
(const struct _ITEMIDLIST **) &pClickedInfo->pidlRel, &ulAttrs);
if (ulAttrs & SFGAO_FOLDER)
{
bIsFolder = TRUE;
DisplayFolder (pClickedInfo);
}
}
if (!bIsFolder)
{
CMINVOKECOMMANDINFO cmi;
cmi.cbSize = sizeof(CMINVOKECOMMANDINFO);
cmi.fMask = 0;
cmi.hwnd = (HWND) GetParent();
cmi.lpVerb = (LPCSTR)(INT_PTR)(idCmd - 1);
cmi.lpParameters = NULL;
cmi.lpDirectory = NULL;
cmi.nShow = SW_SHOWNORMAL;
cmi.dwHotKey = 0;
cmi.hIcon = NULL;
hr = pcm->InvokeCommand (&cmi);
}
}
}
}
if (m_pContextMenu2 != NULL)
{
m_pContextMenu2->Release();
m_pContextMenu2 = NULL;
}
}
pcm->Release();
}
g_pShellManager->m_pBCGMalloc->Free (pPidls);
}
//***************************************************************************************
void CBCGPShellList::EnableShellContextMenu (BOOL bEnable)
{
m_bContextMenu = bEnable;
}
//****************************************************************************************
void CBCGPShellList::OnDestroy()
{
CBCGPShellTree* pTree = GetRelatedTree ();
if (pTree != NULL)
{
ASSERT_VALID (pTree);
pTree->m_hwndRelatedList = NULL;
}
ReleaseCurrFolder ();
CBCGPListCtrl::OnDestroy();
}
//***************************************************************************************
CBCGPShellTree* CBCGPShellList::GetRelatedTree () const
{
if (m_hwndRelatedTree == NULL)
{
return NULL;
}
return DYNAMIC_DOWNCAST (CBCGPShellTree,
CWnd::FromHandlePermanent (m_hwndRelatedTree));
}
//*********************************************************************************
void CBCGPShellList::SetItemTypes (SHCONTF nTypes)
{
ASSERT_VALID (this);
if (m_nTypes != nTypes)
{
m_nTypes = nTypes;
if (GetSafeHwnd () != NULL)
{
Refresh ();
}
}
}
//**********************************************************************************
LRESULT CBCGPShellList::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITMENUPOPUP:
case WM_DRAWITEM:
case WM_MEASUREITEM:
if (m_pContextMenu2 != NULL)
{
m_pContextMenu2->HandleMenuMsg(message, wParam, lParam);
return 0;
}
break;
}
return CBCGPListCtrl::WindowProc(message, wParam, lParam);
}
void CBCGPShellList::OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
ASSERT_VALID (g_pShellManager);
ASSERT (g_pShellManager->m_pBCGMalloc != NULL);
*pResult = 0;
if( !(pNMLV->uChanged & LVIF_STATE) || !((pNMLV->uNewState ^ pNMLV->uOldState) & LVIS_SELECTED) )
{
return;
}
UINT nSelItems = GetSelectedCount ();
LPITEMIDLIST* pPidls = (LPITEMIDLIST*)
g_pShellManager->m_pBCGMalloc->Alloc(sizeof(LPITEMIDLIST) * nSelItems);
ASSERT (pPidls != NULL);
int nCurItem = -1;
LVITEM lvItem;
ZeroMemory(&lvItem, sizeof(lvItem));
lvItem.mask = LVIF_PARAM;
for (UINT i = 0; i < nSelItems; i++)
{
nCurItem = GetNextItem (nCurItem, LVNI_SELECTED);
lvItem.iItem = nCurItem;
if (GetItem (&lvItem))
{
LPBCGCBITEMINFO pInfo = (LPBCGCBITEMINFO)lvItem.lParam;
pPidls [i] = pInfo->pidlRel;
}
}
if (pPidls [0] == NULL)
{
g_pShellManager->m_pBCGMalloc->Free (pPidls);
return;
}
IDataObject *pDataObj = NULL;
HRESULT hr = m_psfCurFolder->GetUIObjectOf( GetSafeHwnd (),
nSelItems, (LPCITEMIDLIST*)pPidls,
IID_IDataObject, NULL, (LPVOID*)&pDataObj );
if (SUCCEEDED (hr))
{
if (GetParent () != NULL)
{
GetParent ()->SendMessage (BCGPM_SELECT_ITEMS_CHANGED, 0, (LPARAM)pDataObj);
}
pDataObj->Release();
}
else
{
if (GetParent () != NULL)
{
GetParent ()->SendMessage (BCGPM_SELECT_ITEMS_CHANGED, 0, (LPARAM)0);
}
}
g_pShellManager->m_pBCGMalloc->Free (pPidls);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -