예제 #1
0
        internal ShellItem(ShellBrowserComponent 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);

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

            type = info.szTypeName;

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

            sortFlag = 1;
        }
예제 #2
0
        internal ShellItem(ShellBrowserComponent 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);
        }
예제 #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;

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

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

                                        if ((attribs & NativeShellAPI.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) == NativeShellAPI.S_OK)
                                {
                                    fileEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(fileEnumPtr, typeof(IEnumIDList));
                                    while (browser.UpdateCondition.ContinueUpdate &&
                                           fileEnum.Next(1, out pidlSubItem, out celtFetched) == NativeShellAPI.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) == NativeShellAPI.S_OK)
                            {
                                folderEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(folderEnumPtr, typeof(IEnumIDList));
                                while (browser.UpdateCondition.ContinueUpdate &&
                                       folderEnum.Next(1, out pidlSubItem, out celtFetched) == NativeShellAPI.S_OK && celtFetched == 1)
                                {
                                    if ((index = subFolders.IndexOf(pidlSubItem)) == -1)
                                    {
                                        IntPtr shellFolderPtr;
                                        if (ShellFolder.BindToObject(
                                                    pidlSubItem,
                                                    IntPtr.Zero,
                                                    ref NativeShellAPI.IID_IShellFolder,
                                                    out shellFolderPtr) == NativeShellAPI.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
                    }
                }
            }
        }