/// <summary> /// Adds a file/directory node and all its parents to the directory tree if it doesn't exist yet. /// </summary> /// <param name="path">Full path of the added element within the file system</param> /// <param name="type">Type of the element to be added (file/directory)</param> /// <param name="nodes">A directory containing all previously created nodes</param> /// <returns>The node corresponding to the specified path</returns> protected ShellItemViewModel CreateNode(string path, ShellItemType type, Dictionary <string, ShellItemViewModel> nodes) { if (nodes.ContainsKey(path)) { return(nodes[path]); } string parentPath = Path.GetDirectoryName(path); var parent = !string.IsNullOrWhiteSpace(parentPath) ? CreateNode(parentPath, ShellItemType.Directory, nodes) : Root; var node = new ShellItemViewModel(this, parent, path, type); parent.Children.Add(node); nodes[path] = node; return(node); }
/// <summary> /// 属性を初期化する。 /// </summary> private void InitAtr(InitMode mode, IntPtr pIDL, ShellAPI.IShellFolder parentSf) { // 基本的な属性を初期化する ShellAPI.SFGAOF uFlags = 0; switch (mode) { case InitMode.Desktop: { this.IsFolder = true; this.IsFileSystem = false; this.HasSubFolder = true; } break; case InitMode.Path: case InitMode.Child: { uFlags = ShellAPI.SFGAOF.SFGAO_FOLDER | ShellAPI.SFGAOF.SFGAO_FILESYSTEM | ShellAPI.SFGAOF.SFGAO_FILESYSANCESTOR; parentSf.GetAttributesOf(1, out pIDL, out uFlags); this.IsFolder = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_FOLDER); this.IsFileSystem = Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_FILESYSTEM); if (this.IsFolder) { // GetAttributesOf で SFGAO_HASSUBFOLDER を調べるとかなり遅くなる、 // そもそも this.HasSubFolder はヒントとして使用するだけなのでフォルダの場合は問答無用で // this.HasSubFolder に true をセットする this.HasSubFolder = true; // このオブジェクト用の IShellFolder インターフェース取得 m_ShellFolder = ShellAPI.BindToIShellFolder(parentSf, pIDL); } } break; } // パス名取得 m_Path = ShellAPI.SHGetPathFromIDList(m_pIDL); // アイコンインデックス番号とかの属性取得 ShellAPI.SHFILEINFO shInfo = new ShellAPI.SHFILEINFO(); ShellAPI.SHGetFileInfoW( m_pIDL, 0, out shInfo, (uint)Marshal.SizeOf(shInfo), ShellAPI.SHGFI.SHGFI_SMALLICON | ShellAPI.SHGFI.SHGFI_SYSICONINDEX | ShellAPI.SHGFI.SHGFI_PIDL | ShellAPI.SHGFI.SHGFI_DISPLAYNAME | ShellAPI.SHGFI.SHGFI_TYPENAME ); m_DisplayName = shInfo.szDisplayName; m_TypeName = shInfo.szTypeName; m_iIconIndex = shInfo.iIcon; // 選択時のアイコンインデックス番号取得 ShellAPI.SHGetFileInfoW( m_pIDL, 0, out shInfo, (uint)Marshal.SizeOf(shInfo), ShellAPI.SHGFI.SHGFI_PIDL | ShellAPI.SHGFI.SHGFI_SMALLICON | ShellAPI.SHGFI.SHGFI_SYSICONINDEX | ShellAPI.SHGFI.SHGFI_OPENICON ); m_iSelectedIconIndex = shInfo.iIcon; // いろいろ調べてアイテム種類(m_ItemType)を確定する if (this.IsFileSystem) { bool bValidated = false; m_FileName = ""; try { m_FileName = System.IO.Path.GetFileName(m_Path); if (this.IsFolder) { if (System.IO.Path.GetPathRoot(m_Path) == m_Path) { // パス名とルートパスが同じならドライブのはず m_ItemType = ShellItemType.Drive; bValidated = true; } else if (Convert.ToBoolean(uFlags & ShellAPI.SFGAOF.SFGAO_FILESYSANCESTOR)) { // ファイルシステムアイテムを含むことができるフォルダ=ファイルフォルダ(だと思う) m_ItemType = ShellItemType.Folder; bValidated = true; } } } catch { // システムのアイテムの場合まともなパス名ではなくて、例外が出ちゃうので // ここで例外キャッチ } if (!bValidated) { m_ItemType = ShellItemType.File; bValidated = true; } } else { if (this.IsFolder) { m_ItemType = ShellItemType.SpecialFolder; } else { m_ItemType = ShellItemType.SpecialItem; } } }