public ShellNode(ShellBrowser browser, IntPtr pidl, IntPtr shellFolderPtr)
        {
            this.Browser = browser;

            this.shellFolderPtr = shellFolderPtr;
            this.shellFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(shellFolderPtr, typeof(IShellFolder));
            this.SubFiles = new ShellItemCollection(this);
            this.SubFolders = new ShellItemCollection(this);

            PIDLRel = new Pidl(pidl, false);

            Text = "Desktop";
            Path = "Desktop";

            SetAttributesDesktop(this);

            ShFileInfo info = new ShFileInfo();
            Shell32.SHGetFileInfo(PIDLRel.Ptr, 0, ref info, Marshal.SizeOf(info), SHGFI.Pidl | SHGFI.TypeName | SHGFI.SysIconIndex);

            Type = info.TypeName;

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

            SortFlag = 1;
        }
Example #2
0
 public Pidl(Pidl pidl, bool clone)
 {
     if (clone)
     {
         this.Ptr = ILClone(pidl.Ptr);
     }
     else
     {
         this.Ptr = pidl.Ptr;
     }
 }
        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(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 ShellNode GetShellItem(Pidl pidlFull)
        {
            ShellNode current = DesktopItem;
            if (pidlFull.Ptr == IntPtr.Zero)
            {
                return current;
            }

            foreach (IntPtr pidlRel in pidlFull)
            {
                int index;
                if ((index = current.IndexOf(pidlRel)) > -1)
                {
                    current = current[index];
                }
                else
                {
                    current = null;
                    break;
                }
            }

            return current;
        }
        public void Update(IntPtr newPidlFull, ShellItemUpdateType changeType)
        {
            Browser.UpdateCondition.ContinueUpdate = false;

            lock (Browser)
            {
                #region Change Pidl and ShellFolder

                if (newPidlFull != IntPtr.Zero)
                {
                    IntPtr tempPidl = Pidl.ILClone(Pidl.ILFindLastID(newPidlFull)), newPidlRel, newShellFolderPtr;
                    Shell32.SHGetRealIDL(ParentItem.ShellFolder, tempPidl, out newPidlRel);

                    if (IsFolder && ParentItem.ShellFolder.BindToObject(newPidlRel, IntPtr.Zero, ref ShellGuids.IShellFolder, out newShellFolderPtr) == 0)
                    {
                        Marshal.ReleaseComObject(shellFolder);
                        Marshal.Release(shellFolderPtr);
                        PIDLRel.Free();

                        shellFolderPtr = newShellFolderPtr;
                        shellFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(shellFolderPtr, typeof(IShellFolder));
                        PIDLRel = new Pidl(newPidlRel, false);

                        foreach (ShellNode child in SubFolders)
                        {
                            UpdateShellFolders(child);
                        }
                    }
                    else
                    {
                        PIDLRel.Free();
                        PIDLRel = new Pidl(newPidlRel, false);
                    }

                    Marshal.FreeCoTaskMem(tempPidl);
                    Marshal.FreeCoTaskMem(newPidlFull);
                }

                #endregion

                #region Make Other Changes

                switch (changeType)
                {
                    case ShellItemUpdateType.Renamed:
                        SetText(this);
                        SetPath(this);
                        break;

                    case ShellItemUpdateType.Updated:
                        if (IsFolder)
                        {
                            SetAttributesFolder(this);
                        }
                        else
                        {
                            SetAttributesFile(this);
                        }
                        break;

                    case ShellItemUpdateType.MediaChange:
                        SetInfo(this);
                        Clear(true, true);
                        break;

                    case ShellItemUpdateType.IconChange:
                        SetInfo(this);
                        break;
                }

                #endregion
            }

            Browser.OnShellItemUpdate(ParentItem, new ShellItemUpdateEventArgs(this, this, changeType));
        }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == (int)WM.ShNotify)
            {
                SHNOTIFYSTRUCT shNotify = (SHNOTIFYSTRUCT)Marshal.PtrToStructure(m.WParam, typeof(SHNOTIFYSTRUCT));

                //Console.Out.WriteLine("Event: {0}", (SHCNE)m.LParam);
                //if (shNotify.dwItem1 != IntPtr.Zero)
                //PIDL.Write(shNotify.dwItem1);
                //if (shNotify.dwItem2 != IntPtr.Zero)
                //PIDL.Write(shNotify.dwItem2);

                switch ((SHCNE)m.LParam)
                {
                    #region File Changes

                    case SHCNE.Create:

                        #region Create Item

                        {
                            if (!Pidl.IsEmpty(shNotify.dwItem1))
                            {
                                IntPtr parent, child, relative;
                                Pidl.SplitPidl(shNotify.dwItem1, out parent, out child);

                                Pidl parentPIDL = new Pidl(parent, false);
                                ShellNode parentItem = browser.GetShellItem(parentPIDL);
                                if (parentItem != null && parentItem.FilesExpanded && !parentItem.SubFiles.Contains(child))
                                {
                                    Shell32.SHGetRealIDL(parentItem.ShellFolder, child, out relative);
                                    parentItem.AddItem(new ShellNode(browser, parentItem, relative));
                                }

                                Marshal.FreeCoTaskMem(child);
                                parentPIDL.Free();
                            }
                        }

                        #endregion

                        break;

                    case SHCNE.RenameItem:

                        #region Rename Item

                        {
                            if (!Pidl.IsEmpty(shNotify.dwItem1) && !Pidl.IsEmpty(shNotify.dwItem2))
                            {
                                ShellNode item = browser.GetShellItem(new Pidl(shNotify.dwItem1, true));
                                if (item != null)
                                {
                                    item.Update(shNotify.dwItem2, ShellItemUpdateType.Renamed);
                                }
                            }
                        }

                        #endregion

                        break;

                    case SHCNE.Delete:

                        #region Delete Item

                        {
                            if (!Pidl.IsEmpty(shNotify.dwItem1))
                            {
                                IntPtr parent, child;
                                Pidl.SplitPidl(shNotify.dwItem1, out parent, out child);

                                Pidl parentPIDL = new Pidl(parent, false);
                                ShellNode parentItem = browser.GetShellItem(parentPIDL);
                                if (parentItem != null && parentItem.SubFiles.Contains(child))
                                {
                                    parentItem.RemoveItem(parentItem.SubFiles[child]);
                                }

                                Marshal.FreeCoTaskMem(child);
                                parentPIDL.Free();
                            }
                        }

                        #endregion

                        break;

                    case SHCNE.UpdateItem:

                        #region Update Item

                        {
                            if (!Pidl.IsEmpty(shNotify.dwItem1))
                            {
                                ShellNode item = browser.GetShellItem(new Pidl(shNotify.dwItem1, true));
                                if (item != null)
                                {
                                    Console.Out.WriteLine("Item: {0}", item);
                                    item.Update(IntPtr.Zero, ShellItemUpdateType.Updated);
                                    item.Update(IntPtr.Zero, ShellItemUpdateType.IconChange);
                                }
                            }
                        }

                        #endregion

                        break;

                    #endregion

                    #region Folder Changes

                    case SHCNE.MkDir:
                    case SHCNE.DriveAdd:
                    case SHCNE.DriveAddGui:

                        #region Make Directory

                        {
                            if (!Pidl.IsEmpty(shNotify.dwItem1))
                            {
                                IntPtr parent, child, relative;
                                Pidl.SplitPidl(shNotify.dwItem1, out parent, out child);

                                Pidl parentPIDL = new Pidl(parent, false);
                                ShellNode parentItem = browser.GetShellItem(parentPIDL);
                                if (parentItem != null && parentItem.FoldersExpanded && !parentItem.SubFolders.Contains(child))
                                {
                                    Shell32.SHGetRealIDL(parentItem.ShellFolder, child, out relative);

                                    IntPtr shellFolderPtr;
                                    if (parentItem.ShellFolder.BindToObject(relative, IntPtr.Zero, ref ShellGuids.IShellFolder, out shellFolderPtr) == 0)
                                    {
                                        parentItem.AddItem(new ShellNode(browser, parentItem, relative, shellFolderPtr));
                                    }
                                    else
                                    {
                                        Marshal.FreeCoTaskMem(relative);
                                    }
                                }

                                Marshal.FreeCoTaskMem(child);
                                parentPIDL.Free();
                            }
                        }

                        #endregion

                        break;

                    case SHCNE.RenameFolder:

                        #region Rename Directory

                        {
                            if (!Pidl.IsEmpty(shNotify.dwItem1) && !Pidl.IsEmpty(shNotify.dwItem2))
                            {
                                ShellNode item = browser.GetShellItem(new Pidl(shNotify.dwItem1, false));
                                if (item != null)
                                {
                                    //Console.Out.WriteLine("Update: {0}", item);
                                    item.Update(shNotify.dwItem2, ShellItemUpdateType.Renamed);
                                }
                            }
                        }

                        #endregion

                        break;

                    case SHCNE.RmDir:
                    case SHCNE.DriveRemoved:

                        #region Remove Directory

                        {
                            if (!Pidl.IsEmpty(shNotify.dwItem1))
                            {
                                IntPtr parent, child;
                                Pidl.SplitPidl(shNotify.dwItem1, out parent, out child);

                                Pidl parentPIDL = new Pidl(parent, false);
                                ShellNode parentItem = browser.GetShellItem(parentPIDL);
                                if (parentItem != null && parentItem.SubFolders.Contains(child))
                                {
                                    parentItem.RemoveItem(parentItem.SubFolders[child]);
                                }

                                Marshal.FreeCoTaskMem(child);
                                parentPIDL.Free();
                            }
                        }

                        #endregion

                        break;

                    case SHCNE.UpdateDir:
                    case SHCNE.Attributes:

                        #region Update Directory

                        {
                            if (!Pidl.IsEmpty(shNotify.dwItem1))
                            {
                                ShellNode item = browser.GetShellItem(new Pidl(shNotify.dwItem1, true));
                                if (item != null)
                                {
                                    item.Update(IntPtr.Zero, ShellItemUpdateType.Updated);
                                    item.Update(IntPtr.Zero, ShellItemUpdateType.IconChange);
                                }
                            }
                        }

                        #endregion

                        break;

                    case SHCNE.MediaInserted:
                    case SHCNE.MediaRemoved:

                        #region Media Change

                        {
                            if (!Pidl.IsEmpty(shNotify.dwItem1))
                            {
                                ShellNode item = browser.GetShellItem(new Pidl(shNotify.dwItem1, true));
                                if (item != null)
                                {
                                    item.Update(IntPtr.Zero, ShellItemUpdateType.MediaChange);
                                }
                            }
                        }

                        #endregion

                        break;

                    #endregion

                    #region Other Changes

                    case SHCNE.AssocChanged:

                        #region Update Images

                        {
                        }

                        #endregion

                        break;

                    case SHCNE.NetShare:
                    case SHCNE.NetUnshare:
                        break;

                    case SHCNE.UpdateImage:
                        UpdateRecycleBin();
                        break;

                    #endregion
                }
            }

            base.WndProc(ref m);
        }