一、几个概念(摘)
1.外壳名字空间:
在WINDOWS中又叫外壳名字空间(Shell Name Space).外壳名字空间是Windows下的标准文件系统,它大大扩展了Dos文件系统,形成了以“桌面”(Desktop)为根的单一的文件系统树,原有的C盘、D盘等目录树变成“我的电脑”这一外壳名字空间子树的下一级子树,而像“控制面板”、“回收站”、“网上邻居”等应用程序及“打印机”等设备也被虚拟成了外壳名字空间中的节点。另外,与DOS中物理存储只能和文件系统项一一对应这一点不同的是,一个实际目录在外壳名字空间中可以表现为不同的项。例如“我的文档”与“C:/MyDocuments”其实都指向“C:/My Documents”目录,但它们在外壳名字空间中是不同的项。
2. 外壳名字空间下的路径: PIDL
PIDL是一个元素类型为ITEMIDLIST结构的数组,数组中元素的个数是未知的,但紧接着数组末尾的必是一个双字节的零。每个数组元素代表了外壳名字空间树中的一层(即一个文件夹或文件),数组中的前一元素代表的是后一元素的父文件夹。由此可见, PIDL实际上就是指向一块由若干个顺序排列的ITEMIDLIST结构组成、并在最后有一个双字节零的空间的指针。所以PIDL的类型就被Windows定义为ITEMIDLIST结构的指针。
PIDL亦有“绝对路径”与“相对路径”的概念。表示“相对路径”的PIDL只有一个ITEMIDLIST结构的元素,用于标识相对于父文件夹的“路径”;表示“绝对路径”的PIDL(简称为“绝对PIDL”)有若干个ITEMIDLIST结构的元素,第一个元素表示外壳名字空间根文件夹(“桌面”)下的某一子文件夹A,第二个元素则表示文件夹A下的某一子文件夹B,其余依此类推。这样绝对PIDL就通过保存一条从“桌面”下的直接子文件夹或文件的绝对PIDL与相对PIDL是相同的,而其他的文件夹或文件的相对PIDL就只是其绝对PIDL的最后一部分了。由于所有的PIDL都是从桌面下的某一个子文件夹开始的,所以对于桌面本身来说,它的PIDL数组显然一个元素都没有。这样就只剩下PIDL数组最后的那个双字节的零了。所以,“桌面”的PIDL就是一个16位的零。
二、几个API
1.HRESULT SHGetSpecialFolderLocation(
HWND hwndOwner,
int nFolder, //CSIDL
LPITEMIDLIST *ppidl //返回CSIDL所对应的绝对PIDL(输出)
);
2.DWORD_PTR SHGetFileInfo(
LPCTSTR pszPath, //uFlags含SHGFI_PIDL时为绝对PIDL(输入)
DWORD dwFileAttributes, //绝对PIDL所对应文件的 file attribute flags (输出)
SHFILEINFO *psfi, //返回file information
UINT cbFileInfo, //SHFILEINFO结构大 UINT uFlags //指定你所要获取的信息
); //该函数返回系统HIMAGELIST
说明:
typedef struct _SHFILEINFO {
HICON hIcon;
int iIcon; //图标索引
DWORD dwAttributes; //文件属性
TCHAR szDisplayName[MAX_PATH]; // 显示名称
TCHAR szTypeName[80]; //文件类型:一个值对应一个二进制位
} SHFILEINFO;
uFlags :SHGFI_DISPLAYNAME | SHGFI_TYPENAME :psfi返回中包含显示名称和文件类型 (其他类推)
3.HRESULT SHGetDesktopFolder(
IShellFolder** ppshf //f返回桌面IShellFolder接口
);
IShellFolder的几个方法:
(1).BingToObject 获取子文件夹的IShellFolder接口
(2).EnumObject获取IEnumIDList ,IEnumIDList ->Next方法获取子文件的相对PIDL(详见MSDN)
(3)GetAttributesOf获取文件属性
注意事项:参数中是绝对PIDL还是相对PIDL。SHGet绝对,IShellFolder相对。PIDL用IMalloc接口开辟空间
三、仿系统目录树
注:本程序在VS2005编译通过(存在小Bug:树节点的加号要展开后才显示,待修改)。
下面是原码
//
BrowseSysTreeDlg.h : 头文件
//
#pragma
once
#include
"
afxcmn.h
"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
//
CBrowseSysTreeDlg 对话框
class
CBrowseSysTreeDlg :
public
CDialog
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
// 构造
public:
CBrowseSysTreeDlg(CWnd* pParent = NULL); // 标准构造函数
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// 对话框数据
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
enum ...{ IDD = IDD_BROWSESYSTREE_DIALOG };
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//添加
protected:
HTREEITEM CreateFolderNode(LPITEMIDLIST lpPidl,HTREEITEM hParent);
BOOL AttachFolders(HTREEITEM hNode);
void FreeNode(HTREEITEM hNode);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// 实现
protected:
HICON m_hIcon;
CTreeCtrl m_ctrlTree;
CImageList m_imageList;
IMalloc* m_pMalloc;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public:
afx_msg void OnNMDblclkSysTree(NMHDR *pNMHDR, LRESULT *pResult);
public:
afx_msg void OnTvnItemexpandingSysTree(NMHDR *pNMHDR, LRESULT *pResult);
public:
afx_msg void OnDestroy();
}
;
//
BrowseSysTreeDlg.cpp : 实现文件
//
#include
"
stdafx.h
"
#include
"
BrowseSysTree.h
"
#include
"
BrowseSysTreeDlg.h
"
#include
"
shlobj.h
"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#ifdef _DEBUG
#define
new DEBUG_NEW
#endif
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
//
用于应用程序“关于”菜单项的 CAboutDlg 对话框
class
CAboutDlg :
public
CDialog
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
public:
CAboutDlg();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// 对话框数据
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
enum ...{ IDD = IDD_ABOUTBOX };
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// 实现
protected:
DECLARE_MESSAGE_MAP()
}
;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void
CAboutDlg::DoDataExchange(CDataExchange
*
pDX)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
CDialog::DoDataExchange(pDX);
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
//
CBrowseSysTreeDlg 对话框
typedef
struct
_NodeInfo
//
节点信息
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
TCHAR szName[MAX_PATH]; //显示的名称
UINT uIcon; //图标
ULONG dwAttributes; //属性
TCHAR szPath[MAX_PATH]; //路径
LPITEMIDLIST lpPidl; //PIDL
WORD wPidlLen; //PLID的长度
IShellFolder* pShellFolder; //指向该节点的IShellFolder接口
BOOL bHasParent; //是否有父节点
}
NODEINFO,
*
LPNODEINFO;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
HTREEITEM CBrowseSysTreeDlg::CreateFolderNode(LPITEMIDLIST lpPidl, HTREEITEM hParent)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
LPNODEINFO lpParentNodeInfo = NULL;
IShellFolder* pShellFolder = NULL;
TCHAR szName[MAX_PATH];
BOOL bRelease = FALSE;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if (NULL != hParent) //获取父IShellFolder接口
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
lpParentNodeInfo = (LPNODEINFO) m_ctrlTree.GetItemData(hParent);
pShellFolder = lpParentNodeInfo->pShellFolder;
}
else //没有父节点,则取桌面IShellFolder
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
::SHGetDesktopFolder(&pShellFolder);
bRelease = TRUE;
if (NULL == pShellFolder)
return NULL;
}
//获取属性
ULONG Attributes = SFGAO_SHARE | SFGAO_FILESYSTEM |
SFGAO_LINK | SFGAO_HASSUBFOLDER;
if(lpParentNodeInfo == NULL || pShellFolder->GetAttributesOf(1,(LPCITEMIDLIST*)&lpPidl, &Attributes) != NOERROR)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
Attributes = 0;
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//长度
WORD wParentPidlLen = 0;
LPITEMIDLIST lpPidlParent;
if (NULL != lpParentNodeInfo)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
wParentPidlLen = lpParentNodeInfo->wPidlLen;
lpPidlParent = lpParentNodeInfo->lpPidl;
}
// 使用IMalloc接口分配新PIDL需要的空间.
LPITEMIDLIST lpPidlNew = (LPITEMIDLIST)m_pMalloc->Alloc(lpPidl->mkid.cb + wParentPidlLen + 2);
if(wParentPidlLen != 0)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
memcpy(lpPidlNew, lpPidlParent, wParentPidlLen);
memcpy((char*)lpPidlNew+wParentPidlLen, lpPidl,lpPidl->mkid.cb);
}
else
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
memcpy(lpPidlNew, lpPidl, lpPidl->mkid.cb);
}
*(WORD*)((char*)lpPidlNew + wParentPidlLen + lpPidl->mkid.cb) = 0;
LPITEMIDLIST lpPidlTemp = lpPidlNew;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//获取显示图标
SHFILEINFO shif;
UINT uIcon;
UINT uSelectedIcon;
::SHGetFileInfo((LPCWSTR)lpPidlTemp, 0, &shif, sizeof(shif),
SHGFI_PIDL | SHGFI_SYSICONINDEX);
uIcon = shif.iIcon;
::SHGetFileInfo((LPCWSTR)lpPidlTemp, 0, &shif, sizeof(shif),
SHGFI_PIDL | SHGFI_SYSICONINDEX|SHGFI_OPENICON|SHGFI_DISPLAYNAME);
uSelectedIcon = shif.iIcon;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//获取路径
TCHAR szPath[MAX_PATH];
::SHGetPathFromIDList(lpPidlTemp, szPath);
lstrcpy(szName, shif.szDisplayName); //取得显示名称
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//获取节点IShellFolder
IShellFolder* pShellFolderNew = NULL;
pShellFolder->BindToObject(lpPidl, NULL, IID_IShellFolder,(void**) &pShellFolderNew);
//建立新节点
LPNODEINFO lpNodeInfoNew = new NODEINFO;
lpNodeInfoNew->bHasParent = (hParent != NULL);
lpNodeInfoNew->dwAttributes = Attributes;
lpNodeInfoNew->lpPidl = lpPidlNew;
if (NULL == hParent)
lpNodeInfoNew->pShellFolder = pShellFolder;
else
lpNodeInfoNew->pShellFolder = pShellFolderNew;
memcpy(lpNodeInfoNew->szName, szName, sizeof(szName));
memcpy(lpNodeInfoNew->szPath, szPath, sizeof(szPath));
lpNodeInfoNew->uIcon = uIcon;
lpNodeInfoNew->wPidlLen = wParentPidlLen + lpPidl->mkid.cb;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//建立树视图插入结构
TVINSERTSTRUCT tvis;
tvis.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE |
TVIF_STATE | TVIF_PARAM;
if(Attributes & SFGAO_HASSUBFOLDER)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
tvis.item.mask |= TVIF_CHILDREN;
tvis.item.cChildren = I_CHILDRENCALLBACK;
// 使用 I_CHILDRENCALLBACK 值告诉控件,该结点有子结点,但具体的结点还没给出
// 当该结点被展开时就会通知父窗口.这时你应该为该结点添加子结点
}
else
tvis.item.cChildren = 0;
tvis.item.stateMask = TVIS_OVERLAYMASK; // 指明状态标志包含覆盖图标
tvis.hInsertAfter = TVI_LAST;
tvis.hParent = hParent;
tvis.item.iImage =uIcon;
tvis.item.iSelectedImage = uSelectedIcon;
tvis.item.lParam = (DWORD)lpNodeInfoNew;
tvis.item.cchTextMax =MAX_PATH;
tvis.item.pszText = szName;
tvis.item.stateMask = TVIS_OVERLAYMASK;
// 设置覆盖图标
if(Attributes & SFGAO_SHARE) // 共享的
tvis.item.state = INDEXTOOVERLAYMASK(1);
else if(Attributes & SFGAO_LINK) // 快捷方式
tvis.item.state = INDEXTOOVERLAYMASK(2);
else // 其它的
tvis.item.state = INDEXTOOVERLAYMASK(0);
HTREEITEM hIns = m_ctrlTree.InsertItem(&tvis); // 插入该结点
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if(bRelease) //释放桌面IShellFolder
pShellFolder->Release();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return hIns;
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
BOOL CBrowseSysTreeDlg::AttachFolders(HTREEITEM hNode)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
CWaitCursor cur; // 显示等待光标
BOOL bRet = FALSE;
BOOL bChildren = FALSE;
m_ctrlTree.SetRedraw(FALSE); // 禁止控件更新窗口,以免插入时闪烁
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
LPNODEINFO lpfn = (LPNODEINFO)m_ctrlTree.GetItemData(hNode);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
IEnumIDList* pEnum = NULL;
if(lpfn->pShellFolder->EnumObjects(m_hWnd, SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN,
&pEnum) == NOERROR)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
bChildren = FALSE;
pEnum->Reset();
ULONG u = 1;
LPITEMIDLIST lpidlChild = NULL;
while(pEnum->Next(1, &lpidlChild, &u) == NOERROR)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
// 为每个PIDL创建对应的树结点(包含其中的虚拟文件夹)
HTREEITEM hChild = CreateFolderNode(lpidlChild, hNode);
if(hChild != NULL)
bChildren = TRUE;
}
// 释放枚举接口
pEnum->Release();
// 调整父结点的属性
if (TRUE == bChildren)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
TVITEM tvi;
tvi.mask = TVIF_CHILDREN;
tvi.hItem = hNode;
m_ctrlTree.SetItem(&tvi);
}
}
// 可以更新窗口了
m_ctrlTree.SetRedraw(TRUE);
return TRUE;
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void
CBrowseSysTreeDlg::FreeNode(HTREEITEM hNode)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
if (NULL == hNode)
hNode = m_ctrlTree.GetRootItem();
else
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
LPNODEINFO lpNodeInfo = (LPNODEINFO)m_ctrlTree.GetItemData(hNode);
if (NULL != lpNodeInfo->pShellFolder)
lpNodeInfo->pShellFolder->Release();
m_pMalloc->Free(lpNodeInfo->lpPidl);
delete lpNodeInfo;
hNode = m_ctrlTree.GetChildItem(hNode);
}
while (NULL != hNode)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
FreeNode(hNode);
hNode = m_ctrlTree.GetNextSiblingItem(hNode);
}
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
CBrowseSysTreeDlg::CBrowseSysTreeDlg(CWnd
*
pParent
/**/
/*=NULL*/
)
: CDialog(CBrowseSysTreeDlg::IDD, pParent)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
VERIFY(SHGetMalloc(&m_pMalloc)==NOERROR);
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void
CBrowseSysTreeDlg::DoDataExchange(CDataExchange
*
pDX)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_SYS_TREE, m_ctrlTree);
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
BEGIN_MESSAGE_MAP(CBrowseSysTreeDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//
}}AFX_MSG_MAP
ON_NOTIFY(NM_DBLCLK, IDC_SYS_TREE,
&
CBrowseSysTreeDlg::OnNMDblclkSysTree)
ON_NOTIFY(TVN_ITEMEXPANDING, IDC_SYS_TREE,
&
CBrowseSysTreeDlg::OnTvnItemexpandingSysTree)
ON_WM_DESTROY()
END_MESSAGE_MAP()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
//
CBrowseSysTreeDlg 消息处理程序
BOOL CBrowseSysTreeDlg::OnInitDialog()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
CDialog::OnInitDialog();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// 将“关于...”菜单项添加到系统菜单中。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
CMenu* pSysMenu = GetSystemMenu(NULL);
if (pSysMenu != NULL)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, NULL); // 设置小图标
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// TODO: 在此添加额外的初始化代码
LPITEMIDLIST lpPidl;
HIMAGELIST hSysImageList = NULL;
SHFILEINFO shif;
if (NOERROR != SHGetSpecialFolderLocation(m_hWnd, CSIDL_DESKTOP, &lpPidl))
return FALSE;
hSysImageList =(HIMAGELIST) ::SHGetFileInfo((LPCWSTR)lpPidl, 0, &shif, sizeof(shif),
SHGFI_PIDL | SHGFI_SMALLICON | SHGFI_SYSICONINDEX);
// 设置重叠图标
// 设置1号重叠图标对应图标列表中索引为0的图标,这是一个手托,象征被共享的文件夹
// 设置2号重叠图标对应图标列表中索引为1的图标,这是一个箭头,象征快捷方式
// 设置3号重叠图标对应图标列表中索引为2的图标,这个图标??
ImageList_SetOverlayImage(hSysImageList, 0,1);
ImageList_SetOverlayImage(hSysImageList, 1,2);
ImageList_SetOverlayImage(hSysImageList, 2,3);
m_ctrlTree.SetImageList(CImageList::FromHandle(hSysImageList),TVSIL_NORMAL);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
HTREEITEM hItem = CreateFolderNode(lpPidl, NULL);
AttachFolders(hItem);
m_ctrlTree.Expand(hItem, TVE_EXPAND);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void
CBrowseSysTreeDlg::OnSysCommand(UINT nID, LPARAM lParam)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
CDialog::OnSysCommand(nID, lParam);
}
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
//
如果向对话框添加最小化按钮,则需要下面的代码
//
来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//
这将由框架自动完成。
void
CBrowseSysTreeDlg::OnPaint()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
if (IsIconic())
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
CPaintDC dc(this); // 用于绘制的设备上下文
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// 使图标在工作矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
...{
CDialog::OnPaint();
}
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
//
当用户拖动最小化窗口时系统调用此函数取得光标显示。
//
HCURSOR CBrowseSysTreeDlg::OnQueryDragIcon()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
return static_cast<HCURSOR>(m_hIcon);
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void
CBrowseSysTreeDlg::OnNMDblclkSysTree(NMHDR
*
pNMHDR, LRESULT
*
pResult)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
// TODO: Add your control notification handler code here
HTREEITEM hItem = m_ctrlTree.GetSelectedItem();
if(m_ctrlTree.GetChildItem(hItem) == NULL)
AttachFolders(hItem);
*pResult = 0;
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void
CBrowseSysTreeDlg::OnTvnItemexpandingSysTree(NMHDR
*
pNMHDR, LRESULT
*
pResult)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: Add your control notification handler code here
if (pNMTreeView->action == TVE_EXPAND )
if(m_ctrlTree.GetChildItem(pNMTreeView->itemNew.hItem) == NULL)
AttachFolders(pNMTreeView->itemNew.hItem);
*pResult = 0;
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void
CBrowseSysTreeDlg::OnDestroy()
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
...
{
FreeNode(NULL);
m_pMalloc->Release();
delete m_pToolTipCtrl;
CDialog::OnDestroy();
// TODO: 在此处添加消息处理程序代码
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)