📄 shellctrls.h
字号:
while( hItem != NULL ) {
DWORD_PTR lParam = GetItemData(hItem);
ATLASSERT(lParam>0);
PSHELLITEMINFO pItem = reinterpret_cast<PSHELLITEMINFO>(lParam);
if( pItem->spFolder->CompareIDs(0, pidlItem, pItem->pidlNode) == 0 ) {
if( CPidl::PidlGetCount(pidlTarget)>1 ) Expand(hItem);
break;
}
hItem = GetNextSiblingItem(hItem);
}
if( hItem == NULL ) return FALSE; // folder not found?
pidlTarget = CPidl::PidlGetNextItem(pidlTarget);
}
if( hItem != NULL ) SelectItem(hItem);
return TRUE;
}
// Implementation
BOOL _Init()
{
// Extract the System Imagelist
CImageList images;
SHFILEINFO sfi;
images = (HIMAGELIST) ::SHGetFileInfo( _T("C:\\"), 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
SetImageList(images.Detach(), TVSIL_NORMAL);
return TRUE;
}
BOOL _Populate(IShellFolder* pFolder, LPCITEMIDLIST pidlParent, DWORD dwAttribs)
{
ATLASSERT(::IsWindow(m_hWnd));
ATLASSERT(pidlParent);
DeleteAllItems();
HTREEITEM hItem = _InsertItem(pFolder, pidlParent, NULL, dwAttribs, TVI_ROOT);
SelectItem(hItem);
Expand(hItem);
return TRUE;
}
HTREEITEM _InsertItem(IShellFolder* pFolder, LPCITEMIDLIST pidlPath, LPCITEMIDLIST pidlNode,
DWORD dwAttribs, HTREEITEM hParentItem)
{
ATLASSERT(pFolder);
ATLASSERT(pidlPath);
// Create PARAM data
PSHELLITEMINFO pItem;
ATLTRY(pItem = new SHELLITEMINFO);
ATLASSERT(pItem);
pItem->pidlFull.Copy( pidlPath );
pItem->pidlFull.Concatenate( pidlNode );
pItem->pidlNode.Copy( pidlNode );
pItem->spFolder = pFolder;
pItem->dwAttribs = dwAttribs;
// Insert tree item...
TV_INSERTSTRUCT item = { 0 };
item.hParent = hParentItem;
item.hInsertAfter = TVI_LAST;
item.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_CHILDREN;
item.item.pszText = LPSTR_TEXTCALLBACK;
item.item.iImage = item.item.iSelectedImage = I_IMAGECALLBACK;
item.item.lParam= (LPARAM) pItem;
item.item.cChildren = (dwAttribs & SFGAO_HASSUBFOLDER);
if( dwAttribs & SFGAO_SHARE ) {
item.item.mask |= TVIF_STATE;
item.item.stateMask |= TVIS_OVERLAYMASK;
item.item.state |= INDEXTOOVERLAYMASK(1);
}
if( dwAttribs & SFGAO_LINK ) {
item.item.mask |= TVIF_STATE;
item.item.stateMask |= TVIS_OVERLAYMASK;
item.item.state |= INDEXTOOVERLAYMASK(2);
}
return InsertItem(&item);
}
// NOTE: Sorting added by Anatoly Ivasyuk.
static int CALLBACK _SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
IShellFolder* piSF = reinterpret_cast<IShellFolder*>(lParamSort);
PSHELLITEMINFO pItem1 = reinterpret_cast<PSHELLITEMINFO>(lParam1);
PSHELLITEMINFO pItem2 = reinterpret_cast<PSHELLITEMINFO>(lParam2);
HRESULT Hr = piSF->CompareIDs(0, pItem1->pidlNode, pItem2->pidlNode);
if( SUCCEEDED(Hr) ) return (SHORT) (Hr & SHCIDS_COLUMNMASK);
return 0;
}
// Message Handlers
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
LRESULT lRes = DefWindowProc(uMsg, wParam, lParam);
_Init();
return lRes;
}
LRESULT OnDeleteItem(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) pnmh;
PSHELLITEMINFO pItem = reinterpret_cast<PSHELLITEMINFO>(pnmtv->itemOld.lParam);
ATLASSERT(pItem);
ATLTRY(delete pItem);
return 0;
}
LRESULT OnGetDispInfo(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
LPNMTVDISPINFO lpdi = (LPNMTVDISPINFO) pnmh;
PSHELLITEMINFO pItem = reinterpret_cast<PSHELLITEMINFO>(lpdi->item.lParam);
SHFILEINFO sfi;
if( lpdi->item.mask & TVIF_TEXT ) {
if( ::SHGetFileInfo((LPCTSTR)(LPCITEMIDLIST)pItem->pidlFull,
0, &sfi, sizeof(sfi),
SHGFI_PIDL | SHGFI_DISPLAYNAME) ) {
::lstrcpy(lpdi->item.pszText, sfi.szDisplayName);
}
}
if( lpdi->item.mask & TVIF_IMAGE ) {
if( ::SHGetFileInfo((LPCTSTR)(LPCITEMIDLIST)pItem->pidlFull,
0, &sfi, sizeof(sfi),
SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_LINKOVERLAY) ) {
lpdi->item.iImage = sfi.iIcon;
}
}
if( lpdi->item.mask & TVIF_SELECTEDIMAGE ) {
if( ::SHGetFileInfo((LPCTSTR)(LPCITEMIDLIST)pItem->pidlFull,
0, &sfi, sizeof(sfi),
SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON) ) {
lpdi->item.iSelectedImage = sfi.iIcon;
}
}
return 0;
}
LRESULT OnItemExpanding(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
{
LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) pnmh;
if( pnmtv->action == TVE_COLLAPSE ) {
Expand(pnmtv->itemNew.hItem, TVE_COLLAPSE | TVE_COLLAPSERESET);
return 0;
}
#ifdef __ATLCTRLX_H__
CWaitCursor cursor;
#endif
PSHELLITEMINFO pFolderItem = reinterpret_cast<PSHELLITEMINFO>(pnmtv->itemNew.lParam);
CComPtr<IShellFolder> spFolder;
if( pFolderItem->pidlNode != NULL ) {
if( FAILED(pFolderItem->spFolder->BindToObject(pFolderItem->pidlNode, NULL, IID_IShellFolder, (LPVOID*)&spFolder)) ) return FALSE;
}
else {
spFolder = pFolderItem->spFolder;
}
// Add children
CComPtr<IEnumIDList> spEnum;
DWORD dwEnumFlags = SHCONTF_FOLDERS;
if( m_dwShellStyle & SCT_EX_SHOWHIDDEN ) dwEnumFlags |= SHCONTF_INCLUDEHIDDEN;
if( SUCCEEDED(spFolder->EnumObjects(NULL, dwEnumFlags, &spEnum)) ) {
CPidl pidl;
DWORD dwFetched;
while( (spEnum->Next(1, &pidl, &dwFetched) == S_OK) && (dwFetched > 0) ) {
// Get attributes and filter some items
DWORD dwAttribs = SFGAO_DISPLAYATTRMASK | SFGAO_HASSUBFOLDER;
if( !_FilterItem(spFolder, pidl, dwAttribs) ) {
_InsertItem(spFolder, pFolderItem->pidlFull, pidl, dwAttribs, pnmtv->itemNew.hItem);
}
pidl.Delete();
}
}
// Sort children
TVSORTCB tvscb;
tvscb.hParent = pnmtv->itemNew.hItem;
tvscb.lpfnCompare = _SortFunc;
tvscb.lParam = (LPARAM) (IShellFolder*) spFolder;
SortChildrenCB(&tvscb);
bHandled = FALSE;
return 0;
}
};
/////////////////////////////////////////////////////////////////////////////
// CShellListCtrl
class CShellListCtrl :
public CWindowImpl< CShellListCtrl, CListViewCtrl, CControlWinTraits >,
public CShellBaseCtrl< CShellListCtrl >
{
public:
typedef CWindowImpl< CShellListCtrl, CListViewCtrl, CControlWinTraits > parentClass;
BEGIN_MSG_MAP(CShellListCtrl)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
REFLECTED_NOTIFY_CODE_HANDLER(LVN_GETDISPINFO, OnGetDispInfo)
REFLECTED_NOTIFY_CODE_HANDLER(LVN_DELETEITEM, OnDeleteItem)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
// Operations
BOOL SubclassWindow(HWND hWnd)
{
ATLASSERT(m_hWnd==NULL);
ATLASSERT(::IsWindow(hWnd));
BOOL bRet = parentClass::SubclassWindow(hWnd);
if( bRet ) _Init();
return bRet;
}
void SortItems()
{
CListViewCtrl::SortItems(_SortFunc, NULL);
}
// Implementation
BOOL _Init()
{
// We must not destroy system image list (Q192055)
ModifyStyle(0, LVS_SHAREIMAGELISTS);
// Extract the System Imagelists
CImageList images;
SHFILEINFO sfi;
images = (HIMAGELIST)::SHGetFileInfo( _T("C:\\"), 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
SetImageList(images.Detach(), LVSIL_SMALL);
images = (HIMAGELIST)::SHGetFileInfo( _T("C:\\"), 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
SetImageList(images.Detach(), LVSIL_NORMAL);
return TRUE;
}
BOOL _Populate(IShellFolder* pFolder, LPCITEMIDLIST pidlPath, DWORD /*dwAttribs*/)
{
ATLASSERT(::IsWindow(m_hWnd));
ATLASSERT(pFolder);
ATLASSERT(pidlPath);
SetRedraw(FALSE);
DeleteAllItems();
CComPtr<IEnumIDList> spEnum;
DWORD dwEnumFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
if( m_dwShellStyle & SCT_EX_SHOWHIDDEN ) dwEnumFlags |= SHCONTF_INCLUDEHIDDEN;
if( SUCCEEDED(pFolder->EnumObjects(NULL, dwEnumFlags, &spEnum)) ) {
CPidl pidl;
DWORD dwFetched;
while( (spEnum->Next(1, &pidl, &dwFetched) == S_OK) && (dwFetched > 0) ) {
// Get attributes and filter some items
DWORD dwAttribs = SFGAO_DISPLAYATTRMASK;
if( !_FilterItem(pFolder, pidl, dwAttribs) ) {
_InsertItem(pFolder, pidlPath, pidl, dwAttribs);
}
pidl.Delete();
}
}
SortItems();
SetRedraw(TRUE);
Invalidate();
return TRUE;
}
int _InsertItem(IShellFolder* pFolder, LPCITEMIDLIST pidlPath, LPCITEMIDLIST pidlNode,
DWORD dwAttribs)
{
ATLASSERT(pFolder);
ATLASSERT(pidlPath);
// Create PARAM data
PSHELLITEMINFO pItem;
ATLTRY(pItem = new SHELLITEMINFO);
ATLASSERT(pItem);
pItem->pidlFull.Copy( pidlPath );
pItem->pidlFull.Concatenate( pidlNode );
pItem->pidlNode.Copy( pidlNode );
pItem->spFolder = pFolder;
pItem->dwAttribs = dwAttribs;
// Insert listview item
LVITEM item = { 0 };
item.iItem = GetItemCount();
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
item.pszText = LPSTR_TEXTCALLBACK;
item.iImage = I_IMAGECALLBACK;
item.lParam = (LPARAM) pItem;
if( dwAttribs & SFGAO_SHARE ) {
item.mask |= LVIF_STATE;
item.stateMask |= LVIS_OVERLAYMASK;
item.state |= INDEXTOOVERLAYMASK(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -