⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shellitem.cs

📁 C#界面编程
💻 CS
📖 第 1 页 / 共 4 页
字号:

            return ((expandFiles == filesExpanded || !expandFiles) && (expandFolders == foldersExpanded || !expandFolders));
        }

        internal void Clear(bool clearFiles, bool clearFolders)
        {
            if (((clearFiles && filesExpanded) || !clearFiles) &&
                ((clearFolders && foldersExpanded) || !clearFolders) &&
                (clearFiles || clearFolders) && ShellFolder != null && !disposed)
            {
                lock (browser)
                {
                    try
                    {
                        #region Reset Files

                        if (clearFiles)
                        {
                            foreach (IDisposable item in subFiles)
                                item.Dispose();

                            subFiles.Clear();
                            filesExpanded = false;
                        }

                        #endregion

                        #region Reset Folders

                        if (clearFolders)
                        {
                            foreach (IDisposable item in subFolders)
                                item.Dispose();

                            subFolders.Clear();
                            foldersExpanded = false;
                        }

                        #endregion
                    }
                    catch (Exception) { }
                }
            }
        }

        #region Updates

        internal void Update(bool updateFiles, bool updateFolders)
        {
            if (browser.UpdateCondition.ContinueUpdate && (updateFiles || updateFolders) && ShellFolder != null && !disposed)
            {
                lock (browser)
                {
                    #region Fields

                    IntPtr fileEnumPtr = IntPtr.Zero, folderEnumPtr = IntPtr.Zero;
                    IEnumIDList fileEnum = null, folderEnum = null;
                    IntPtr pidlSubItem;
                    int celtFetched;

                    ShellAPI.SHCONTF fileFlag =
                            ShellAPI.SHCONTF.NONFOLDERS |
                            ShellAPI.SHCONTF.INCLUDEHIDDEN;

                    ShellAPI.SHCONTF folderFlag =
                            ShellAPI.SHCONTF.FOLDERS |
                            ShellAPI.SHCONTF.INCLUDEHIDDEN;

                    bool[] fileExists;
                    fileExists = new bool[subFiles.Count];

                    bool[] folderExists;
                    folderExists = new bool[subFolders.Count];

                    int index;

                    #endregion

                    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 fileEnumPtr) == ShellAPI.S_OK)
                                {
                                    fileEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(fileEnumPtr, typeof(IEnumIDList));
                                    ShellAPI.SFGAO attribs = ShellAPI.SFGAO.FOLDER;
                                    while (browser.UpdateCondition.ContinueUpdate &&
                                           fileEnum.Next(1, out pidlSubItem, out celtFetched) == ShellAPI.S_OK && celtFetched == 1)
                                    {
                                        ShellFolder.GetAttributesOf(1, new IntPtr[] { pidlSubItem }, ref attribs);

                                        if ((attribs & ShellAPI.SFGAO.FOLDER) == 0)
                                        {
                                            if ((index = subFiles.IndexOf(pidlSubItem)) == -1)
                                            {
                                                ShellItem newItem = new ShellItem(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 fileEnumPtr) == ShellAPI.S_OK)
                                {
                                    fileEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(fileEnumPtr, typeof(IEnumIDList));
                                    while (browser.UpdateCondition.ContinueUpdate &&
                                           fileEnum.Next(1, out pidlSubItem, out celtFetched) == ShellAPI.S_OK && celtFetched == 1)
                                    {
                                        if ((index = subFiles.IndexOf(pidlSubItem)) == -1)
                                        {
                                            add.Add(new ShellItem(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 (ShellItem oldItem in remove)
                                {
                                    if ((newIndex = add.IndexOf(oldItem.Text)) > -1)
                                    {
                                        ShellItem 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 (ShellItem 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 folderEnumPtr) == ShellAPI.S_OK)
                            {
                                folderEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(folderEnumPtr, typeof(IEnumIDList));
                                while (browser.UpdateCondition.ContinueUpdate &&
                                       folderEnum.Next(1, out pidlSubItem, out celtFetched) == ShellAPI.S_OK && celtFetched == 1)
                                {
                                    if ((index = subFolders.IndexOf(pidlSubItem)) == -1)
                                    {
                                        IntPtr shellFolderPtr;
                                        if (ShellFolder.BindToObject(
                                                    pidlSubItem,
                                                    IntPtr.Zero,
                                                    ref ShellAPI.IID_IShellFolder,
                                                    out shellFolderPtr) == ShellAPI.S_OK)
                                        {
                                            add.Add(new ShellItem(
                                                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 (ShellItem oldItem in remove)
                                {
                                    if ((newIndex = add.IndexOf(oldItem.Text)) > -1)
                                    {
                                        ShellItem 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 (ShellItem 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 (folderEnum != null)
                        {
                            Marshal.ReleaseComObject(folderEnum);
                            Marshal.Release(folderEnumPtr);
                        }

                        if (fileEnum != null)
                        {
                            Marshal.ReleaseComObject(fileEnum);

                            if (!(type == browser.SystemFolderName && string.Compare(text, "Control Panel", true) == 0))
                                Marshal.Release(fileEnumPtr);
                        }

                        #endregion
                    }
                }
            }
        }

        internal void AddItem(ShellItem item)
        {
            browser.UpdateCondition.ContinueUpdate = false;
            lock (browser)
            {
                try
                {
                    if (item.IsFolder)
                        SubFolders.Add(item);
                    else
                        SubFiles.Add(item);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -