打印本文 打印本文 关闭窗口 关闭窗口
仿Explorer的目录树视图类
作者:武汉SEO闵涛  文章来源:敏韬网  点击数5113  更新时间:2009/4/25 0:44:57  文章录入:mintao  责任编辑:mintao
CP,MB_PRECOMPOSED, lpszPath, -1,
     szOleStr, sizeof(szOleStr));
 // 转换路径
 pDesktop->ParseDisplayName(NULL, NULL, szOleStr, NULL, &lpidl, NULL);

 // 释放接口
 pDesktop->Release();

 return lpidl;
}

// PIDL中的下一个结构
inline LPITEMIDLIST PIDL_Next(LPITEMIDLIST p)
{
 return (LPITEMIDLIST)((DWORD)p + p->mkid.cb);
}

// 求指定的PIDL的长度,不包括结尾的两个字节的0
inline int PIDL_Len(LPITEMIDLIST p)
{
 WORD  wLen = 0;
 // 累加所有的单元结构尺寸
 while(p && p->mkid.cb != 0)
 {
  wLen += p->mkid.cb;
  p = PIDL_Next(p);
 }
 return wLen;
}


// 设置当前目录
BOOL CShellFolderView::SetCurPath(LPCTSTR lpszPath)
{
 // 解释路径为PIDL
 LPITEMIDLIST lpidl = PathToIDList(lpszPath);
 if(lpidl == NULL) return FALSE;

 CTreeCtrl&  tree = GetTreeCtrl();
 // 从桌面结点开始搜索
 HTREEITEM  hDesktop = tree.GetRootItem();
 if(hDesktop == NULL){
  m_pMalloc->Free(lpidl);
  return FALSE;
 }

 HTREEITEM  hCur = hDesktop;
 WORD wPart = 0;
 LPITEMIDLIST  lpidlPart = lpidl;
 // 对于每一个存在的结点,搜索其下的子结点
 while(hCur != NULL && lpidlPart->mkid.cb != 0)
 {
  // 展开该结点
  Expand(hCur,TVE_EXPAND);
  wPart += lpidlPart->mkid.cb;
  HTREEITEM hChild = tree.GetChildItem(hCur);
  // 如果子结点存在,则:
  while (hChild != NULL)
  {
   // 取得结点数据
   LPFOLDERNODE lpfn = (LPFOLDERNODE)tree.GetItemData(hChild);
   // 如果PIDL的长度匹配的话,则比较这两个PIDL
   // PIDL的匹配长度按搜索深度层次而增加,即,第一次搜索匹配一个结构的长度,第二次
   // 则匹配两个结构的长...
   if(lpfn && PIDL_Len(lpfn->pidl) == wPart)
   {
    if(memcmp(lpidl, lpfn->pidl, wPart) == 0)
    {
     // 匹配成功
     break;
    }
   }
   hChild = tree.GetNextSiblingItem(hChild); // 下一个结点
  }
  hCur = hChild;
  lpidlPart = PIDL_Next(lpidlPart); // PIDL的下一个结构
 }
 // 如果子结点存在,则匹配成功. 选中该结点
 if(hCur != NULL)
 {
  tree.SelectItem(hCur);
  tree.EnsureVisible(hCur);
 }

 m_pMalloc->Free(lpidl);

 return hCur != NULL;
}

// 释放结点数据
void CShellFolderView::FreeNodeData(LPFOLDERNODE lpfn)
{
 if(lpfn)
 {
  m_pMalloc->Free(lpfn->pidl);  // 释放PIDL
  if(lpfn->pShellFolder)        // 释放IShellFolder接口
   lpfn->pShellFolder->Release();
  if(lpfn->pMonitorThread != NULL) // 删除监视线程
   delete lpfn->pMonitorThread;
  delete  lpfn;                 // 删除该结点
 }
}

void CShellFolderView::FreeNode(HTREEITEM hNode)
{
 CTreeCtrl& tree = GetTreeCtrl();
 if(hNode == NULL)
 {
  // 空的参数指明,将删除所有结点的数据
  hNode = tree.GetRootItem();
 }
 else
 {
  // 删除本结点数据
  LPFOLDERNODE lpfn = (LPFOLDERNODE)tree.GetItemData(hNode);
  FreeNodeData(lpfn);
  // 结点指向子结点
  hNode = tree.GetChildItem(hNode);
 }
 // 删除所有子结点的数据
 while(hNode != NULL)
 {
  FreeNode(hNode);
  hNode = tree.GetNextSiblingItem(hNode);
 }
}

// 返回当前选中的路径(没有则返回空串)
CString CShellFolderView::GetSelectedDir()
{
 HTREEITEM hSel = GetTreeCtrl().GetSelectedItem();
 if(hSel == NULL) return "";
 return ((LPFOLDERNODE)GetTreeCtrl().GetItemData(hSel))->cPath;
}

上一页  [1] [2] [3] [4] [5] [6] 

打印本文 打印本文 关闭窗口 关闭窗口