sp;TRACE3("<%s> = \"%s\"; // Normal = %s\n", fpl.cInFolder, fpl.cForParsing, fpl.cNormal); } // 取得属性 ULONG Attributes = SFGAO_SHARE | SFGAO_FILESYSTEM | SFGAO_LINK | SFGAO_HASSUBFOLDER; if(lpfnParent == NULL || lpfnParent->pShellFolder->GetAttributesOf( 1, (LPCITEMIDLIST*)&lpidl, &Attributes) != NOERROR) { Attributes = 0; //lpfnParent = NULL; } // 是否是一个虚拟文件夹 BOOL bVirFolder = ((Attributes & SFGAO_FILESYSTEM) == 0); if(lpfnParent != NULL) { switch(lpfnParent->fType) { case ftNetworkNeighborhood: case ftNetNode: bVirFolder = TRUE; } } if(!bVirtual && bVirFolder) return NULL; // 生成该文件夹的绝对PIDL,方法就是将相对PIDL附加到父PIDL后 WORD wParentPIDLLen = 0; LPITEMIDLIST lpidlParent = NULL; if(lpfnParent != NULL) { wParentPIDLLen = lpfnParent->widlen; lpidlParent = lpfnParent->pidl; } WORD pidlen = lpidl->mkid.cb; // 使用IMalloc接口分配新PIDL需要的空间.因为从系统API返回的PIDL // 都是通过IMalloc接口分配的空间,所以为了统一,这里也使用IMalloc来分配空间 LPITEMIDLIST lpidlNew = (LPITEMIDLIST)m_pMalloc->Alloc(pidlen + wParentPIDLLen + 2); if(wParentPIDLLen != 0) { memcpy(lpidlNew, lpidlParent, wParentPIDLLen); memcpy((char*)lpidlNew+wParentPIDLLen, lpidl,pidlen); } else { memcpy(lpidlNew, lpidl, pidlen); } *(WORD*)((char*)lpidlNew + wParentPIDLLen + pidlen) = 0; LPITEMIDLIST lpidlTemp = /*bVirFolder ? lpidl : */lpidlNew; // 获取图标索引 SHFILEINFO shfi; UINT uIcon, uSelectedIcon; ::SHGetFileInfo((LPCTSTR)lpidlTemp, SFGAO_SHARE, &shfi, sizeof(shfi), SHGFI_PIDL | SHGFI_SYSICONINDEX); uIcon = uSelectedIcon = shfi.iIcon; //if((Attributes & SFGAO_FOLDER) == SFGAO_FOLDER) { ::SHGetFileInfo((LPCTSTR)lpidlTemp, SFGAO_SHARE, &shfi, sizeof(shfi), SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_OPENICON); uSelectedIcon = shfi.iIcon; } // 一个新的结点 LPFOLDERNODE lpNewNode = new FOLDERNODE; lpNewNode->widlen = wParentPIDLLen + pidlen; lpNewNode->pidl = lpidlNew; strcpy(lpNewNode->cPath, (LPCTSTR)strPath); lpNewNode->bHasParent = (hParent != NULL); //lpNewNode->pChangeThread = NULL; //lpNewNode->VolSer = 1; // 结点的类型(只要和几个固定的名字比较一下啦) if(strPath.Compare(c_cMyComputer) == 0) lpNewNode->fType = ftMyComputer; else if(strPath.Compare(c_cNetworkNeighborhood) == 0) lpNewNode->fType = ftNetworkNeighborhood; else if(strPath.Compare(c_cRecycleBin) == 0) lpNewNode->fType = ftRecycleBin; else lpNewNode->fType = ftFolder; lpNewNode->dwAttributes = Attributes; lpNewNode->pMonitorThread = NULL; // 获取该文件夹对应的IShellFolder接口 // If this Node has no parent, it mut be the Desktop. if(lpfnParent != NULL) { lpfnParent->pShellFolder->BindToObject(lpidl, NULL, IID_IShellFolder, (void**)&lpNewNode->pShellFolder); //if(lpfnParent->fType == ftNetworkNeighborhood) //{ // lpNewNode->fType = ftNetNode; // sprintf(lpNewNode->cPath, "\\\\%s", (LPCTSTR)strFileName); //} } else { // 桌面的IShellFolder ::SHGetDesktopFolder(&lpNewNode->pShellFolder); } // 插入树结点 TVINSERTSTRUCT tvis; tvis.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE | TVIF_PARAM; // 如果该文件夹包含子文件夹,则对应的树结点也应该有子结点 if(Attributes & SFGAO_HASSUBFOLDER) { tvis.item.mask |= TVIF_CHILDREN; // 使用 I_CHILDRENCALLBACK 值告诉控件,该结点有子结点,但具体的结点还没给出 // 当该结点被展开时就会通知父窗口.这时你应该为该结点添加子结点 tvis.item.cChildren = I_CHILDRENCALLBACK; } // 设置覆盖图标 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); tvis.item.stateMask = TVIS_OVERLAYMASK; // 指明状太标志包含覆盖图标 tvis.item.iImage = uIcon; // 正常图标 tvis.item.iSelectedImage = uSelectedIcon;// 选中时的图标 //CString strTemp = strFileName + "(" + strPath + ")"; // 看看它的完整路径 tvis.item.pszText = (char*)fpl.cNormal; // 标题 tvis.hParent = hParent; // 父结点 tvis.hInsertAfter = TVI_LAST; // 插入到其它兄弟结点的后面 tvis.item.lParam = (DWORD)lpNewNode; // 自定义的结点数据 HTREEITEM hIns = tree.InsertItem(&tvis); // 插入该结点 if(hIns == NULL) // 插入失败??不大可能的事 FreeNodeData(lpNewNode); return hIns; // 返回新结点句柄 } // GetPath returns the path name for true folders, and a null string // for virtual folders. CString CShellFolderView::GetPath(HTREEITEM hNode) { CString strPath(""); if(hNode == NULL) return strPath; // 对于虚拟文件夹返回空串 switch(((LPFOLDERNODE)(GetTreeCtrl().GetItemData(hNode)))->fType) { case ftNetworkNeighborhood: case ftNetNode: case ftRecycleBin: case ftMyComputer: return strPath; } // 对于真正的文件夹返回绝对路径 strPath = ((LPFOLDERNODE)(GetTreeCtrl().GetItemData(hNode)))->cPath; if(strPath.GetLength() > 0) // If path is null, it''''s a virtual folder { if(strPath.GetLength() < 3) // If the result is less than 3 bytes, strPath += "\\"; // It''''s the root -- add a "\". } return strPath; } // 对目录进行排序的回调函数 // The lParam1 and lParam2 parameters correspond to the lParam member // of the TVITEM structure for the two items being compared. // The lParamSort parameter corresponds to the lParam member of this structure. static int CALLBACK ShortItemProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
上一页 [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文件系统的反删除方法
|