예제 #1
0
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
#if DEBUG
                --_instanceCount;
#endif

                if (disposing)
                {
                    if (_pidl != null)
                    {
                        _pidl.Dispose();
                        _pidl = null;
                    }

                    if (_rootItem != null)
                    {
                        // do not dispose this - we don't own it!
                        _rootItem = null;
                    }
                }

                if (_shellFolder != null)
                {
                    // release the IShellFolder interface of this shell item
                    Marshal.ReleaseComObject(_shellFolder);
                    _shellFolder = null;
                }

                _disposed = true;
            }
        }
예제 #2
0
        /// <remarks>
        /// This method will not update any registered components.
        /// It is for updating the coordinator's own state.
        /// </remarks>
        private Pidl BrowseToCore(Pidl pidl)
        {
            if (pidl != null && !pidl.IsFolder)
            {
                // if for some reason we're trying to browse to a file, use the file's location instead
                using (Pidl parent = pidl.GetParent())
                {
                    return(this.BrowseToCore(parent));
                }
            }

            if (_browseHistory.Current != pidl)
            {
                Pidl clonePidl = null;
                if (pidl != null)
                {
                    clonePidl = pidl.Clone();
                }

                _browseHistory.Go(clonePidl);

                this.UpdateProperties();
                this.OnCurrentPidlChanged(EventArgs.Empty);
            }
            return(_browseHistory.Current);
        }
예제 #3
0
 public void BrowseTo(Environment.SpecialFolder specialFolder)
 {
     using (Pidl pidl = new Pidl(specialFolder))
     {
         this.BrowseTo(pidl);
     }
 }
예제 #4
0
            protected override void Dispose(bool disposing)
            {
                if (disposing)
                {
                    DisposeEach(this.Items);

                    if (_currentShellItem != null)
                    {
                        _currentShellItem.Dispose();
                        _currentShellItem = null;
                    }

                    if (_rootShellItem != null)
                    {
                        _rootShellItem.Dispose();
                        _rootShellItem = null;
                    }

                    if (_myDocumentsReferencePidl != null)
                    {
                        _myDocumentsReferencePidl.Dispose();
                        _myDocumentsReferencePidl = null;
                    }
                }
                base.Dispose(disposing);
            }
예제 #5
0
 public DefaultSearchLocations()
 {
     _dictionary = new Dictionary <string, Pidl>(5);
     foreach (Environment.SpecialFolder folder in EnumerateLocations())
     {
         Pidl pidl = null;
         try
         {
             pidl = new Pidl(folder);
             string displayName = pidl.DisplayName;
             if (!string.IsNullOrEmpty(displayName))
             {
                 _dictionary.Add(displayName.ToLowerInvariant(), pidl);
                 continue;
             }
             pidl.Dispose();
         }
         catch (Exception)
         {
             if (pidl != null)
             {
                 pidl.Dispose();
             }
         }
     }
 }
예제 #6
0
 public void Dispose()
 {
     if (_pidl != null)
     {
         _pidl.Dispose();
         _pidl = null;
     }
 }
예제 #7
0
 void IFolderCoordinatee.BrowseTo(Pidl pidl)
 {
     if (this.CurrentPidlCore != pidl)
     {
         this.BrowseToCore(pidl);
         this.OnCurrentPidlChanged(EventArgs.Empty);
     }
 }
예제 #8
0
        public void BrowseTo(int stepsForwardInHistory)
        {
            Pidl current = this.BrowseHistoryCore(stepsForwardInHistory);

            foreach (IFolderCoordinatee coordinatee in _list)
            {
                coordinatee.BrowseTo(current);
            }
        }
예제 #9
0
        public bool TryBrowseToPhysicalLocation(string path)
        {
            Pidl pidl;

            if (Pidl.TryParse(path, out pidl))
            {
                this.BrowseTo(pidl);
                pidl.Dispose();
                return(true);
            }
            return(false);
        }
예제 #10
0
        private bool UpdateCanBrowseToParent()
        {
            Pidl current           = _browseHistory.Current;
            bool canBrowseToParent = (current != null && !current.IsRoot);

            if (_canBrowseToParent != canBrowseToParent)
            {
                _canBrowseToParent = canBrowseToParent;
                this.OnPropertyChanged(new PropertyChangedEventArgs("CanBrowseToParent"));
            }
            return(canBrowseToParent);
        }
예제 #11
0
        private void OnFolderCoordinateePidlChanged(object sender, EventArgs e)
        {
            Pidl pidl = ((IFolderCoordinatee)sender).Pidl;

            this.BrowseToCore(pidl);
            foreach (IFolderCoordinatee coordinatee in _list)
            {
                if (coordinatee != sender)
                {
                    coordinatee.BrowseTo(pidl);
                }
            }
        }
예제 #12
0
 public void BrowseToPidl(Pidl pidl)
 {
     _suppressBrowseEvents = true;
     try
     {
         this.Browse(new ShellItem(pidl, _rootShellItem, false));
     }
     catch (Exception ex)
     {
         HandleBrowseException(ex);
     }
     finally
     {
         _suppressBrowseEvents = false;
     }
 }
예제 #13
0
 public void BrowseToParent()
 {
     if (_browseHistory.Current != null)
     {
         Pidl parent = _browseHistory.Current.GetParent();
         if (parent != null)
         {
             try
             {
                 this.BrowseTo(parent);
             }
             finally
             {
                 parent.Dispose();
             }
         }
     }
 }
예제 #14
0
        private IEnumerable <Pidl> EnumerateChildPidls(Native.SHCONTF flags)
        {
            if (!_isFolder)
            {
                throw new InvalidOperationException("Children can only be enumerated on a folder-type item.");
            }
            if (_shellFolder == null)
            {
                return(new Pidl[0]);
            }

            // Get the IEnumIDList interface pointer.
            Native.IEnumIDList pEnum = null;

            try
            {
                uint hRes = _shellFolder.EnumObjects(IntPtr.Zero, flags, out pEnum);
                if (hRes != 0)
                {
                    Marshal.ThrowExceptionForHR((int)hRes);
                }
            }
            catch (UnauthorizedAccessException ex)
            {
                throw new PathAccessException(_pidl.Path, ex);
            }
            catch (Exception ex)
            {
                throw new Exception("IShellFolder::EnumObjects failed to enumerate child objects.", ex);
            }

            try
            {
                return(Pidl.ConvertPidlEnumeration(pEnum));
            }
            finally
            {
                // Free the interface pointer.
                Marshal.ReleaseComObject(pEnum);
            }
        }
예제 #15
0
            public FolderListView() : base()
            {
                _currentShellItem         = _rootShellItem.Clone();
                _myDocumentsReferencePidl = new Pidl(Environment.SpecialFolder.MyDocuments);

                this.Alignment          = ListViewAlignment.SnapToGrid;
                this.AllowColumnReorder = false;
                this.AutoArrange        = true;
                this.CheckBoxes         = false;
                this.DereferenceLinks   = true;
                this.HeaderStyle        = ColumnHeaderStyle.Clickable;
                this.HideSelection      = false;
                this.LabelEdit          = false;
                this.LabelWrap          = true;
                this.ListViewItemSorter = new FolderListViewItemComparer();
                this.MultiSelect        = true;
                this.Scrollable         = true;
                this.Sorting            = SortOrder.Ascending;
                this.TileSize           = new Size(12 * (this.FontHeight + 4), 3 * this.FontHeight + 4);
                this.View = View.LargeIcon;
                this.PopulateItems();
            }
예제 #16
0
        public ShellItem()
        {
            _rootItem = this;
            try
            {
                // create a PIDL for the Desktop shell item.
                _pidl = new Pidl(Environment.SpecialFolder.Desktop);

                var shInfo = new Native.SHFILEINFO();
                Native.Shell32.SHGetFileInfo((IntPtr)_pidl, 0, out shInfo, (uint)Marshal.SizeOf(shInfo), SHGFI.SHGFI_PIDL | SHGFI.SHGFI_DISPLAYNAME | SHGFI.SHGFI_SYSICONINDEX);

                // get the root IShellFolder interface
                int hResult = Native.Shell32.SHGetDesktopFolder(ref _shellFolder);
                if (hResult != 0)
                {
                    Marshal.ThrowExceptionForHR(hResult);
                }

                _displayName   = shInfo.szDisplayName;
                _typeName      = string.Empty;
                _iconIndex     = shInfo.iIcon;
                _isFolder      = true;
                _isVirtual     = true;
                _hasSubFolders = true;
            }
            catch (Exception ex)
            {
                // if an exception happens during construction, we must release the PIDL now (remember, it's a pointer!)
                if (_pidl != null)
                {
                    _pidl.Dispose();
                }
                throw new Exception("Creation of the root namespace shell item failed.", ex);
            }

#if DEBUG
            _instanceCount++;
#endif
        }
예제 #17
0
        public void BrowseTo(Pidl pidl)
        {
            if (pidl == null)
            {
                throw new ArgumentNullException("pidl");
            }

            CancelEventArgs e = new CancelEventArgs();

            this.OnCurrentPidlChanging(e);
            if (e.Cancel)
            {
                return;
            }

            Pidl current = this.BrowseToCore(pidl);

            foreach (IFolderCoordinatee coordinatee in _list)
            {
                coordinatee.BrowseTo(current);
            }
        }
예제 #18
0
 public void BrowseTo(Pidl absolutePidl)
 {
     _suppressBrowseEvents = true;
     try
     {
         if (absolutePidl != null)
         {
             TreeNodeCollection nextSearchDomain = this.Nodes;
             do
             {
                 TreeNodeCollection currentSearchDomain = nextSearchDomain;
                 nextSearchDomain = null;
                 foreach (FolderTreeNode node in currentSearchDomain)
                 {
                     if (node.Pidl == absolutePidl)
                     {
                         this.SelectedNode = node;
                         break;
                     }
                     else if (node.Pidl.IsAncestorOf(absolutePidl))
                     {
                         node.Expand();
                         nextSearchDomain = node.Nodes;
                         break;
                     }
                 }
             } while (nextSearchDomain != null);
         }
     }
     catch (Exception ex)
     {
         HandleBrowseException(ex);
     }
     finally
     {
         _suppressBrowseEvents = false;
     }
 }
예제 #19
0
        public override void Reload()
        {
            Pidl selectedPidl = _folderTreeView.CurrentPidl.Clone();

            _suspendBeforeBrowse = true;
            try
            {
                foreach (FolderTreeNode node in _folderTreeView.Nodes)
                {
                    node.Reload();
                }

                _folderTreeView.BrowseTo(selectedPidl);
            }
            catch (Exception ex)
            {
                this.HandleBrowseException(ex);
            }
            finally
            {
                _suspendBeforeBrowse = false;
                selectedPidl.Dispose();
            }
        }
예제 #20
0
 protected override void BrowseToCore(Pidl pidl)
 {
     _folderTreeView.BrowseTo(pidl);
 }
예제 #21
0
 protected override void BrowseToCore(Pidl pidl)
 {
     _folderListView.BrowseToPidl(pidl);
 }
예제 #22
0
 public ShellItem(Pidl pidl, ShellItem parentShellItem) : this(pidl, parentShellItem, true)
 {
 }
예제 #23
0
        public bool TryBrowseToVirtualLocation(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                this.BrowseTo((Pidl)null);
                return(true);
            }

            string vRelativePath;

            // try to figure how the virtual path is rooted - if there is no match, assume desktop as root
            Pidl vPathRootPidl = _defaultSearchLocations.FindRoot(path, out vRelativePath) ?? _rootShellItem.Pidl;

            if (string.IsNullOrEmpty(vRelativePath))
            {
                // no umatched path relative to the root, so we can browse there directly
                // this PIDL is either owned by _rootShellItem or _defaultSearchLocations, so we don't need to dispose of it
                this.BrowseTo(vPathRootPidl);
                return(true);
            }

            string vChildComponent;

            // try to find the first matching child of the discovered special path root
            string vFirstComponent = GetPathRoot(vRelativePath, out vChildComponent);

            using (ShellItem vPathRootShellItem = new ShellItem(vPathRootPidl, _rootShellItem, false))
            {
                List <ShellItem> children = new List <ShellItem>(vPathRootShellItem.EnumerateChildren());
                try
                {
                    // find the first child whose display name matches the first component of the desired path
                    foreach (ShellItem child in children)
                    {
                        if (string.Equals(child.DisplayName, vFirstComponent, StringComparison.InvariantCultureIgnoreCase))
                        {
                            // if we have an additional child path component, and this item has a physical path, combine them!
                            if (!string.IsNullOrEmpty(vChildComponent) && !string.IsNullOrEmpty(child.Path))
                            {
                                string fullyQualifiedPath = Path.Combine(child.Path, vChildComponent);
                                using (Pidl pidl = Pidl.Parse(fullyQualifiedPath))
                                {
                                    if (pidl == null)
                                    {
                                        return(false);
                                    }
                                    this.BrowseTo(pidl);
                                    return(true);
                                }
                            }
                            this.BrowseTo(child.Pidl);
                            return(true);
                        }
                    }
                }
                finally
                {
                    // the call to EnumerateChildren() created this items - we must dispose them!
                    foreach (ShellItem child in children)
                    {
                        child.Dispose();
                    }
                }
            }

            return(false);
        }
예제 #24
0
            public FolderListViewItem(Pidl absolutePidl, Pidl myDocumentsReferencePidl, FileSizeFormat fileSizeFormat)
            {
                _pidl     = absolutePidl;
                _fullPath = absolutePidl.Path;

                // request shell item info now - it's faster than binding to ShellItem directly, and we need it for sorting purposes anyway
                var uFlags = SHGFI.SHGFI_PIDL | SHGFI.SHGFI_TYPENAME | SHGFI.SHGFI_DISPLAYNAME | SHGFI.SHGFI_SYSICONINDEX;

                // bug #9975: asking for SHGFI_ATTRIBUTES can be a very slow operation, so we don't want to ask for them unless we really need them.
                // if we're dealing with a regular file or directory, then getting the attributes gives us no additional information, so we can avoid it
                var isFile      = !string.IsNullOrEmpty(_fullPath) && File.Exists(_fullPath);
                var isDirectory = !string.IsNullOrEmpty(_fullPath) && Directory.Exists(_fullPath);

                if (!isFile && !isDirectory)
                {
                    uFlags = uFlags | SHGFI.SHGFI_ATTRIBUTES;
                }

                var shInfo = new SHFILEINFO();

                Shell32.SHGetFileInfo((IntPtr)_pidl, 0, out shInfo, (uint)Marshal.SizeOf(shInfo), uFlags);

                // check if item is purely virtual or is a physical file system object
                var isPureVirtual = !isFile && !isDirectory && ((SFGAO)shInfo.dwAttributes & SFGAO.SFGAO_FILESYSTEM) == 0;

                // check if item is actually a folder or potentially has subfolders; exclude real files that provide subfolders via shell namespace extensions (e.g. ZIP files in WinXP)
                var isFolder = isDirectory || (((SFGAO)shInfo.dwAttributes & (SFGAO.SFGAO_FOLDER | SFGAO.SFGAO_HASSUBFOLDER)) != 0 && !isFile);

                byte itemClass;

                if (_pidl == myDocumentsReferencePidl)
                {
                    itemClass = 0;
                }
                else if (isPureVirtual && isFolder)
                {
                    itemClass = 64;
                }
                else if (isFolder)
                {
                    itemClass = (byte)(128 + GetRootVolumeIndex(_fullPath));
                }
                else
                {
                    itemClass = byte.MaxValue;
                }

                this._iconIndex         = shInfo.iIcon;
                this._lastModifiedValid = false;
                this.DisplayName        = shInfo.szDisplayName;
                this.TypeName           = shInfo.szTypeName;
                this.ItemClass          = itemClass;
                this.LastModified       = DateTime.MinValue;
                this.IsFolder           = isFolder;
                this.FileSize           = -1;

                if (File.Exists(_fullPath))
                {
                    FileInfo fileInfo = new FileInfo(this._fullPath);
                    this._lastModifiedValid = true;
                    this.LastModified       = fileInfo.LastWriteTime;
                    this.FileSize           = fileInfo.Length;
                }
                else if (Directory.Exists(_fullPath))
                {
                    this._lastModifiedValid = true;
                    this.LastModified       = Directory.GetLastWriteTime(_fullPath);
                }

                this.Text       = this.DisplayName;
                this.ImageIndex = this._iconIndex;
                this.SubItems.Add(CreateSubItem(this, FormatFileSize(this.FileSize, fileSizeFormat)));
                this.SubItems.Add(CreateSubItem(this, this.TypeName));
                this.SubItems.Add(CreateSubItem(this, FormatLastModified(this.LastModified, this._lastModifiedValid)));
            }
예제 #25
0
            protected override void OnDoubleClick(EventArgs e)
            {
                if (this.SelectedItems != null && this.SelectedItems.Count > 0)
                {
                    try
                    {
                        Point point             = this.PointToClient(Cursor.Position);
                        FolderListViewItem item = (FolderListViewItem)this.GetItemAt(point.X, point.Y);
                        if (item != null)
                        {
                            var pidl = item.Pidl.Clone();
                            try
                            {
                                if (DereferenceLinks && pidl.IsLink)
                                {
                                    // attempt to resolve links first if necessary
                                    string resolvedPath;
                                    Pidl   resolvedPidl;
                                    if (ShellItem.TryResolveLink(Handle, pidl.Path, out resolvedPath) && Pidl.TryParse(resolvedPath, out resolvedPidl))
                                    {
                                        pidl.Dispose();
                                        pidl = resolvedPidl;
                                    }
                                }

                                var handled = false;

                                var control = Parent as FolderView;
                                if (control != null)
                                {
                                    var args = new FolderViewItemEventArgs(new FolderViewItem(pidl));
                                    control.OnItemDoubleClick(args);
                                    handled = args.Handled;
                                }

                                if (AutoDrillDown && pidl.IsFolder && !handled)
                                {
                                    // if the user double clicked on a folder item, perform a drill down
                                    Browse(new ShellItem(pidl, _rootShellItem, false));
                                }
                            }
                            finally
                            {
                                pidl.Dispose();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        HandleBrowseException(ex);
                    }
                }
                base.OnDoubleClick(e);
            }
예제 #26
0
            protected override void OnKeyDown(KeyEventArgs e)
            {
                if (e.KeyCode == Keys.Enter)
                {
                    if (this.SelectedItems != null && this.SelectedItems.Count > 0)
                    {
                        try
                        {
                            FolderListViewItem item = (FolderListViewItem)this.FocusedItem;
                            if (item != null)
                            {
                                var pidl = item.Pidl.Clone();
                                try
                                {
                                    if (DereferenceLinks && pidl.IsLink)
                                    {
                                        // attempt to resolve links first if necessary
                                        string resolvedPath;
                                        Pidl   resolvedPidl;
                                        if (ShellItem.TryResolveLink(Handle, pidl.Path, out resolvedPath) && Pidl.TryParse(resolvedPath, out resolvedPidl))
                                        {
                                            pidl.Dispose();
                                            pidl = resolvedPidl;
                                        }
                                    }

                                    var handled = false;

                                    var control = Parent as FolderView;
                                    if (control != null)
                                    {
                                        var args = new FolderViewItemEventArgs(new FolderViewItem(pidl));
                                        control.OnItemKeyEnterPressed(args);
                                        handled = args.Handled;
                                    }

                                    if (AutoDrillDown && pidl.IsFolder && !handled)
                                    {
                                        // if the user pressed ENTER on a folder item, perform a drill down
                                        Browse(new ShellItem(pidl, _rootShellItem, false));
                                    }
                                }
                                finally
                                {
                                    pidl.Dispose();
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            HandleBrowseException(ex);
                        }
                    }

                    e.Handled          = true;
                    e.SuppressKeyPress = true;
                }
                base.OnKeyDown(e);
            }
예제 #27
0
 internal FolderTreeItem(Pidl pidl)
     : base(pidl.Path, pidl.VirtualPath, pidl.DisplayName, pidl.IsFolder, pidl.IsLink)
 {
 }
예제 #28
0
 protected abstract void BrowseToCore(Pidl pidl);
예제 #29
0
        public ShellItem(Pidl pidl, ShellItem parentShellItem, bool relativePidl)
        {
            int hResult;

            _rootItem = parentShellItem._rootItem;
            try
            {
                IntPtr tempPidl;
                if (relativePidl)
                {
                    _pidl    = new Pidl(parentShellItem.Pidl, pidl);
                    tempPidl = (IntPtr)pidl;                      // use the relative one from parameters
                }
                else
                {
                    _pidl    = pidl.Clone();
                    tempPidl = (IntPtr)_pidl;                      // use the absolute one that we constructed just now
                }

                const Native.SHGFI flags = Native.SHGFI.SHGFI_PIDL                 // indicates that we're specifying the item by PIDL
                                           | Native.SHGFI.SHGFI_DISPLAYNAME        // indicates that we want the item's display name
                                           | Native.SHGFI.SHGFI_SYSICONINDEX       // indicates that we want the item's icon's index in the system image list
                                           | Native.SHGFI.SHGFI_ATTRIBUTES         // indicates that we want the item's attributes
                                           | Native.SHGFI.SHGFI_TYPENAME;          // indicates that we want the item's type name
                Native.SHFILEINFO shInfo = new Native.SHFILEINFO();
                Native.Shell32.SHGetFileInfo((IntPtr)_pidl, 0, out shInfo, (uint)Marshal.SizeOf(shInfo), flags);

                // read item attributes
                Native.SFGAO attributeFlags = (Native.SFGAO)shInfo.dwAttributes;

                // create the item's IShellFolder interface
                if ((attributeFlags & Native.SFGAO.SFGAO_FOLDER) != 0)
                {
                    Guid iidIShellFolder = new Guid(IID.IID_IShellFolder);
                    if (_pidl == _rootItem._pidl)
                    {
                        // if the requested PIDL is the root namespace (the desktop) we can't use the the BindToObject method, so get it directly
                        hResult = Native.Shell32.SHGetDesktopFolder(ref _shellFolder);
                    }
                    else
                    {
                        if (relativePidl)
                        {
                            hResult = (int)parentShellItem._shellFolder.BindToObject(tempPidl, IntPtr.Zero, ref iidIShellFolder, out _shellFolder);
                        }
                        else
                        {
                            hResult = (int)_rootItem._shellFolder.BindToObject(tempPidl, IntPtr.Zero, ref iidIShellFolder, out _shellFolder);
                        }
                    }

                    if (hResult != 0)
                    {
                        // some objects are marked as folders, but really aren't and thus cannot be bound to an IShellFolder
                        // log these events for future study, but it's not exactly something to be concerned about in isolated cases.
                        // Marshal.ThrowExceptionForHR(hResult);
                        if ((attributeFlags & Native.SFGAO.SFGAO_HASSUBFOLDER) == 0)
                        {
                            attributeFlags = attributeFlags & ~Native.SFGAO.SFGAO_FOLDER;
                        }
                    }
                }

                _displayName   = shInfo.szDisplayName;
                _typeName      = shInfo.szTypeName;
                _iconIndex     = shInfo.iIcon;
                _isFolder      = (attributeFlags & Native.SFGAO.SFGAO_FOLDER) != 0;
                _isVirtual     = (attributeFlags & Native.SFGAO.SFGAO_FILESYSTEM) == 0;
                _hasSubFolders = (attributeFlags & Native.SFGAO.SFGAO_HASSUBFOLDER) != 0;
            }
            catch (UnauthorizedAccessException ex)
            {
                // if an exception happens during construction, we must release the PIDL now (remember, it's a pointer!)
                var path = string.Empty;
                if (_pidl != null)
                {
                    path = _pidl.Path;
                    _pidl.Dispose();
                }
                throw new PathAccessException(path, ex);
            }
            catch (Exception ex)
            {
                // if an exception happens during construction, we must release the PIDL now (remember, it's a pointer!)
                if (_pidl != null)
                {
                    _pidl.Dispose();
                }
                throw new Exception("Creation of the specified shell item failed.", ex);
            }

#if DEBUG
            _instanceCount++;
#endif
        }