Exemplo n.º 1
0
 public ShellTreeEventArgs(ShellItem shellItem)
 {
     ShellItem = shellItem;
 }
Exemplo n.º 2
0
        /// <summary>
        /// Gets the children.
        /// </summary>
        /// <param name="childTypes">The child types.</param>
        /// <returns>
        /// The children.
        /// </returns>
        public IEnumerable<ShellItem> GetChildren(ChildTypes childTypes)
        {
            //  We'll return a list of children.
            var children = new List<ShellItem>();

            //  Create the enum flags from the childtypes.
            SHCONTF enumFlags = 0;
            if (childTypes.HasFlag(ChildTypes.Folders))
                enumFlags |= SHCONTF.SHCONTF_FOLDERS;
            if (childTypes.HasFlag(ChildTypes.Files))
                enumFlags |= SHCONTF.SHCONTF_NONFOLDERS;
            if (childTypes.HasFlag(ChildTypes.Hidden))
                enumFlags |= SHCONTF.SHCONTF_INCLUDEHIDDEN;

            try
            {
                //  Create an enumerator for the children.
                IEnumIDList pEnum;
                var result = ShellFolderInterface.EnumObjects(IntPtr.Zero, enumFlags, out pEnum);

                //  Validate the result.
                if (result != 0)
                {
                    //  Throw the failure as an exception.
                    Marshal.ThrowExceptionForHR((int)result);
                }

                // TODO: This logic should go in the pidl manager.

                //  Enumerate the children, ten at a time.
                const int batchSize = 10;
                var pidlArray = Marshal.AllocCoTaskMem(IntPtr.Size * 10);
                uint itemsFetched;
                result = WinError.S_OK;
                do
                {
                    result = pEnum.Next(batchSize, pidlArray, out itemsFetched);

                    //  Get each pidl.
                    var pidls = new IntPtr[itemsFetched];
                    Marshal.Copy(pidlArray, pidls, 0, (int) itemsFetched);
                    foreach (var childPidl in pidls)
                    {
                        //  Create a new shell folder.
                        var childShellFolder = new ShellItem();

                        //  Initialize it.
                        try
                        {
                            childShellFolder.Initialise(childPidl, this);
                        }
                        catch (Exception exception)
                        {
                            throw new InvalidOperationException("Failed to initialise child.", exception);
                        }

                        //  Add the child.
                        children.Add(childShellFolder);

                        //  Free the PIDL, reset the result.
                        Marshal.FreeCoTaskMem(childPidl);
                    }
                } while (result == WinError.S_OK);
            
                Marshal.FreeCoTaskMem(pidlArray);

                //  Release the enumerator.
                if(Marshal.IsComObject(pEnum))
                    Marshal.ReleaseComObject(pEnum);
            }
            catch (Exception exception)
            {
                throw new InvalidOperationException("Failed to enumerate children.", exception);
            }

            //  Sort the children.
            var sortedChildren = children.Where(c => c.IsFolder).ToList();
            sortedChildren.AddRange(children.Where(c => !c.IsFolder));

            //  Return the children.
            return sortedChildren;
        }
Exemplo n.º 3
0
        private void OpenItemContextMenu(ShellItem itemHit, int x, int y)
        {
                //  TODO: we need a min and max for the menu items.

            //  see http://www.codeproject.com/Articles/4025/Use-Shell-ContextMenu-in-your-applications for more

            //  The shell folder we use to get the UI object is either the folder itself if the
            //  item is a folder, or the parent folder otherwise.
            var shellFolder = itemHit.IsFolder ? itemHit.ShellFolderInterface : itemHit.ParentItem.ShellFolderInterface;

            //  The item pidl is either the folder if the item is a folder, or the combined pidl otherwise.
            var fullIdList = itemHit.IsFolder
                ? PidlManager.PidlToIdlist(itemHit.PIDL)
                : PidlManager.Combine(PidlManager.PidlToIdlist(itemHit.ParentItem.PIDL),
                    PidlManager.PidlToIdlist(itemHit.RelativePIDL));
                

            //  Get the UI object of the context menu.
            IntPtr apidl = PidlManager.PidlsToAPidl(new IntPtr[] {PidlManager.IdListToPidl(fullIdList)});


            IntPtr ppv = IntPtr.Zero;
            shellFolder.GetUIObjectOf(Handle, 1, apidl, Shell32.IID_IContextMenu, 0,
                out ppv);

            //  If we have an item, cast it.
            if (ppv != IntPtr.Zero)
            {
                IContextMenu contextMenu = (IContextMenu)Marshal.GetObjectForIUnknown(ppv);

                var popupMenu = new ContextMenu();
                contextMenu.QueryContextMenu(popupMenu.Handle, 0, 0, 65525, CMF.CMF_EXPLORE);
                popupMenu.Show(this, new Point(x, y));
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Initialises the ShellItem, from its PIDL and parent.
        /// </summary>
        /// <param name="pidl">The pidl.</param>
        /// <param name="parentFolder">The parent folder.</param>
        private void Initialise(IntPtr pidl, ShellItem parentFolder)
        {
            //  Set the parent item and relative pidl.
            ParentItem = parentFolder;
            RelativePIDL = pidl;

            //  Create the fully qualified PIDL.
            PIDL = Shell32.ILCombine(parentFolder.PIDL, pidl);

            //  Use the desktop folder to get attributes.
            var flags = SFGAO.SFGAO_FOLDER | SFGAO.SFGAO_HASSUBFOLDER | SFGAO.SFGAO_BROWSABLE | SFGAO.SFGAO_FILESYSTEM;
            //todo was this parentFolder.ShellFolderInterface.GetAttributesOf(1, ref pidl, ref flags);

            var apidl = Marshal.AllocCoTaskMem(IntPtr.Size*1);
            Marshal.Copy(new IntPtr[] {pidl}, 0, apidl, 1);

            parentFolder.ShellFolderInterface.GetAttributesOf(1, apidl, ref flags);
           
            IsFolder = (flags & SFGAO.SFGAO_FOLDER) != 0;
            HasSubFolders = (flags & SFGAO.SFGAO_HASSUBFOLDER) != 0;

            //  Get the file info.
            var fileInfo = new SHFILEINFO();
            Shell32.SHGetFileInfo(PIDL, 0, out fileInfo, (uint)Marshal.SizeOf(fileInfo),
                SHGFI.SHGFI_SMALLICON | SHGFI.SHGFI_SYSICONINDEX | SHGFI.SHGFI_PIDL | SHGFI.SHGFI_DISPLAYNAME | SHGFI.SHGFI_ATTRIBUTES);

            //  Set extended attributes.
            DisplayName = fileInfo.szDisplayName;
            Attributes = (SFGAO)fileInfo.dwAttributes;
            TypeName = fileInfo.szTypeName;
            IconIndex = fileInfo.iIcon;

            //  Are we a folder?
            if (IsFolder)
            {
                //  Bind the shell folder interface.
                IShellFolder shellFolderInterface;
                IntPtr ppv = IntPtr.Zero;
                var result = parentFolder.ShellFolderInterface.BindToObject(pidl, IntPtr.Zero, ref Shell32.IID_IShellFolder,
                    out ppv);//out shellFolderInterface);
                shellFolderInterface = ((IShellFolder) Marshal.GetObjectForIUnknown(ppv));
                ShellFolderInterface = shellFolderInterface;

                //  Validate the result.
                if (result != 0)
                {
                    //  Throw the failure as an exception.
                    Marshal.ThrowExceptionForHR((int)result);
                }
            }
        }
Exemplo n.º 5
0
 private void FireOnShellItemSelected(ShellItem shellItem)
 {
     var theEvent = OnShellItemSelected;
     if(theEvent != null)
         theEvent(this, new ShellTreeEventArgs(shellItem));
 }