ShellFolder, lpidl, SHGDN_FORPARSING, lpfpl->cForParsing); GetName(pShellFolder, lpidl, SHGDN_INFOLDER, lpfpl->cInFolder); // 取得的COM接口一定要释放 if(bRelease) pShellFolder->Release(); } ///////////////////////////////////////////////////////////////////////////// // CShellFolderView
IMPLEMENT_DYNCREATE(CShellFolderView, CTreeView) CShellFolderView::CShellFolderView() { // 取得内存分配的COM接口, 这里一定要成功,否则接下来的程序中无法分配空间 VERIFY(SHGetMalloc(&m_pMalloc)==NOERROR); } CShellFolderView::~CShellFolderView() { // 释放IMalloc接口 m_pMalloc->Release(); } BEGIN_MESSAGE_MAP(CShellFolderView, CTreeView) //{{AFX_MSG_MAP(CShellFolderView) ON_WM_CREATE() ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding) ON_WM_DESTROY() //}}AFX_MSG_MAP ON_MESSAGE(WM_U_FOLDERCHANGED, OnFolderChanged) END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////// // CShellFolderView drawing //void CShellFolderView::OnDraw(CDC* pDC) //{ // CDocument* pDoc = GetDocument(); // TODO: add draw code here //} ///////////////////////////////////////////////////////////////////////////// // CShellFolderView diagnostics #ifdef _DEBUG void CShellFolderView::AssertValid() const { CTreeView::AssertValid(); } void CShellFolderView::Dump(CDumpContext& dc) const { CTreeView::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CShellFolderView message handlers int CShellFolderView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CTreeView::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here // 设置树控件的风格:带有展开按钮,结点间有连线 GetTreeCtrl().ModifyStyle(0, TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT); RetrieveSysImageList(); // 取得系统图标列表 // 显示桌面虚拟文件夹 ShowDesktop(); return 0; } // 当某个结点将要被展开前 void CShellFolderView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; // TODO: Add your control notification handler code here // 如果是展开操作 if(pNMTreeView->action == TVE_EXPAND) { // 如果被展开的结点还没有子结点则为该结点附加它的子结点 // 我们不能一开始就将所有的结点添加上去,这将是一个漫长的过程,且浪费 // 大量的系统资源,只有那些被展开的结点才需要显示其子结点 if(GetTreeCtrl().GetChildItem(pNMTreeView->itemNew.hItem) == NULL) { AttachFolders(pNMTreeView->itemNew.hItem); } } *pResult = 0; *pResult = 0; } void CShellFolderView::OnDestroy() { // 释放所有的结点 FreeNode(NULL); CTreeView::OnDestroy(); } // 当被监视的文件夹发生变化时,该消息被监视线程发送过来 LRESULT CShellFolderView::OnFolderChanged(WPARAM wParam, LPARAM) { // 变化对应的结点句柄 HTREEITEM hNode = (HTREEITEM)wParam; CTreeCtrl& tree = GetTreeCtrl(); // 视图上的树控件 // 保存该结点的状态(是否是已经展开的) BOOL bExpanded = tree.GetItemState(hNode, TVIS_EXPANDED) == TVIS_EXPANDED; // 它的子结点 HTREEITEM hChild = tree.GetChildItem(hNode); // 删除该结点下的所有子结点 while(hChild != NULL) { HTREEITEM hCur = hChild; hChild = tree.GetNextSiblingItem(hChild); // 下一个子结点 FreeNode(hCur); tree.DeleteItem(hCur); } // 重新生成子结点. AttachFolders(hNode); // 恢复展开状态(如果以前是展开的) if(bExpanded) tree.Expand(hNode, TVE_EXPAND); return 0; } ////////////////////////////////////////////////////////////////// // protected member function // 获取系统图标列表 void CShellFolderView::RetrieveSysImageList() { PATHINFO DesktopInfo; SHFILEINFO FileInfo; CString strDesktop; GetSpecialFolder(CSIDL_DESKTOPDIRECTORY, &DesktopInfo); // SHGetFileInfo函数的返回值就是系统图标列表的句柄(可参考MSDN) HIMAGELIST hSysImageList = (HIMAGELIST)::SHGetFileInfo( (LPCTSTR)DesktopInfo.pidl, 0, &FileInfo, sizeof(FileInfo), SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON); // 设置重叠图标 // 设置1号重叠图标对应图标列表中索引为0的图标,这是一个手托,象征被共享的文件夹 // 设置2号重叠图标对应图标列表中索引为1的图标,这是一个箭头,象征快捷方式 // 设置3号重叠图标对应图标列表中索引为2的图标,这个图标我研究了好长时间也没看出来是个什么东东 ImageList_SetOverlayImage(hSysImageList, 0,1); ImageList_SetOverlayImage(hSysImageList, 1,2); ImageList_SetOverlayImage(hSysImageList, 2,3); // 树控件就使用这个图标列表 GetTreeCtrl().SetImageList(CImageList::FromHandle(hSysImageList),TVSIL_NORMAL); } // 获取特殊的文件夹信息 void CShellFolderView::GetSpecialFolder(int nFolder, LPPATHINFO lppi) { LPITEMIDLIST lpidl = NULL; // 取得该文件夹的PIDL if(SUCCEEDED(SHGetSpecialFolderLocation(m_hWnd, nFolder, &lpidl))) { lppi->pidl = lpidl; // Get the actual path of the directory from the PItemIDList SHGetPathFromIDList(lpidl, lppi->cPath); // Do it // Get the Normal Image index SHFILEINFO shfi; SHGetFileInfo((LPCTSTR)lpidl, SFGAO_SHARE, &shfi, sizeof(shfi), SHGFI_PIDL | SHGFI_SYSICONINDEX); lppi->uIconIndex = shfi.iIcon; // Get the selected image index SHGetFileInfo((LPCTSTR)lpidl, SFGAO_SHARE, &shfi, sizeof(shfi), SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_OPENICON); lppi->uSelectedIndex = shfi.iIcon; } } void CShellFolderView::GetNetHood(LPPATHINFO lpPI) { FILEPATHLIST fpl; GetSpecialFolder(CSIDL_NETWORK, lpPI); GetLongFilePath(NULL, lpPI->pidl, &fpl); strcpy(lpPI->cText, fpl.cNormal); } // CreateFolderNode creates a Folder_Node and inserts it under // the "parent" node (if any), using the last of the path // string as the Name, and setting the new node''''s text // property to match. HTREEITEM CShellFolderView::CreateFolderNode( LPITEMIDLIST lpidl, // 文件夹的PIDL HTREEITEM hParent, // 父结点 BOOL bVirtual) // 是否包含虚拟文件夹 { CTreeCtrl& tree = GetTreeCtrl(); LPFOLDERNODE lpfnParent = NULL; FILEPATHLIST fpl; // 父结点的信息 if(hParent != NULL) { lpfnParent = (LPFOLDERNODE)tree.GetItemData(hParent); GetLongFilePath(lpfnParent->pShellFolder, lpidl, &fpl); } else { GetLongFilePath(NULL, lpidl, &fpl); } CString strFileName(fpl.cInFolder); // 相对名字 CString strPath(fpl.cForParsing); // 法定名字 // 以"::"开头的,是一些特殊的文件夹,普通的目录或文件的名称中是不能包含":"字符的 // 打印出来看看都是些什么东东 if(strncmp(fpl.cForParsing, "::", 2) ==0) { &nb 上一页 [1] [2] [3] [4] [5] [6] 下一页 [办公软件]在sybase中插入图片、PDF、文本文件 [办公软件]安装Sybase ASE [办公软件]linux指令大全(完整篇) [办公软件]Linux新手入门常用命令大全 [办公软件]在RedHat Linux 9里安装gaim0.80 [办公软件]浅谈Linux 下Java 1.5 汉字方块问题解决方法 [办公软件]Linux程序员必读:中文化与GB18030标准 [办公软件]linux指令大全 [办公软件]制作Linux启动盘的四种方法 [办公软件]Linux文件系统的反删除方法
|