Example #1
0
        internal ShellItem(ShellBrowser browser, IntPtr pidl, IntPtr shellFolderPtr)
        {
            this.browser = browser;

            this.shellFolderPtr = shellFolderPtr;
            this.shellFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(shellFolderPtr, typeof(IShellFolder));
            subFiles = new ShellItemCollection(this);
            subFolders = new ShellItemCollection(this);

            pidlRel = new PIDL(pidl, false);

            text = "Desktop";
            path = "Desktop";

            SetAttributesDesktop(this);

            ShellAPI.SHFILEINFO info = new ShellAPI.SHFILEINFO();
            ShellAPI.SHGetFileInfo(pidlRel.Ptr, 0, ref info, ShellAPI.cbFileInfo,
                                   ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.TYPENAME | ShellAPI.SHGFI.SYSICONINDEX);

            type = info.szTypeName;

            ShellImageList.SetIconIndex(this, info.iIcon, false);
            ShellImageList.SetIconIndex(this, info.iIcon, true);

            sortFlag = 1;
        }
Example #2
0
        internal ShellItem(ShellBrowser browser, ShellItem 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);
        }
Example #3
0
        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
                    }
                }
            }
        }