• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
thankgoodness
博客园    首页    新随笔    联系   管理    订阅  订阅

列举shell namespace的树控件

if !defined(AFX_EXPLORERTREE_H__F22991C2_DB9C_11D6_B7DB_0080C82BE86B__INCLUDED_)
#define AFX_EXPLORERTREE_H__F22991C2_DB9C_11D6_B7DB_0080C82BE86B__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ExplorerTree.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CExplorerTree window
class CExplorerTree : public CTreeCtrl
{

public
:
HTREEITEM GetItemFromPath(CString&path);
class
FILEITEM{
public
:
LPITEMIDLIST pidl;
BOOL bListed;
FILEITEM(){
pidl=NULL;
bListed=FALSE;
}
};

typedef
FILEITEM* LPFILEITEM;

CExplorerTree(DWORD flag=SHCONTF_FOLDERS);//SHCONTF_NONFOLDER,SHCONTF_INCLUDEHIDDEN
virtual ~CExplorerTree();
void
BuildTree();
void
RefreshTree(HTREEITEM item=NULL);
void
DeleteTree(HTREEITEM item=NULL);
void
ListFolder(HTREEITEM item);
BOOL GetItemPath(HTREEITEM item,CString&path);
void
ExpandTree(HTREEITEM item);
BOOL GetItemFolder(HTREEITEM&item,LPSHELLFOLDER&lpFolder);
protected
:
LPMALLOC lpMalloc;
LPSHELLFOLDER lpDesktop;
DWORD dwListFlag;
//methods
static int CALLBACK CompareItem(LPARAM lParam1,LPARAM lParam2,LPARAM lParam);
LPITEMIDLIST Append(LPCITEMIDLIST pidlBase,LPCITEMIDLIST pidlAdd);
LPITEMIDLIST MakeCopy(LPCITEMIDLIST pidl);
UINT GetSize(LPCITEMIDLIST pidl);
LPITEMIDLIST GetNextItemID(LPCITEMIDLIST pidl);
int
GetIcon(LPITEMIDLIST pidl,UINT flag=SHGFI_OPENICON);
BOOL GetItemName(LPITEMIDLIST  pidl,CString&name);
BOOL ItemIsFileSystem(LPITEMIDLIST pidl);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CExplorerTree)
public:
//}}AFX_VIRTUAL

// Generated message map functions
protected:
BOOL EqualPIDL(LPITEMIDLIST&pidl1,LPITEMIDLIST&pidl2);
HTREEITEM FindPath(HTREEITEM item,LPITEMIDLIST&pidl);
//{{AFX_MSG(CExplorerTree)
afx_msg void OnItemExpanded(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};


/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_EXPLORERTREE_H__F22991C2_DB9C_11D6_B7DB_0080C82BE86B__INCLUDED_)
// ExplorerTree.cpp : implementation file
//

#include "stdafx.h"
#include "ExplorerTree.h"
#include <atlconv.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CExplorerTree

CExplorerTree::CExplorerTree(DWORD flag)
{
dwListFlag=flag;
lpMalloc=NULL;
lpDesktop=NULL;
}
CExplorerTree::~CExplorerTree()
{
}
BEGIN_MESSAGE_MAP(CExplorerTree, CTreeCtrl)
//{{AFX_MSG_MAP(CExplorerTree)
	ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemExpanded)
ON_WM_CREATE()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CExplorerTree message handlers
int CExplorerTree::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
BuildTree();
return 0;
}
void CExplorerTree::RefreshTree(HTREEITEM item)
{
if(ItemHasChildren(item)){
DeleteTree(item);
}
ListFolder(item);
}
int CExplorerTree::GetIcon(LPITEMIDLIST pidl, UINT flag)
{
SHFILEINFO sfi;
flag|=(SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL);
SHGetFileInfo((LPCTSTR)pidl,0,&sfi,sizeof(SHFILEINFO),flag);
return sfi.iIcon;
}
BOOL CExplorerTree::GetItemName(LPITEMIDLIST pidl, CString &name)
{
	SHFILEINFO sfi;
SHGetFileInfo((LPCTSTR)pidl,0,&sfi,sizeof(SHFILEINFO),SHGFI_DISPLAYNAME|SHGFI_PIDL);
name=sfi.szDisplayName;
return TRUE;
}
void CExplorerTree::OnItemExpanded(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
*pResult = 0;
HTREEITEM item=pNMTreeView->itemNew.hItem;
if (ItemHasChildren(item)&&pNMTreeView->action==TVE_EXPAND){
ExpandTree(pNMTreeView->itemNew.hItem);
}
}
void CExplorerTree::DeleteTree(HTREEITEM item)
{
LPSHELLFOLDER lpFolder=NULL;
HTREEITEM root=item;
if(root==NULL)
root=GetRootItem();
if(root==NULL)
return;
if (ItemHasChildren(root)){
HTREEITEM hChildItem = GetChildItem(root);
while (hChildItem != NULL)
{
DeleteTree(hChildItem);
LPFILEITEM pItem=(LPFILEITEM)GetItemData(hChildItem);
LPITEMIDLIST pidl=pItem->pidl;
lpMalloc->Free(pidl);
delete pItem;
DeleteItem(hChildItem);
hChildItem = GetChildItem(root);
}
}
}
void CExplorerTree::ListFolder(HTREEITEM item)
{
HTREEITEM hRoot=item;
if(item==NULL)
hRoot=GetRootItem();
LPFILEITEM pItem=(LPFILEITEM)GetItemData(hRoot);
if(ItemHasChildren(hRoot))
return;
LPITEMIDLIST pidl,temp;
int open;
int nm;
LPSHELLFOLDER lpFolder=NULL;
if(!GetItemFolder(hRoot,lpFolder)||lpFolder==NULL)
return;
BeginWaitCursor();
CString name;
LPENUMIDLIST lpEnum=NULL;
ULONG cnt;
LPITEMIDLIST root=pItem->pidl;
pItem->bListed=TRUE;
if(SUCCEEDED(lpFolder->EnumObjects(0,dwListFlag,&lpEnum))){
while(S_OK==lpEnum->Next(1,&temp,&cnt)){
pidl=Append(root,temp);
if(ItemIsFileSystem(pidl)){
open=GetIcon(pidl);
nm=GetIcon(pidl,0);
				GetItemName(pidl,name);
pItem=new FILEITEM;
pItem->pidl=pidl;
HTREEITEM child=InsertItem(name,nm,open,hRoot);
SetItemData(child,(DWORD)pItem);
}
else
lpMalloc->Free(pidl);
lpMalloc->Free(temp);
}
lpEnum->Release();
}
lpFolder->Release();
TVSORTCB tvs;
tvs.hParent = hRoot;
tvs.lpfnCompare = CompareItem;
tvs.lParam =(long)this;
SortChildrenCB(&tvs);
EndWaitCursor();
}
LPITEMIDLIST CExplorerTree::GetNextItemID(LPCITEMIDLIST pidl)
{
// Check for valid pidl.
	if(pidl == NULL)
return NULL;
// Get the size of the specified item identifier.
	int cb = pidl->mkid.cb;
// If the size is zero, it is the end of the list.
	if (cb == 0)
return NULL;
// Add cb to pidl (casting to increment by bytes).
	pidl = (LPITEMIDLIST) (((LPBYTE) pidl) + cb);
// Return NULL if it is null-terminating, or a pidl otherwise.
	return (pidl->mkid.cb == 0) ? NULL : (LPITEMIDLIST) pidl;
}
UINT CExplorerTree::GetSize(LPCITEMIDLIST pidl)
{
UINT cbTotal = 0;
if (pidl)
{
cbTotal += sizeof(pidl->mkid.cb);    // Null terminator
        while (pidl)
{
cbTotal += pidl->mkid.cb;
pidl = GetNextItemID(pidl);
}
}
return cbTotal;
}
LPITEMIDLIST CExplorerTree::MakeCopy(LPCITEMIDLIST pidl)
{
UINT cb = 0;
LPITEMIDLIST pidlTemp = (LPITEMIDLIST) pidl;
// Calculate size of list.
    cb = GetSize(pidl);
LPITEMIDLIST pidlRet = (LPITEMIDLIST)lpMalloc->Alloc(cb);
if (pidlRet)
CopyMemory(pidlRet, pidl, cb);
return pidlRet;
}
LPITEMIDLIST CExplorerTree::Append(LPCITEMIDLIST pidlBase, LPCITEMIDLIST pidlAdd)
{
if(pidlBase == NULL)
return NULL;
if(pidlAdd == NULL)
return MakeCopy(pidlBase);
LPITEMIDLIST pidlNew;
UINT cb1 = GetSize(pidlBase) - sizeof(pidlBase->mkid.cb);
UINT cb2 = GetSize(pidlAdd);
pidlNew = (LPITEMIDLIST)lpMalloc->Alloc(cb1 + cb2);
if (pidlNew)
{
CopyMemory(pidlNew, pidlBase, cb1);
CopyMemory(((LPSTR)pidlNew) + cb1, pidlAdd, cb2);
}
return pidlNew;
}
BOOL CExplorerTree::GetItemFolder(HTREEITEM &item, LPSHELLFOLDER &lpFolder)
{
HTREEITEM parent=item;
LPITEMIDLIST pidl=NULL;
if(item==GetRootItem())
return SUCCEEDED(lpDesktop->QueryInterface(IID_IShellFolder,(void**)&lpFolder));
LPFILEITEM pItem=(LPFILEITEM)GetItemData(item);
pidl=pItem->pidl;
HRESULT hres=lpDesktop->BindToObject(pidl,0,IID_IShellFolder,(void**)&lpFolder);
return SUCCEEDED(hres);
}
void CExplorerTree::OnDestroy()
{
DeleteTree();
HTREEITEM root=GetRootItem();
if(root==NULL)
return;
LPFILEITEM pItem=(LPFILEITEM)GetItemData(root);
LPITEMIDLIST pidl=pItem->pidl;
lpMalloc->Free(pidl);
delete pItem;
DeleteAllItems();
if(lpMalloc)
lpMalloc->Release();
if(lpDesktop)
lpDesktop->Release();
CTreeCtrl::OnDestroy();
}
void CExplorerTree::BuildTree()
{
if(lpMalloc||lpDesktop||GetRootItem())
return;
SHFILEINFO sfi;
ZeroMemory(&sfi,sizeof(SHFILEINFO));
HIMAGELIST hil=(HIMAGELIST)SHGetFileInfo("*.txt",FILE_ATTRIBUTE_NORMAL,&sfi,sizeof(SHFILEINFO),
SHGFI_USEFILEATTRIBUTES|SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
if(hil){
CImageList *pim=CImageList::FromHandle(hil);
SetImageList(pim,LVSIL_NORMAL);
pim->Detach();
}
SHGetMalloc(&lpMalloc);
SHGetDesktopFolder(&lpDesktop);
LPITEMIDLIST pidl=(LPITEMIDLIST)lpMalloc->Alloc(sizeof(USHORT));
*((USHORT*)pidl)=0;
int open=GetIcon(pidl);
int nm=GetIcon(pidl,0);
CString name;
GetItemName(lpDesktop,pidl,name);
HTREEITEM hRoot=InsertItem(name,nm,open);
LPFILEITEM pItem=new FILEITEM;
pItem->pidl=pidl;
SetItemData(hRoot,(DWORD)pItem);
RefreshTree(hRoot);
Expand(hRoot,TVE_EXPAND);
}
BOOL CExplorerTree::GetItemPath(HTREEITEM item, CString &path)
{
LPFILEITEM pItem=(LPFILEITEM)GetItemData(item);
LPITEMIDLIST pidl=pItem->pidl;
BOOL ret=SHGetPathFromIDList(pidl,path.GetBuffer(MAX_PATH));
path.ReleaseBuffer();
return ret;
}
int CExplorerTree::CompareItem(LPARAM lParam1, LPARAM lParam2, LPARAM lParam)
{
LPITEMIDLIST p1=((LPFILEITEM)lParam1)->pidl;
LPITEMIDLIST p2=((LPFILEITEM)lParam2)->pidl;
CString name1,name2;
CExplorerTree*pTree=(CExplorerTree*)lParam;
SHGetPathFromIDList(p1,name1.GetBuffer(MAX_PATH));
name1.ReleaseBuffer();
SHGetPathFromIDList(p2,name2.GetBuffer(MAX_PATH));
name2.ReleaseBuffer();
if(name1.IsEmpty()&&name2.IsEmpty()){
pTree->GetItemName(pTree->lpDesktop,p1,name1);
pTree->GetItemName(pTree->lpDesktop,p2,name2);
}
if(name1.IsEmpty()&&!name2.IsEmpty())
return 1;
if(name2.IsEmpty()&&!name1.IsEmpty())
return -1;
return strcmpi(name1,name2);
}
void CExplorerTree::ExpandTree(HTREEITEM item)
{
LPFILEITEM pItem=(LPFILEITEM)GetItemData(item);
if(ItemHasChildren(item)){
HTREEITEM hChildItem = GetChildItem(item);
while (hChildItem != NULL)
{
LPFILEITEM pItem=(LPFILEITEM)GetItemData(hChildItem);
if(!pItem->bListed)
ListFolder(hChildItem);
hChildItem = GetNextItem(hChildItem, TVGN_NEXT);
}
}
//	RedrawWindow();
}
BOOL CExplorerTree::ItemIsFileSystem(LPITEMIDLIST pidl)
{
SHFILEINFO sfi;
UINT flag=(SHGFI_ATTRIBUTES|SHGFI_PIDL);
SHGetFileInfo((LPCTSTR)pidl,0,&sfi,sizeof(SHFILEINFO),flag);
return TRUE;//(sfi.dwAttributes&(SFGAO_FILESYSTEM|SFGAO_FILESYSANCESTOR));
}
HTREEITEM CExplorerTree::GetItemFromPath(CString &path)
{
USES_CONVERSION;
LPITEMIDLIST pidl;
/*	if(pidl!=NULL){
HTREEITEM item=FindPath(GetRootItem(),pidl);
lpMalloc->Free(pidl);
return item;
}
else
return NULL;
*/
CString xx;
HTREEITEM item=GetRootItem();
int index=0;
do{
index=path.Find("\\",index+1);
if(index!=-1)
xx=path.Left(index+1);
else
xx=path;
if(NOERROR!=lpDesktop->ParseDisplayName(0,0,A2W(xx),0,&pidl,0))
return NULL;
item=FindPath(item,pidl);
if(item)
ExpandTree(GetParentItem(item));
lpMalloc->Free(pidl);
}while(xx!=path);
return item;
}
HTREEITEM CExplorerTree::FindPath(HTREEITEM item, LPITEMIDLIST &pidl)
{
LPFILEITEM pItem=(LPFILEITEM)GetItemData(item);
CString text=GetItemText(item);
if(EqualPIDL(pItem->pidl,pidl))
return item;
if(!ItemHasChildren(item))
return NULL;
HTREEITEM hFound=NULL;
HTREEITEM hChildItem = GetChildItem(item);
while (hChildItem != NULL)
{
text=GetItemText(hChildItem);
hFound=FindPath(hChildItem,pidl);
if(hFound!=NULL)
break;
hChildItem = GetNextItem(hChildItem, TVGN_NEXT);
}
return hFound;
}
BOOL CExplorerTree::EqualPIDL(LPITEMIDLIST &pidl1, LPITEMIDLIST &pidl2)
{
UINT sz=GetSize(pidl1);
if(sz!=GetSize(pidl2))
return FALSE;
BYTE* p1=(BYTE*)pidl1;
BYTE* p2=(BYTE*)pidl2;
for(UINT i=0;i<sz;i++){
if(*p1++!=*p2++)
return FALSE;
}
return TRUE;
}
posted @ 2009-04-01 08:36  宇晨  阅读(523)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3