public ShellNode(ShellBrowser browser, ShellNode parentItem, IntPtr pidl) { this.Browser = browser; this.ParentItem = parentItem; PIDLRel = new Pidl(pidl, false); SetText(this); SetPath(this); SetAttributesFile(this); SetInfo(this); SortFlag = MakeSortFlag(this); }
public ShellNode[] GetPath(ShellNode item) { ArrayList pathList = new ArrayList(); ShellNode currentItem = item; while (currentItem.ParentItem != null) { pathList.Add(currentItem); currentItem = currentItem.ParentItem; } pathList.Add(currentItem); pathList.Reverse(); return (ShellNode[])pathList.ToArray(typeof(ShellNode)); }
public ShellNode(ShellBrowser browser, ShellNode parentItem, IntPtr pidl, IntPtr shellFolderPtr) { this.Browser = browser; this.ParentItem = parentItem; this.shellFolderPtr = shellFolderPtr; this.shellFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(shellFolderPtr, typeof(IShellFolder)); SubFiles = new ShellItemCollection(this); SubFolders = new ShellItemCollection(this); PIDLRel = new Pidl(pidl, false); SetText(this); SetPath(this); SetAttributesFolder(this); SetInfo(this); SortFlag = MakeSortFlag(this); }
public static bool GetIQueryInfo(ShellNode item, out IntPtr iQueryInfoPtr, out IQueryInfo iQueryInfo) { ShellNode parent = item.ParentItem ?? item; if (parent.ShellFolder.GetUIObjectOf(IntPtr.Zero, 1, new[] { item.PIDLRel.Ptr }, ref ShellGuids.IQueryInfo, IntPtr.Zero, out iQueryInfoPtr) == 0) { iQueryInfo = (IQueryInfo)Marshal.GetTypedObjectForIUnknown(iQueryInfoPtr, typeof(IQueryInfo)); return true; } else { iQueryInfo = null; iQueryInfoPtr = IntPtr.Zero; return false; } }
private static short MakeSortFlag(ShellNode item) { if (item.IsFolder) { if (item.IsDisk) { return 1; } if (item.Text == item.Browser.MyDocumentsName && item.Type == item.Browser.SystemFolderName) { return 2; } else if (item.Text == item.Browser.MyComputerName) { return 3; } else if (item.Type == item.Browser.SystemFolderName) { if (!item.IsBrowsable) { return 4; } else { return 5; } } else if (item.IsFolder && !item.IsBrowsable) { return 6; } else { return 7; } } else { return 8; } }
public bool Contains(ShellNode value) { return (SubFolders.Contains(value) || SubFiles.Contains(value)); }
public static string GetRealPath(ShellNode item) { if (item.Equals(item.Browser.DesktopItem)) { return SpecialFolderPath.MyDocuments; } else if (item.Type == item.Browser.SystemFolderName) { IntPtr strr = Marshal.AllocCoTaskMem(ShellApi.MaxPath * 2 + 4); Marshal.WriteInt32(strr, 0, 0); StringBuilder buf = new StringBuilder(ShellApi.MaxPath); if (item.ParentItem.ShellFolder.GetDisplayNameOf(item.PIDLRel.Ptr, SHGNO.ForParsing, strr) == 0) { ShellApi.StrRetToBuf(strr, item.PIDLRel.Ptr, buf, ShellApi.MaxPath); } Marshal.FreeCoTaskMem(strr); return buf.ToString(); } else { return item.Path; } }
public bool Expand(bool expandFiles, bool expandFolders, IntPtr winHandle) { if (((expandFiles && !FilesExpanded) || !expandFiles) && ((expandFolders && !FoldersExpanded) || !expandFolders) && (expandFiles || expandFolders) && ShellFolder != null && !disposed) { IEnumIDList fileList = null; IEnumIDList folderList = null; try { int celtFetched; IntPtr pidlSubItem; if (expandFiles) { if (this.Equals(Browser.DesktopItem) || ParentItem.Equals(Browser.DesktopItem)) { if (ShellFolder.EnumObjects(winHandle, SHCONT.NonFolders | SHCONT.IncludeHidden, out fileList) == 0) { while (fileList.Next(1, out pidlSubItem, out celtFetched) == 0 && celtFetched == 1) { SFGAO attribs = SFGAO.Folder; ShellFolder.GetAttributesOf(1, new[] { pidlSubItem }, ref attribs); if ((attribs & SFGAO.Folder) == 0) { ShellNode newItem = new ShellNode(Browser, this, pidlSubItem); if (!SubFolders.Contains(newItem.Text)) { SubFiles.Add(newItem); } } else { Marshal.FreeCoTaskMem(pidlSubItem); } } SubFiles.Sort(); FilesExpanded = true; } } else { if (ShellFolder.EnumObjects(winHandle, SHCONT.NonFolders | SHCONT.IncludeHidden, out fileList) == 0) { while (fileList.Next(1, out pidlSubItem, out celtFetched) == 0 && celtFetched == 1) { ShellNode newItem = new ShellNode(Browser, this, pidlSubItem); SubFiles.Add(newItem); } SubFiles.Sort(); FilesExpanded = true; } } } if (expandFolders) { if (ShellFolder.EnumObjects(winHandle, SHCONT.Folders | SHCONT.IncludeHidden, out folderList) == 0) { while (folderList.Next(1, out pidlSubItem, out celtFetched) == 0 && celtFetched == 1) { IntPtr shellFolderPtr; if (ShellFolder.BindToObject(pidlSubItem, IntPtr.Zero, ref ShellGuids.IShellFolder, out shellFolderPtr) == 0) { ShellNode newItem = new ShellNode(Browser, this, pidlSubItem, shellFolderPtr); SubFolders.Add(newItem); } } SubFolders.Sort(); FoldersExpanded = true; } } } catch (Exception) { } finally { if (folderList != null) { Marshal.ReleaseComObject(folderList); } if (fileList != null) { Marshal.ReleaseComObject(fileList); } } } return ((expandFiles == FilesExpanded || !expandFiles) && (expandFolders == FoldersExpanded || !expandFolders)); }
private static void SetAttributesDesktop(ShellNode item) { item.IsFolder = true; item.IsLink = false; item.IsShared = false; item.IsFileSystem = true; item.IsHidden = false; item.HasSubfolder = true; item.IsBrowsable = true; item.CanRename = false; item.CanRead = true; }
private static void SetInfo(ShellNode item) { Pidl pidlFull = item.PIDLFull; ShFileInfo info = new ShFileInfo(); Shell32.SHGetFileInfo(pidlFull.Ptr, 0, ref info, Marshal.SizeOf(info), SHGFI.Pidl | SHGFI.TypeName | SHGFI.SysIconIndex); pidlFull.Free(); ShellImageList.SetIconIndex(item, info.IconIndex, false); ShellImageList.SetIconIndex(item, info.IconIndex, true); item.Type = info.TypeName; }
public static bool GetNewContextMenu(ShellNode item, out IntPtr iContextMenuPtr, out IContextMenu iContextMenu) { if (Ole32.CoCreateInstance( ref ShellGuids.NewMenu, IntPtr.Zero, CLSCTX.InProcServer, ref ShellGuids.IContextMenu, out iContextMenuPtr) == 0) { iContextMenu = Marshal.GetTypedObjectForIUnknown(iContextMenuPtr, typeof(IContextMenu)) as IContextMenu; IntPtr iShellExtInitPtr; if (Marshal.QueryInterface( iContextMenuPtr, ref ShellGuids.IShellExtInit, out iShellExtInitPtr) == 0) { IShellExtInit iShellExtInit = Marshal.GetTypedObjectForIUnknown(iShellExtInitPtr, typeof(IShellExtInit)) as IShellExtInit; Pidl pidlFull = item.PIDLFull; if (iShellExtInit != null) { iShellExtInit.Initialize(pidlFull.Ptr, IntPtr.Zero, 0); Marshal.ReleaseComObject(iShellExtInit); } Marshal.Release(iShellExtInitPtr); pidlFull.Free(); return true; } else { if (iContextMenu != null) { Marshal.ReleaseComObject(iContextMenu); iContextMenu = null; } if (iContextMenuPtr != IntPtr.Zero) { Marshal.Release(iContextMenuPtr); iContextMenuPtr = IntPtr.Zero; } return false; } } else { iContextMenuPtr = IntPtr.Zero; iContextMenu = null; return false; } }
/// <summary> /// Invokes a specific command for a set of pidls /// </summary> /// <param name="parent">the parent ShellItem which contains the pidls</param> /// <param name="pidls">the pidls from the list for which to invoke</param> /// <param name="cmd">the execute string from the command to invoke</param> /// <param name="ptInvoke">the point (in screen coцrdinates) from which to invoke</param> public static void InvokeCommand(ShellNode parent, IntPtr[] pidls, string cmd, Point ptInvoke) { IntPtr icontextMenuPtr; IContextMenu iContextMenu; if (GetIContextMenu(parent.ShellFolder, pidls, out icontextMenuPtr, out iContextMenu)) { try { InvokeCommand( iContextMenu, cmd, ShellNode.GetRealPath(parent), ptInvoke); } catch { } finally { if (iContextMenu != null) Marshal.ReleaseComObject(iContextMenu); if (icontextMenuPtr != IntPtr.Zero) Marshal.Release(icontextMenuPtr); } } }
public ShellItemUpdateEventArgs(ShellNode oldItem, ShellNode newItem, ShellItemUpdateType type) { this.OldItem = oldItem; this.NewItem = newItem; this.UpdateType = type; }
private void Initialize() { IntPtr tempPidl; ShFileInfo info; //My Computer info = new ShFileInfo(); tempPidl = IntPtr.Zero; Shell32.SHGetSpecialFolderLocation(IntPtr.Zero, CSIDL.Drives, out tempPidl); Shell32.SHGetFileInfo(tempPidl, 0, ref info, Marshal.SizeOf(info), SHGFI.Pidl | SHGFI.DisplayName | SHGFI.TypeName); SystemFolderName = info.TypeName; MyComputerName = info.DisplayName; Marshal.FreeCoTaskMem(tempPidl); // //Dekstop tempPidl = IntPtr.Zero; Shell32.SHGetSpecialFolderLocation(IntPtr.Zero, CSIDL.Desktop, out tempPidl); IntPtr desktopFolderPtr; Shell32.SHGetDesktopFolder(out desktopFolderPtr); DesktopItem = new ShellNode(this, tempPidl, desktopFolderPtr); // //My Documents uint pchEaten = 0; SFGAO pdwAttributes = 0; DesktopItem.ShellFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, SpecialFolderPath.MyDocuments, ref pchEaten, out tempPidl, ref pdwAttributes); info = new ShFileInfo(); Shell32.SHGetFileInfo(tempPidl, 0, ref info, Marshal.SizeOf(info), SHGFI.Pidl | SHGFI.DisplayName); MyDocumentsName = info.DisplayName; Marshal.FreeCoTaskMem(tempPidl); StringBuilder path = new StringBuilder(ShellApi.MaxPath); Shell32.SHGetFolderPath(IntPtr.Zero, CSIDL.Personal, IntPtr.Zero, SHGFP.TypeCurrent, path); MyDocumentsPath = path.ToString(); // }
public void Insert(int index, ShellNode value) { items.Insert(index, value); }
private static void SetAttributesFolder(ShellNode item) { // file/folder attributes SFGAO attribs = SFGAO.Share | SFGAO.FileSystem | SFGAO.Hidden | SFGAO.HasSubFolder | SFGAO.Browsable | SFGAO.CanRename | SFGAO.Storage; item.ParentItem.ShellFolder.GetAttributesOf(1, new IntPtr[] { item.PIDLRel.Ptr }, ref attribs); item.IsFolder = true; item.IsLink = false; item.IsShared = (attribs & SFGAO.Share) != 0; item.IsFileSystem = (attribs & SFGAO.FileSystem) != 0; item.IsHidden = (attribs & SFGAO.Hidden) != 0; item.HasSubfolder = (attribs & SFGAO.HasSubFolder) != 0; item.IsBrowsable = (attribs & SFGAO.Browsable) != 0; item.CanRename = (attribs & SFGAO.CanRename) != 0; item.CanRead = (attribs & SFGAO.Storage) != 0; item.IsDisk = (item.Path.Length == 3 && item.Path.EndsWith(":\\")); }
public void Remove(ShellNode value) { items.Remove(value); }
private static void SetAttributesFile(ShellNode item) { // file/folder attributes SFGAO attribs = SFGAO.Link | SFGAO.Share | SFGAO.FileSystem | SFGAO.Hidden | SFGAO.CanRename | SFGAO.Stream; item.ParentItem.ShellFolder.GetAttributesOf(1, new IntPtr[] { item.PIDLRel.Ptr }, ref attribs); item.IsFolder = false; item.IsLink = (attribs & SFGAO.Link) != 0; item.IsShared = (attribs & SFGAO.Share) != 0; item.IsFileSystem = (attribs & SFGAO.FileSystem) != 0; item.IsHidden = (attribs & SFGAO.Hidden) != 0; item.HasSubfolder = false; item.IsBrowsable = false; item.CanRename = (attribs & SFGAO.CanRename) != 0; item.CanRead = (attribs & SFGAO.Stream) != 0; item.IsDisk = false; }
public void Update(bool updateFiles, bool updateFolders) { if (Browser.UpdateCondition.ContinueUpdate && (updateFiles || updateFolders) && ShellFolder != null && !disposed) { lock (Browser) { IEnumIDList fileList = null; IEnumIDList folderList = null; IntPtr pidlSubItem; int celtFetched; SHCONT fileFlag = SHCONT.NonFolders | SHCONT.IncludeHidden; SHCONT folderFlag = SHCONT.Folders | SHCONT.IncludeHidden; bool[] fileExists; fileExists = new bool[SubFiles.Count]; bool[] folderExists; folderExists = new bool[SubFolders.Count]; int index; try { #region Update Files if (Browser.UpdateCondition.ContinueUpdate && updateFiles) { ShellItemCollection add = new ShellItemCollection(this); ShellItemCollection remove = new ShellItemCollection(this); bool fileEnumCompleted = false; #region Add Files if (this.Equals(Browser.DesktopItem) || ParentItem.Equals(Browser.DesktopItem)) { if (ShellFolder.EnumObjects(IntPtr.Zero, fileFlag, out fileList) == 0) { SFGAO attribs = SFGAO.Folder; while (Browser.UpdateCondition.ContinueUpdate && fileList.Next(1, out pidlSubItem, out celtFetched) == 0 && celtFetched == 1) { ShellFolder.GetAttributesOf(1, new IntPtr[] { pidlSubItem }, ref attribs); if ((attribs & SFGAO.Folder) == 0) { if ((index = SubFiles.IndexOf(pidlSubItem)) == -1) { ShellNode newItem = new ShellNode(Browser, this, pidlSubItem); if (!SubFolders.Contains(newItem.Text)) { add.Add(newItem); } } else if (index < fileExists.Length) { fileExists[index] = true; Marshal.FreeCoTaskMem(pidlSubItem); } } else { Marshal.FreeCoTaskMem(pidlSubItem); } } fileEnumCompleted = true; } } else { if (ShellFolder.EnumObjects(IntPtr.Zero, fileFlag, out fileList) == 0) { while (Browser.UpdateCondition.ContinueUpdate && fileList.Next(1, out pidlSubItem, out celtFetched) == 0 && celtFetched == 1) { if ((index = SubFiles.IndexOf(pidlSubItem)) == -1) { add.Add(new ShellNode(Browser, this, pidlSubItem)); } else if (index < fileExists.Length) { fileExists[index] = true; Marshal.FreeCoTaskMem(pidlSubItem); } } fileEnumCompleted = true; } } #endregion #region Remove Files for (int i = 0; fileEnumCompleted && Browser.UpdateCondition.ContinueUpdate && i < fileExists.Length; i++) { if (!fileExists[i] && SubFiles[i] != null) { remove.Add(SubFiles[i]); } } #endregion #region Do Events if (fileEnumCompleted && Browser.UpdateCondition.ContinueUpdate) { int newIndex; foreach (ShellNode oldItem in remove) { if ((newIndex = add.IndexOf(oldItem.Text)) > -1) { ShellNode newItem = add[newIndex]; add.Remove(newItem); oldItem.PIDLRel.Free(); oldItem.PIDLRel = new Pidl(newItem.PIDLRel.Ptr, true); oldItem.shellFolder = newItem.shellFolder; oldItem.shellFolderPtr = newItem.shellFolderPtr; ((IDisposable)newItem).Dispose(); Browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(oldItem, oldItem, ShellItemUpdateType.Updated)); } else { SubFiles.Remove(oldItem); Browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(oldItem, null, ShellItemUpdateType.Deleted)); ((IDisposable)oldItem).Dispose(); } } foreach (ShellNode newItem in add) { SubFiles.Add(newItem); Browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(null, newItem, ShellItemUpdateType.Created)); } SubFiles.Capacity = SubFiles.Count; SubFiles.Sort(); FilesExpanded = true; } #endregion } #endregion #region Update Folders if (Browser.UpdateCondition.ContinueUpdate && updateFolders) { ShellItemCollection add = new ShellItemCollection(this); ShellItemCollection remove = new ShellItemCollection(this); bool folderEnumCompleted = false; #region Add Folders if (ShellFolder.EnumObjects(IntPtr.Zero, folderFlag, out folderList) == 0) { while (Browser.UpdateCondition.ContinueUpdate && folderList.Next(1, out pidlSubItem, out celtFetched) == 0 && celtFetched == 1) { if ((index = SubFolders.IndexOf(pidlSubItem)) == -1) { IntPtr shellFolderPtr; if (ShellFolder.BindToObject(pidlSubItem, IntPtr.Zero, ref ShellGuids.IShellFolder, out shellFolderPtr) == 0) { add.Add(new ShellNode(Browser, this, pidlSubItem, shellFolderPtr)); } } else if (index < folderExists.Length) { folderExists[index] = true; Marshal.FreeCoTaskMem(pidlSubItem); } } folderEnumCompleted = true; } #endregion #region Remove Folders for (int i = 0; folderEnumCompleted && Browser.UpdateCondition.ContinueUpdate && i < folderExists.Length; i++) { if (!folderExists[i] && SubFolders[i] != null) { remove.Add(SubFolders[i]); } } #endregion #region Do Events if (folderEnumCompleted && Browser.UpdateCondition.ContinueUpdate) { int newIndex; foreach (ShellNode oldItem in remove) { if ((newIndex = add.IndexOf(oldItem.Text)) > -1) { ShellNode newItem = add[newIndex]; add.Remove(newItem); oldItem.PIDLRel.Free(); oldItem.PIDLRel = new Pidl(newItem.PIDLRel, true); Marshal.ReleaseComObject(oldItem.shellFolder); Marshal.Release(oldItem.shellFolderPtr); oldItem.shellFolder = newItem.shellFolder; oldItem.shellFolderPtr = newItem.shellFolderPtr; newItem.shellFolder = null; newItem.shellFolderPtr = IntPtr.Zero; ((IDisposable)newItem).Dispose(); Browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(oldItem, oldItem, ShellItemUpdateType.Updated)); } else { SubFolders.Remove(oldItem); Browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(oldItem, null, ShellItemUpdateType.Deleted)); ((IDisposable)oldItem).Dispose(); } } foreach (ShellNode newItem in add) { SubFolders.Add(newItem); Browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(null, newItem, ShellItemUpdateType.Created)); } SubFolders.Capacity = SubFolders.Count; SubFolders.Sort(); FoldersExpanded = true; } #endregion } #endregion } catch (Exception) { } finally { #region Free if (folderList != null) { Marshal.ReleaseComObject(folderList); } if (fileList != null) { Marshal.ReleaseComObject(fileList); } #endregion } } } }
public ShellItemEnumerator(ShellNode parent) { this.parent = parent; }
public void AddItem(ShellNode item) { Browser.UpdateCondition.ContinueUpdate = false; lock (Browser) { try { if (item.IsFolder) { SubFolders.Add(item); } else { SubFiles.Add(item); } Browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(null, item, ShellItemUpdateType.Created)); } catch (Exception) { } } }
public ShellItemCollection(ShellNode shellItem) { this.ShellItem = shellItem; }
public void RemoveItem(ShellNode item) { Browser.UpdateCondition.ContinueUpdate = false; lock (Browser) { try { if (item.IsFolder) { SubFolders.Remove(item); } else { SubFiles.Remove(item); } Browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(item, null, ShellItemUpdateType.Deleted)); ((IDisposable)item).Dispose(); } catch (Exception) { } } }
public int Add(ShellNode value) { return items.Add(value); }
public static void UpdateShellFolders(ShellNode item) { item.UpdateShellFolder = true; foreach (ShellNode child in item.SubFolders) { UpdateShellFolders(child); } }
public bool Contains(ShellNode value) { return items.Contains(value); }
public int IndexOf(ShellNode value) { int index; index = SubFolders.IndexOf(value); if (index > -1) { return index; } index = SubFiles.IndexOf(value); if (index > -1) { return SubFolders.Count + index; } return -1; }
public int IndexOf(ShellNode value) { return items.IndexOf(value); }
private static void SetText(ShellNode item) { IntPtr strr = Marshal.AllocCoTaskMem(ShellApi.MaxPath * 2 + 4); Marshal.WriteInt32(strr, 0, 0); StringBuilder buf = new StringBuilder(ShellApi.MaxPath); if (item.ParentItem.ShellFolder.GetDisplayNameOf(item.PIDLRel.Ptr, SHGNO.InFolder, strr) == 0) { ShellApi.StrRetToBuf(strr, item.PIDLRel.Ptr, buf, ShellApi.MaxPath); item.Text = buf.ToString(); } Marshal.FreeCoTaskMem(strr); }
public static DragDropEffects CanDropClipboard(ShellNode item) { IntPtr dataObject; Ole32.OleGetClipboard(out dataObject); IntPtr targetPtr; IDropTarget target; DragDropEffects retVal = DragDropEffects.None; if (GetIDropTarget(item, out targetPtr, out target)) { // Check Copy DragDropEffects effects = DragDropEffects.Copy; if (target.DragEnter(dataObject, MK.Control, new POINT(), ref effects) == 0) { if (effects == DragDropEffects.Copy) { retVal |= DragDropEffects.Copy; } target.DragLeave(); } // Check Move effects = DragDropEffects.Move; if (target.DragEnter(dataObject, MK.Shift, new POINT(), ref effects) == 0) { if (effects == DragDropEffects.Move) { retVal |= DragDropEffects.Move; } target.DragLeave(); } // Check Lick effects = DragDropEffects.Link; if (target.DragEnter(dataObject, MK.Alt, new POINT(), ref effects) == 0) { if (effects == DragDropEffects.Link) { retVal |= DragDropEffects.Link; } target.DragLeave(); } Marshal.ReleaseComObject(target); Marshal.Release(targetPtr); } return retVal; }