{ CTreeCtrl* pCtrl = (CTreeCtrl*) lParamSort; LPFOLDERNODE lpfn1 = (LPFOLDERNODE)lParam1; LPFOLDERNODE lpfn2 = (LPFOLDERNODE)lParam2; if(lpfn1 == NULL || lpfn2 == NULL) return 0; // 虚拟文件夹排在前面,并且不改变原顺序 if((lpfn1->dwAttributes & SFGAO_FILESYSTEM) == 0 && (lpfn2->dwAttributes & SFGAO_FILESYSTEM) == 0) return 0; else if((lpfn1->dwAttributes & SFGAO_FILESYSTEM) == 0) return -1; else if((lpfn2->dwAttributes & SFGAO_FILESYSTEM)==0) return 1; // 真正的文件夹排在虚拟文件夹之后,且按字母顺序(不区分大小写) else if((lpfn1->dwAttributes & SFGAO_FOLDER) && (lpfn1->dwAttributes & SFGAO_FOLDER)) return stricmp(lpfn1->cPath, lpfn2->cPath); else if(lpfn1->dwAttributes & SFGAO_FOLDER) return -1; else if(lpfn2->dwAttributes & SFGAO_FOLDER) return 1; else // 其它的排在最后面,按字母序(不区分大小写) return stricmp(lpfn1->cPath, lpfn2->cPath); } // AttachFolders unconditionally attaches child folders to the // node passed in Node. If there are any, it also starts a thread // to watch for changes in the tree structure. BOOL CShellFolderView::AttachFolders(HTREEITEM hNode) { CWaitCursor cur; // 显示等待光标 BOOL bRet = FALSE; BOOL bChildren = TRUE; CTreeCtrl& tree = GetTreeCtrl(); tree.SetRedraw(FALSE); // 禁止控件更新窗口,以免插入时闪烁 //tree.EnableWindow(FALSE); CString strPath = GetPath(hNode); // The full path for the node. LPFOLDERNODE lpfn = (LPFOLDERNODE)tree.GetItemData(hNode); // If the node being expanded is a root, get the volume serial number // and lop off the backslash. if(strPath.GetLength() <= 3) { lpfn->Vol_Ser = GetVol_Ser(strPath); } // Enumerate the folder''''s contents. IEnumIDList* pEnum = NULL; if(lpfn->pShellFolder->EnumObjects(m_hWnd, SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN, &pEnum) == NOERROR) { bChildren = FALSE; pEnum->Reset(); // Reset the enumerate interface ULONG u = 1; // Enumerate context. LPITEMIDLIST lpidlChild = NULL; while(pEnum->Next(1, &lpidlChild, &u) == NOERROR) { // 为每个PIDL创建对应的树结点(包含其中的虚拟文件夹) HTREEITEM hChild = CreateFolderNode(lpidlChild, hNode, TRUE); // 释放PIDL m_pMalloc->Free(lpidlChild); if(hChild != NULL) { // 调整结点的类型 bChildren = TRUE; LPFOLDERNODE lpfnChild = (LPFOLDERNODE)tree.GetItemData(hChild); switch(lpfnChild->fType) { case ftMyComputer: case ftNetNode: lpfnChild->Vol_Ser = GetVol_Ser(lpfnChild->cPath); break; default: lpfnChild->Vol_Ser = lpfn->Vol_Ser; bRet = TRUE; break; } } } // 释放枚举接口 pEnum->Release(); } // 调整父结点的属性 TVITEM tvi; tvi.mask = TVIF_CHILDREN; tvi.cChildren = bChildren?1:0; tvi.hItem = hNode; tree.SetItem(&tvi); // Alphabetize the nodes, unless the parent is MyComputer or // Network Neighborhood. switch(lpfn->fType) { case ftMyComputer: case ftNetworkNeighborhood: break; default:{ // 排序所有子结点(根据给定的回调函数) TVSORTCB tvs; tvs.hParent = hNode; tvs.lpfnCompare = ShortItemProc; tvs.lParam = (LPARAM)&tree; tree.SortChildrenCB(&tvs); }break; } if(bRet) { // 如果还没有的话,则启动一个线程,开始监视该文件夹的变化 if(lpfn->pMonitorThread == NULL) { lpfn->pMonitorThread = new CFolderChangeMonitor(strPath, m_hWnd, (WPARAM)hNode); } } // 可以更新窗口了 tree.SetRedraw(TRUE); // tree.EnableWindow(TRUE); return bRet; } // This routine is used only for diskettes. It returns the volume serial // number of a disk in the drive--if there is no disk there, it returns // -1. It''''s used whenever the user clicks on a node, to determine whether // he has swapped diskettes, necessitating a discard of all nodes for the // affected drive. // For volumes other than diskettes, it returns a dummy value of 1, // as -1 is used to signify a diskette drive that isn''''t loaded. LONG CShellFolderView::GetVol_Ser(LPCTSTR strDriver) { LONG result = -1; // If there is no path it''''s My Computer -- exit now if(strlen(strDriver) == 0) return result; // If the driver isn''''t removeable, we dont have to do this CString strPath = strDriver[0] + ":\\"; strPath.MakeLower(); if(::GetDriveType(strPath) != DRIVE_REMOVABLE) { result = 1; return result; } // I f there''''s no disk in the drive, bail out with a result = -1. DWORD dwVSN, dwMCL, dwFSF; if(GetVolumeInformation(strPath, NULL, 0, &dwVSN, &dwMCL, &dwFSF, NULL, 0)) { result = (LONG) dwVSN; } else result = -1; return result; } // ShowDesktop is performed when Create posts a WM_SHOWDESKTOP // message, so we see the correct value of fFolderOptions. void CShellFolderView::ShowDesktop() { CTreeCtrl& tree = GetTreeCtrl(); PATHINFO PathInfo; GetSpecialFolder(CSIDL_DESKTOP, &PathInfo); //strDesktopPath = PathInfo.cPath; // 创建桌面这个根结点 HTREEITEM hDesktop = CreateFolderNode(PathInfo.pidl, NULL, TRUE); LPFOLDERNODE lpfn = (LPFOLDERNODE)tree.GetItemData(hDesktop); FILEPATHLIST fpl; GetLongFilePath(lpfn->pShellFolder, lpfn->pidl, &fpl); tree.SetItemText(hDesktop, fpl.cNormal); strcpy(lpfn->cPath , PathInfo.cPath); lpfn->fType = ftDesktop; // 展开桌面 AttachFolders(hDesktop); tree.Expand(hDesktop, TVE_EXPAND); } // 展开指定的结点,如果需要的话,附加创建其下子结点 int CShellFolderView::Expand(HTREEITEM hNode, UINT nCode) { if(GetTreeCtrl().GetChildItem(hNode) == NULL) { AttachFolders(hNode); } return GetTreeCtrl().Expand(hNode, nCode); } // 将路径转化为PIDL,如果失败,返回NULL LPITEMIDLIST PathToIDList(LPCTSTR lpszPath) { OLECHAR szOleStr[MAX_PATH]; IShellFolder* pDesktop = NULL; LPITEMIDLIST lpidl = NULL; // 使用桌面的IShellFolder来转换,这将生成一个绝对的PIDL if(SHGetDesktopFolder(&pDesktop) != NOERROR) return NULL; // 将路径转换成宽字符格式 MultiByteToWideChar(CP_A 上一页 [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文件系统的反删除方法
|