Example #1
0
        public void CanFullRoundTripPidl()
        {
            IntPtr pidl  = default(IntPtr);
            IntPtr pidl2 = default(IntPtr);

            try
            {
                NativeMethods.SHGetKnownFolderIDList(KnownFolderGuids.FOLDERID_Downloads,
                                                     KNOWN_FOLDER_FLAG.KF_NO_FLAGS,
                                                     IntPtr.Zero, out pidl);

                var idList = PidlManager.PidlToIdlist(pidl);
                pidl2 = PidlManager.IdListToPidl(idList);
                var idList2 = PidlManager.PidlToIdlist(pidl2);

                Assert.IsTrue(idList.Matches(idList2));
            }
            finally
            {
                if (pidl != default(IntPtr))
                {
                    NativeMethods.ILFree(pidl);
                }

                if (pidl2 != default(IntPtr))
                {
                    NativeMethods.ILFree(pidl2);
                }
            }
        }
Example #2
0
        public void GetLogicalLocationForDesktopParentOf()
        {
            var testitem = KF_IID.ID_FOLDERID_ComputerFolder;

            IdList parentIdList = null, relativeChild = null;
            var    retVal = PidlManager.GetParentIdListFromPath(testitem, out parentIdList, out relativeChild);

            Assert.IsTrue(relativeChild != null);
            Assert.IsTrue(relativeChild.Size == 1);

            Assert.IsTrue(retVal == true);
            Assert.IsFalse(parentIdList == null);
            Assert.IsTrue(parentIdList.Size == 0);  // An empty list represents the desktop

            IntPtr parentPIDL = PidlManager.IdListToPidl(IdList.Create(parentIdList.Ids));

            try
            {
                Assert.IsFalse(parentPIDL == default(IntPtr));

                string path = PidlManager.GetPathFromPIDL(parentPIDL);

                Assert.IsFalse(string.IsNullOrEmpty(path));
                Assert.IsFalse(testitem.Equals(path, StringComparison.InvariantCultureIgnoreCase));

                // The expected parent of 'This PC' is the 'Desktop'
                Assert.IsTrue(path.Equals(KF_IID.ID_FOLDERID_Desktop, StringComparison.InvariantCultureIgnoreCase));

                // this works for display name return PidlManager.GetPidlDisplayName(parentPIDL);
            }
            finally
            {
                parentPIDL = PidlManager.FreeCoTaskMem(parentPIDL);
            }
        }
Example #3
0
        /// <summary>
        /// Gets the ResourceId (libararyName, index) of a shell icon
        /// based on an <see cref="IdList"/> object
        /// to support IconExtaction and display in UI layer.
        /// </summary>
        /// <param name="ilPidl"></param>
        /// <param name="isDirectory"></param>
        /// <param name="forceLoadFromDisk"></param>
        /// <param name="size"></param>
        /// <param name="iconState"></param>
        /// <returns></returns>
        public static string FromPidl(IdList ilPidl,
                                      bool isDirectory,
                                      bool forceLoadFromDisk,
                                      IconSize size = IconSize.large,
                                      ShellIconStateConstants iconState = ShellIconStateConstants.ShellIconStateNormal)
        {
            IntPtr ptrPidl = default(IntPtr);

            try
            {
                if ((ptrPidl = PidlManager.IdListToPidl(ilPidl)) != default(IntPtr))
                {
                    return(IconHelper.FromPidl(ptrPidl, isDirectory, forceLoadFromDisk,
                                               size, iconState));
                }
            }
            finally
            {
                if (ptrPidl != default(IntPtr))
                {
                    ptrPidl = PidlManager.ILFree(ptrPidl);
                }
            }

            return(null);
        }
Example #4
0
        public void CanBouncePidl()
        {
            IntPtr pidl = default(IntPtr);

            try
            {
                NativeMethods.SHGetKnownFolderIDList(KnownFolderGuids.FOLDERID_Documents,
                                                     KNOWN_FOLDER_FLAG.KF_NO_FLAGS,
                                                     IntPtr.Zero, out pidl);

                var idList = PidlManager.PidlToIdlist(pidl);  // Convert pidl to idlist

                NativeMethods.ILFree(pidl);
                pidl = default(IntPtr);

                pidl = PidlManager.IdListToPidl(idList);     // Convert idlist to pidl

                var displayName = PidlManager.GetPidlDisplayName(pidl);
                Assert.AreEqual(displayName, "Documents");
            }
            finally
            {
                if (pidl != default(IntPtr))
                {
                    NativeMethods.ILFree(pidl);
                }
            }
        }
Example #5
0
        /// <summary>
        /// Gets a <see cref="KnownFolderNative"/> object from an <see cref="IdList"/>
        /// based PIDL if this represents a knownfolder, or otherwise, null.
        /// </summary>
        /// <param name="ashellListId"></param>
        /// <returns></returns>
        internal static KnownFolderNative FromPIDL(IdList ashellListId)
        {
            bool isDesktop = true;

            if (ashellListId != null)
            {
                if (ashellListId.Size > 0)
                {
                    isDesktop = false;
                }
            }

            if (isDesktop == true)
            {
                return(KnownFolderHelper.FromPath(KF_IID.ID_FOLDERID_Desktop, true));
            }

            IntPtr pidl = default(IntPtr);

            try
            {
                pidl = PidlManager.IdListToPidl(ashellListId);

                KnownFolderManagerClass knownFolderManager = new KnownFolderManagerClass();

                IKnownFolderNative iknownFolder;
                HRESULT            hr = knownFolderManager.FindFolderFromIDList(pidl, out iknownFolder);

                return((hr == HRESULT.S_OK) ? new KnownFolderNative(iknownFolder) : null);
            }
            finally
            {
                pidl = PidlManager.ILFree(pidl);
            }
        }
Example #6
0
        public void GetStorageLocationForSpecialFolderParent()
        {
            string originalPath = null;
            IntPtr ptrPath      = default(IntPtr);

            try
            {
                using (var kfn = KnownFolderHelper.FromKnownFolderGuid(new Guid(KF_ID.ID_FOLDERID_Windows)))
                {
                    kfn.Obj.GetPath(0, out ptrPath);

                    Assert.IsTrue(ptrPath != default(IntPtr));

                    originalPath = Marshal.PtrToStringUni(ptrPath);
                }

                Assert.IsFalse(string.IsNullOrEmpty(originalPath));

                string testFolder = System.IO.Path.Combine(originalPath, "System32");
                Assert.IsTrue(System.IO.Directory.Exists(testFolder));

                IdList parentIdList = null, relativeChild = null;
                var    retVal = PidlManager.GetParentIdListFromPath(testFolder, out parentIdList, out relativeChild);

                Assert.IsTrue(relativeChild != null);
                Assert.IsTrue(relativeChild.Size == 1);

                IntPtr parentPIDL = PidlManager.IdListToPidl(IdList.Create(parentIdList.Ids));
                try
                {
                    Assert.IsFalse(parentPIDL == default(IntPtr));

                    string path = PidlManager.GetPathFromPIDL(parentPIDL);

                    Assert.IsTrue(retVal == true);
                    Assert.IsFalse(parentIdList == null);

                    // Expectation: Should display a path like 'C:\' or special folder path
                    Assert.IsFalse(string.IsNullOrEmpty(testFolder));
                    Assert.IsFalse(testFolder.Equals(path, StringComparison.InvariantCultureIgnoreCase));

                    // The expected parent of a drive is 'This PC'
                    Assert.IsTrue(path.Equals(KF_IID.ID_FOLDERID_Windows, StringComparison.InvariantCultureIgnoreCase));
                }
                finally
                {
                    parentPIDL = PidlManager.FreeCoTaskMem(parentPIDL);
                }
            }
            finally
            {
                ptrPath = PidlManager.FreeCoTaskMem(ptrPath);
            }
        }
 /// <summary>
 /// Gets the ITEMIDLIST for the folder object.
 /// </summary>
 /// <param name="ppidl">The address of an ITEMIDLIST pointer. This PIDL represents the absolute location of the folder and must be relative to the desktop. This is typically a copy of the PIDL passed to Initialize.</param>
 /// <returns>
 /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
 /// </returns>
 /// <remarks>
 /// If the folder object has not been initialized, this method returns S_FALSE and ppidl is set to NULL.
 /// </remarks>
 int IPersistFolder2.GetCurFolder(out IntPtr ppidl)
 {
     //  Return null if we're not initialised.
     if (idListAbsolute == null)
     {
         ppidl = IntPtr.Zero;
         return(WinError.S_FALSE);
     }
     //  Return the pidl.
     ppidl = PidlManager.IdListToPidl(idListAbsolute);
     return(WinError.S_OK);
 }
Example #8
0
        public void CanFullRoundTripPidl()
        {
            IntPtr pidl;

            Shell32.SHGetKnownFolderIDList(KnownFolders.FOLDERID_Downloads, KNOWN_FOLDER_FLAG.KF_NO_FLAGS, IntPtr.Zero,
                                           out pidl);
            var idList  = PidlManager.PidlToIdlist(pidl);
            var pidl2   = PidlManager.IdListToPidl(idList);
            var idList2 = PidlManager.PidlToIdlist(pidl2);

            Assert.IsTrue(idList.Matches(idList2));
        }
        /// <summary>
        /// Retrieves the specified number of item identifiers in the
        /// enumeration sequence and advances the current position by
        /// the number of items retrieved.
        /// </summary>
        /// <param name="celt">Number of elements in the array pointed to by the rgelt parameter.</param>
        /// <param name="rgelt">Address of an array of ITEMIDLIST pointers that receives the item identifiers. The implementation must allocate these item identifiers
        /// using the Shell's allocator (retrieved by the SHGetMalloc function). The calling application is responsible for freeing the item
        /// identifiers using the Shell's allocator.</param>
        /// <param name="pceltFetched">Address of a value that receives a count of the item identifiers actually returned in rgelt. The count can be smaller than the value
        /// specified in the celt parameter. This parameter can be NULL only if celt is one.</param>
        /// <returns></returns>
        public int Next(uint celt, IntPtr rgelt, out uint pceltFetched)
        {
            //  Request the children from the extension. As this is an abstract call, we always
            //  use an exception handler.
            var items = new List <IShellNamespaceItem>();

            try
            {
                //  TODO: We may want to improve on the public api here so that we don't have to enumerate
                //  everything to get certain items.

                //  Enumerate the children, adding them to the items collection and moving the index forwards
                //  by the number of items we've enumerated.
                items.AddRange(
                    shellNamespaceFolder
                    .GetChildren(_shellNamespaceEnumerationFlags)
                    .Skip((int)currentIndex)
                    .Take((int)celt));
                currentIndex += (uint)items.Count;
            }
            catch (Exception exception)
            {
                //  Log the exception, but continue as if we've enumerated nothing.
                Diagnostics.Logging.Error(string.Format("An unhandled exception occured enumerating {0} items from the {1} namespace extension.", celt, shellNamespaceFolder.GetDisplayName(DisplayNameContext.Normal)),
                                          exception);
            }

            //  If we've not enumerated anything, we can return now.
            if (items.Any() == false && celt > 0)
            {
                pceltFetched = 0;
                return(WinError.S_FALSE);
            }

            //  For every item enumerated, use the PIDL manager to create a shell allocated PIDL.
            //  These PIDLs must not be relative, so using the value returned by the GetShellId
            //  function is enough.
            var pidlArray = items.Select(
                iid => PidlManager.IdListToPidl(IdList.Create(new List <ShellId> {
                iid.GetShellId()
            }))).ToArray();

            //  Copy the data to the provided array.
            Marshal.Copy(pidlArray, 0, rgelt, pidlArray.Length);
            pceltFetched = (uint)items.Count;

            //  We're done. We return OK if we've got more to enumerate and false otherwise.
            return(pceltFetched == celt ? WinError.S_OK : WinError.S_FALSE);
        }
Example #10
0
        public void GetLogicalLocationForThisPCParentOf()
        {
            // Get the default drive's path
            var drive = new DirectoryInfo(Environment.SystemDirectory).Root.Name;

            Assert.IsFalse(string.IsNullOrEmpty(drive));

            var list = new List <string>();

            list.Add(drive);
            list.Add(KF_IID.ID_FOLDERID_Documents);
            list.Add(KF_IID.ID_FOLDERID_Music);
            list.Add(KF_IID.ID_FOLDERID_Downloads);
            list.Add(KF_IID.ID_FOLDERID_Pictures);
            list.Add(KF_IID.ID_FOLDERID_Videos);

            foreach (var testFolder in list)
            {
                IdList parentIdList = null, relativeChild = null;
                var    retVal = PidlManager.GetParentIdListFromPath(testFolder, out parentIdList, out relativeChild);

                Assert.IsTrue(relativeChild != null);
                Assert.IsTrue(relativeChild.Size == 1);

                Assert.IsTrue(retVal == true);
                Assert.IsFalse(parentIdList == null);

                IntPtr parentPIDL = PidlManager.IdListToPidl(IdList.Create(parentIdList.Ids));
                try
                {
                    Assert.IsFalse(parentPIDL == default(IntPtr));

                    string path = PidlManager.GetPathFromPIDL(parentPIDL);

                    // Expectation: Should display a path like 'C:\' or special folder path
                    Assert.IsFalse(string.IsNullOrEmpty(path));
                    Assert.IsFalse(testFolder.Equals(path, StringComparison.InvariantCultureIgnoreCase));

                    // The expected parent of a drive is 'This PC'
                    Assert.IsTrue(path.Equals(KF_IID.ID_FOLDERID_ComputerFolder, StringComparison.InvariantCultureIgnoreCase));

                    // this works for display name return PidlManager.GetPidlDisplayName(parentPIDL);
                }
                finally
                {
                    parentPIDL = PidlManager.FreeCoTaskMem(parentPIDL);
                }
            }
        }
Example #11
0
        public void CanBouncePidl()
        {
            IntPtr pidl;

            Shell32.SHGetKnownFolderIDList(KnownFolders.FOLDERID_Documents, KNOWN_FOLDER_FLAG.KF_NO_FLAGS, IntPtr.Zero,
                                           out pidl);
            var idList = PidlManager.PidlToIdlist(pidl);

            Shell32.ILFree(pidl);
            pidl = PidlManager.IdListToPidl(idList);
            var pszPath     = new StringBuilder();
            var displayName = PidlManager.GetPidlDisplayName(pidl);

            Assert.AreEqual(displayName, "Documents");
        }
        private void OnOpen(object sender, EventArgs eventArgs)
        {
            SHELLEXECUTEINFO sei = new SHELLEXECUTEINFO();

            sei.cbSize = Marshal.SizeOf(sei);
            sei.fMask  = SEE.SEE_MASK_IDLIST | SEE.SEE_MASK_CLASSNAME;
            var fullPidl = PidlManager.IdListToPidl(PidlManager.Combine(_folderIdList, _folderItemIdLists[0]));

            sei.lpIDList = fullPidl;
            sei.lpClass  = "folder";
            sei.hwnd     = CurrentInvokeCommandInfo.WindowHandle;
            sei.nShow    = CurrentInvokeCommandInfo.ShowCommand;
            sei.lpVerb   = "open"; // todo parameter open.
            Shell32.ShellExecuteEx(ref sei);
            PidlManager.DeletePidl(fullPidl);
        }
        /// <summary>
        /// Translates the display name of a file object or a folder into an item identifier list.
        /// </summary>
        /// <param name="hwnd">A window handle. The client should provide a window handle if it displays a dialog or message box. Otherwise set hwnd to NULL.</param>
        /// <param name="pbc">Optional. A pointer to a bind context used to pass parameters as inputs and outputs to the parsing function.</param>
        /// <param name="pszDisplayName">A null-terminated Unicode string with the display name.</param>
        /// <param name="pchEaten">A pointer to a ULONG value that receives the number of characters of the display name that was parsed. If your application does not need this information, set pchEaten to NULL, and no value will be returned.</param>
        /// <param name="ppidl">When this method returns, contains a pointer to the PIDL for the object.</param>
        /// <param name="pdwAttributes">The value used to query for file attributes. If not used, it should be set to NULL.</param>
        /// <returns>
        /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
        /// </returns>
        /// <exception cref="System.NotImplementedException"></exception>
        int IShellFolder.ParseDisplayName(IntPtr hwnd, IntPtr pbc, string pszDisplayName, ref uint pchEaten, out IntPtr ppidl, ref SFGAO pdwAttributes)
        {
            //  First we can decode the pidl from the display name.
            var idList = IdList.FromParsingString(pszDisplayName);

            ppidl = PidlManager.IdListToPidl(idList);

            //  We always eat the entire display string for SharpShell PIDL/DisplayName parsing.
            pchEaten = (uint)pszDisplayName.Length;


            //  In theory, we should understand the pidl.
            var item = GetChildItem(idList);
            var name = item.GetDisplayName(DisplayNameContext.Normal);

            //  TODO: We may be asked to get the attributes at the same time. If so, we must set them here.
            return(WinError.S_OK);
        }
Example #14
0
        public static void OpenSystemMenu(ShellItem itemHit, Control ctrl, int x, int y)
        {
            //  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 = new IntPtr[] { PidlManager.IdListToPidl(fullIdList) };
            // PidlManager.PidlsToAPidl(new IntPtr[] { PidlManager.IdListToPidl(fullIdList) });

            IntPtr ppv = IntPtr.Zero;

            shellFolder.GetUIObjectOf(ctrl.Handle, 1,
                                      apidl,
                                      Shell32.IID_IContextMenu, 0,
                                      out ppv);

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

                var popupMenu = new ContextMenu();
                contextMenu.QueryContextMenu(popupMenu.Handle, 0, 0, 65525, CMF.CMF_EXPLORE);
                popupMenu.Show(ctrl, new Point(x, y));
                return;
            }
        }
Example #15
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));
            }
        }
        /// <summary>
        /// Retrieves an OLE interface that can be used to carry out actions on the
        /// specified file objects or folders. Return value: error code, if any
        /// </summary>
        /// <param name="hwndOwner">Handle to the owner window that the client should specify if it displays a dialog box or message box.</param>
        /// <param name="cidl">Number of file objects or subfolders specified in the apidl parameter.</param>
        /// <param name="apidl">Address of an array of pointers to ITEMIDLIST  structures, each of which  uniquely identifies a file object or subfolder relative to the parent folder.</param>
        /// <param name="riid">Identifier of the COM interface object to return.</param>
        /// <param name="rgfReserved">Reserved.</param>
        /// <param name="ppv">Pointer to the requested interface.</param>
        /// <returns>
        /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
        /// </returns>
        int IShellFolder.GetUIObjectOf(IntPtr hwndOwner, uint cidl, IntPtr apidl, ref Guid riid, uint rgfReserved, out IntPtr ppv)
        {
            //  Get the ID lists from the array of PIDLs provided.
            var idLists = PidlManager.APidlToIdListArray(apidl, (int)cidl);

            if (riid == typeof(IContextMenu).GUID || riid == typeof(IContextMenu2).GUID || riid == typeof(IContextMenu3).GUID)
            {
                //  If the folder implments the context menu provider, we can use that.
                var contextMenuProvider = proxyFolder as IShellNamespaceFolderContextMenuProvider;
                if (contextMenuProvider != null)
                {
                    ppv = Marshal.GetComInterfaceForObject(contextMenuProvider.CreateContextMenu(idListAbsolute, idLists),
                                                           typeof(IContextMenu));
                    return(WinError.S_OK);
                }
                var dcm = new DEFCONTEXTMENU
                {
                    hwnd                = hwndOwner,
                    pcmcb               = null,
                    pidlFolder          = PidlManager.IdListToPidl(idListAbsolute),
                    psf                 = this,
                    cidl                = cidl,
                    apidl               = apidl,
                    punkAssociationInfo = IntPtr.Zero,
                    cKeys               = 0,
                    aKeys               = null
                };

                //  Create the default context menu.
                var result = Shell32.SHCreateDefaultContextMenu(dcm, riid, out ppv);
            }
            else if (riid == Shell32.IID_ExtractIconW)
            {
                //  If we've been asked for an icon, it should only be for a single PIDL.
                if (idLists.Length != 1)
                {
                    Diagnostics.Logging.Error(string.Format("The Shell Folder Impl for folder {0} has been asked for icons for multiple files at once, this is not supportedd.",
                                                            proxyFolder.GetDisplayName(DisplayNameContext.Normal)));
                    ppv = IntPtr.Zero;
                    return(WinError.E_FAIL);
                }

                //  Get the idlist and item.
                var idList = idLists[0];
                var item   = GetChildItem(idList);

                //  Now get the icon. If we don't provide one we'll use the defaults.
                var icon = item.GetIcon();
                if (icon == null)
                {
                    ProvideDefaultIExtractIcon(item is IShellNamespaceFolder, out ppv);
                    return(WinError.S_OK);
                }
                else
                {
                    //  Create an icon provider.
                    var provider = new Components.ExtractIconImpl()
                    {
                        DoNotCacheIcons = false, Icon = icon
                    };
                    ppv = Marshal.GetComInterfaceForObject(provider, typeof(IExtractIconW));
                    return(WinError.S_OK);
                }
            }
            else if (riid == Shell32.IID_IDataObject)
            {
                //  Create the data object.
                Shell32.SHCreateDataObject(PidlManager.IdListToPidl(idListAbsolute), cidl, apidl, null, riid, out ppv);
            }
            else if (riid == Shell32.IID_IQueryAssociations)
            {
                //  If we've been asked for a query associations, it should only be for a single PIDL.
                if (idLists.Length != 1)
                {
                    Diagnostics.Logging.Error(string.Format("The Shell Folder Impl for folder {0} has been asked for query associations for multiple files at once, this is not supportedd.",
                                                            proxyFolder.GetDisplayName(DisplayNameContext.Normal)));
                    ppv = IntPtr.Zero;
                    return(WinError.E_FAIL);
                }
                var item     = GetChildItem(idLists[0]);
                var isFolder = item is IShellNamespaceFolder;

                if (isFolder)
                {
                    //  todo perhaps a good class name would simply be the
                    //  name of the item type? or an attribute that uses the classname as a
                    //  fallback.
                    var associations = new ASSOCIATIONELEMENT[]
                    {
                        new ASSOCIATIONELEMENT
                        {
                            ac       = ASSOCCLASS.ASSOCCLASS_PROGID_STR,
                            hkClass  = IntPtr.Zero,
                            pszClass = "FolderViewSampleType"
                        },
                        new ASSOCIATIONELEMENT
                        {
                            ac       = ASSOCCLASS.ASSOCCLASS_FOLDER,
                            hkClass  = IntPtr.Zero,
                            pszClass = "FolderViewSampleType"
                        }
                    };
                    Shell32.AssocCreateForClasses(associations, (uint)associations.Length, riid, out ppv);
                }
                else
                {
                    var associations = new ASSOCIATIONELEMENT[]
                    {
                        new ASSOCIATIONELEMENT
                        {
                            ac       = ASSOCCLASS.ASSOCCLASS_PROGID_STR,
                            hkClass  = IntPtr.Zero,
                            pszClass = "FolderViewSampleType"
                        }
                    };
                    Shell32.AssocCreateForClasses(associations, (uint)associations.Length, riid, out ppv);
                }
            }

            /*   } */


            //  We have a set of child pidls (i.e. length one). We can now offer interfaces such as:

            /*
             * IContextMenu	The cidl parameter can be greater than or equal to one.
             * IContextMenu2	The cidl parameter can be greater than or equal to one.
             * IDataObject	The cidl parameter can be greater than or equal to one.
             * IDropTarget	The cidl parameter can only be one.
             * IExtractIcon	The cidl parameter can only be one.
             * IQueryInfo	The cidl parameter can only be one.
             * */

            //  IID_IExtractIconW
            //  IID_IDataObject
            //  IID_IQueryAssociations
            //  Currently, we don't offer any extra child item UI objects.
            ppv = IntPtr.Zero;
            return(WinError.E_NOINTERFACE);
        }
Example #17
0
        public void CanGetShellFolder2()
        {
            string specialPath = KF_IID.ID_FOLDERID_UsersFiles;

            IdList parentIdList = null, relativeChild = null;
            var    retVal = PidlManager.GetParentIdListFromPath(specialPath, out parentIdList, out relativeChild);

            Assert.IsTrue(retVal);

            // Child item is the desktop -> cannot implement this for desktop since it has no parent
            if (parentIdList == null || relativeChild == null)
            {
                throw new NotImplementedException();
            }

            IntPtr parentPtr      = default(IntPtr);
            IntPtr relChildPtr    = default(IntPtr);
            IntPtr relChildPtr1   = default(IntPtr);
            IntPtr ptrShellFolder = default(IntPtr);

            try
            {
                parentPtr   = PidlManager.IdListToPidl(parentIdList);
                relChildPtr = PidlManager.IdListToPidl(relativeChild);

                Assert.IsTrue(parentPtr != default(IntPtr));
                Assert.IsTrue(relChildPtr != default(IntPtr));

                Guid    guid = typeof(IShellFolder2).GUID;
                HRESULT hr   = NativeMethods.SHBindToParent(relChildPtr, guid,
                                                            out ptrShellFolder, ref relChildPtr1);

                Assert.IsTrue(hr == HRESULT.S_OK);

                using (var shellFolder = new ShellFolder(ptrShellFolder))
                {
                    Assert.IsTrue(shellFolder != null);

                    var ParseName = shellFolder.GetShellFolderName(relChildPtr, SHGDNF.SHGDN_FORPARSING);
                    Assert.IsFalse(string.IsNullOrEmpty(ParseName));

                    var Name = shellFolder.GetShellFolderName(relChildPtr, SHGDNF.SHGDN_NORMAL);
                    Assert.IsFalse(string.IsNullOrEmpty(Name));
                }
            }
            finally
            {
                if (parentPtr != default(IntPtr))
                {
                    NativeMethods.ILFree(parentPtr);
                }

                if (relChildPtr != default(IntPtr))
                {
                    NativeMethods.ILFree(relChildPtr);
                }

                //                if (relChildPtr != default(IntPtr))
                //                    NativeMethods.ILFree(relChildPtr1);
            }
        }
Example #18
0
        public void GetIconForParentOfSpecialFolder()
        {
            var testPath = KF_IID.ID_FOLDERID_Fonts;

            IdList parentIdList = null, relativeChild = null;
            var    retVal = PidlManager.GetParentIdListFromPath(testPath, out parentIdList, out relativeChild);

            Assert.IsTrue(retVal);

            // Child item is the desktop -> extract and return desktop icon
            if (parentIdList == null || relativeChild == null)
            {
                throw new NotImplementedException();
            }

            IntPtr parentPtr      = default(IntPtr);
            IntPtr relChildPtr    = default(IntPtr);
            IntPtr ptrShellFolder = default(IntPtr);
            IntPtr ptrExtractIcon = default(IntPtr);
            IntPtr smallHicon     = default(IntPtr);
            IntPtr largeHicon     = default(IntPtr);

            try
            {
                parentPtr   = PidlManager.IdListToPidl(parentIdList);
                relChildPtr = PidlManager.IdListToPidl(relativeChild);

                Assert.IsTrue(parentPtr != default(IntPtr));
                Assert.IsTrue(relChildPtr != default(IntPtr));

                Guid    guid = typeof(IShellFolder2).GUID;
                HRESULT hr   = NativeMethods.SHBindToParent(parentPtr, guid,
                                                            out ptrShellFolder, ref relChildPtr);

                Assert.IsTrue(hr == HRESULT.S_OK);

                using (var shellFolder = new ShellFolder(ptrShellFolder))
                {
                    Assert.IsTrue(shellFolder != null);

                    guid = typeof(IExtractIcon).GUID;
                    var pidls = new[] { relChildPtr };
                    hr = shellFolder.Obj.GetUIObjectOf(IntPtr.Zero, 1, pidls, guid,
                                                       IntPtr.Zero, out ptrExtractIcon);

                    Assert.IsTrue(hr == HRESULT.S_OK);

                    using (var extractIcon = new GenericCOMFolder <IExtractIcon>(ptrExtractIcon))
                    {
                        Assert.IsTrue(extractIcon != null);

                        var  iconFile = new StringBuilder(NativeMethods.MAX_PATH);
                        int  index    = -1;
                        uint pwFlags  = 0;
                        hr = extractIcon.Obj.GetIconLocation(0, iconFile, (uint)iconFile.Capacity,
                                                             ref index, ref pwFlags);

                        Assert.IsTrue(hr == HRESULT.S_OK);

                        Assert.IsFalse(string.IsNullOrEmpty(iconFile.ToString()));

                        hr = extractIcon.Obj.Extract(iconFile.ToString(), index,
                                                     ref smallHicon, ref largeHicon, 16);

                        Assert.IsTrue(hr == HRESULT.S_OK);
                        PngBitmapDecoder bitmapDecoder = null;
                        using (var memoryStream = new MemoryStream())
                        {
                            Icon.FromHandle(smallHicon).ToBitmap().Save(memoryStream, ImageFormat.Png);
                            memoryStream.Seek(0, SeekOrigin.Begin);

                            // Decode the icon
                            bitmapDecoder = new PngBitmapDecoder(memoryStream, BitmapCreateOptions.None, BitmapCacheOption.Default);
                        }

                        Assert.IsTrue(bitmapDecoder != null);
                        Assert.IsTrue(bitmapDecoder.Frames != null);
                        Assert.IsTrue(bitmapDecoder.Frames.Count > 0);

                        Assert.IsTrue(bitmapDecoder.Frames[0] != null);

                        bitmapDecoder = null;
                        using (var memoryStream = new MemoryStream())
                        {
                            Icon.FromHandle(largeHicon).ToBitmap().Save(memoryStream, ImageFormat.Png);
                            memoryStream.Seek(0, SeekOrigin.Begin);

                            // Decode the icon
                            bitmapDecoder = new PngBitmapDecoder(memoryStream, BitmapCreateOptions.None, BitmapCacheOption.Default);
                        }

                        Assert.IsTrue(bitmapDecoder != null);
                        Assert.IsTrue(bitmapDecoder.Frames != null);
                        Assert.IsTrue(bitmapDecoder.Frames.Count > 0);

                        Assert.IsTrue(bitmapDecoder.Frames[0] != null);
                    }
                }
            }
            finally
            {
                if (parentPtr != default(IntPtr))
                {
                    NativeMethods.ILFree(parentPtr);
                }

////                if (relChildPtr != default(IntPtr))    NOT NECESSARY
////                    NativeMethods.ILFree(relChildPtr);

                if (smallHicon != default(IntPtr))
                {
                    NativeMethods.DestroyIcon(smallHicon);
                }

                if (largeHicon != default(IntPtr))
                {
                    NativeMethods.DestroyIcon(largeHicon);
                }
            }
        }
Example #19
0
        /// <summary>
        /// Gets an icons reource id if available in the format:
        /// "filename, index"
        /// where the first part is a string and the 2nd part is a negativ integer number).
        ///
        /// This format is usally used by the Windows Shell libraries so we use it here
        /// to add missing ResourceIds.
        /// </summary>
        /// <param name="parentIdList"></param>
        /// <param name="filename"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        internal static bool GetIconResourceId(IdList parentIdList,
                                               out string filename,
                                               out int index)
        {
            filename = null;
            index    = -1;

            IntPtr parentPtr      = default(IntPtr);
            IntPtr relChildPtr    = default(IntPtr);
            IntPtr ptrShellFolder = default(IntPtr);
            IntPtr ptrExtractIcon = default(IntPtr);
            IntPtr smallHicon     = default(IntPtr);
            IntPtr largeHicon     = default(IntPtr);

            try
            {
                if (parentIdList.Size == 0)
                {
                    parentPtr   = PidlManager.IdListToPidl(parentIdList);
                    relChildPtr = PidlManager.IdListToPidl(IdList.Create());
                }
                else
                {
                    IdList parIdList = null, relChildIdList = null;
                    PidlManager.GetParentChildIdList(parentIdList, out parIdList, out relChildIdList);

                    parentPtr   = PidlManager.IdListToPidl(parIdList);
                    relChildPtr = PidlManager.IdListToPidl(relChildIdList);
                }

                if (parentPtr == default(IntPtr) || relChildPtr == default(IntPtr))
                {
                    return(false);
                }

                Guid    guid = typeof(IShellFolder2).GUID;
                HRESULT hr   = NativeMethods.SHBindToParent(parentPtr, guid,
                                                            out ptrShellFolder, ref relChildPtr);

                if (hr != HRESULT.S_OK)
                {
                    return(false);
                }

                using (var shellFolder = new ShellFolder(ptrShellFolder))
                {
                    if (shellFolder == null)
                    {
                        return(false);
                    }

                    guid = typeof(IExtractIcon).GUID;
                    var pidls = new IntPtr[] { relChildPtr };
                    hr = shellFolder.Obj.GetUIObjectOf(IntPtr.Zero, 1, pidls, guid,
                                                       IntPtr.Zero, out ptrExtractIcon);

                    if (hr != HRESULT.S_OK)
                    {
                        return(false);
                    }

                    using (var extractIcon = new GenericCOMFolder <IExtractIcon>(ptrExtractIcon))
                    {
                        if (extractIcon == null)
                        {
                            return(false);
                        }

                        var  iconFile = new StringBuilder(NativeMethods.MAX_PATH);
                        uint pwFlags  = 0;

                        hr = extractIcon.Obj.GetIconLocation(0, iconFile,
                                                             (uint)iconFile.Capacity,
                                                             ref index, ref pwFlags);

                        if (hr != HRESULT.S_OK)
                        {
                            return(false);
                        }

                        if (string.IsNullOrEmpty(iconFile.ToString()))
                        {
                            return(false);
                        }

                        filename = iconFile.ToString();

                        return(true);
                    }
                }
            }
            finally
            {
                if (parentPtr != default(IntPtr))
                {
                    NativeMethods.ILFree(parentPtr);
                }

                ////if (relChildPtr != default(IntPtr))
                ////    Shell32.ILFree(relChildPtr);

                if (smallHicon != default(IntPtr))
                {
                    NativeMethods.DestroyIcon(smallHicon);
                }

                if (largeHicon != default(IntPtr))
                {
                    NativeMethods.DestroyIcon(largeHicon);
                }
            }
        }
Example #20
0
////        public void LoadProperties()
////        {
////            if (_KnownFolderIsInitialized == false)
////            {
////                _KnownFolderIsInitialized = true;
////                KnownFolder = LoadKnownFolder();
////            }
////
////            if (_ItemTypeIsInitialized == false)
////            {
////                _ItemTypeIsInitialized = true;
////                ItemType = LoadItemType();
////            }
////
////            if (_IconResourceIdInitialized == false)
////            {
////                _IconResourceIdInitialized = true;
////                _IconResourceId = LoadIconResourceId();
////            }
////        }

        /// <summary>
        /// Initializes the items type flags and path properties.
        /// </summary>
        /// <param name="path">Is either a path reference a la 'C:' or a
        /// special folder path reference a la '::{...}' <seealso cref="KF_IID"/>
        /// for more details.</param>
        /// <returns>Returns a simple pojo type object to initialize
        /// the calling object members.</returns>
        internal static BrowseItemFromPath InitItem(string path)
        {
            if (string.IsNullOrEmpty(path) == true)   // return unknown references
            {
                var ret = new BrowseItemFromPath(path, path);
                ret.Name = path;
                return(ret);
            }

            if (path.Length == 38)
            {
                try
                {
                    Guid theGuid;
                    if (Guid.TryParse(path, out theGuid) == true)
                    {
                        path = KF_IID.IID_Prefix + path;
                    }
                }
                catch
                {
                    // Catching errors just in case ...
                }
            }

            // Return item for root desktop item
            if (string.Compare(path, KF_IID.ID_ROOT_Desktop, true) == 0)
            {
                return(InitDesktopRootItem());
            }

            ShellHelpers.SpecialPath isSpecialID = ShellHelpers.IsSpecialPath(path);
            string normPath = null, SpecialPathId = null;
            bool   hasPIDL = false;
            IdList parentIdList, relativeChildIdList;

            if (isSpecialID == ShellHelpers.SpecialPath.IsSpecialPath)
            {
                SpecialPathId = path;
                hasPIDL       = PidlManager.GetParentIdListFromPath(path, out parentIdList, out relativeChildIdList);
            }
            else
            {
                normPath = Browser.NormalizePath(path);
                hasPIDL  = PidlManager.GetParentIdListFromPath(normPath, out parentIdList, out relativeChildIdList);
            }

            if (hasPIDL == false)   // return references that cannot resolve with a PIDL
            {
                var ret = new BrowseItemFromPath(path, path);
                ret.Name = path;
                return(ret);
            }

            string parseName      = normPath;
            string name           = normPath;
            string labelName      = null;
            IdList fullIdList     = null;

            // Get the IShellFolder2 Interface for the original path item...
            IntPtr fullPidlPtr    = default(IntPtr);
            IntPtr ptrShellFolder = default(IntPtr);
            IntPtr parentPIDLPtr  = default(IntPtr);
            IntPtr relativeChildPIDLPtr = default(IntPtr);

            try
            {
                // We are asked to build the desktop root item here...
                if (parentIdList == null && relativeChildIdList == null)
                {
                    using (var shellFolder = new ShellFolderDesktop())
                    {
                        parseName = shellFolder.GetShellFolderName(fullPidlPtr, SHGDNF.SHGDN_FORPARSING);
                        name      = shellFolder.GetShellFolderName(fullPidlPtr, SHGDNF.SHGDN_INFOLDER | SHGDNF.SHGDN_FOREDITING);
                        labelName = shellFolder.GetShellFolderName(fullPidlPtr, SHGDNF.SHGDN_NORMAL);
                    }
                }
                else
                {
                    fullIdList  = PidlManager.CombineParentChild(parentIdList, relativeChildIdList);
                    fullPidlPtr = PidlManager.IdListToPidl(fullIdList);

                    if (fullPidlPtr == default(IntPtr))
                    {
                        return(null);
                    }

                    HRESULT hr = HRESULT.False;

                    if (fullIdList.Size == 1) // Is this item directly under the desktop root?
                    {
                        hr = NativeMethods.SHGetDesktopFolder(out ptrShellFolder);

                        if (hr != HRESULT.S_OK)
                        {
                            return(null);
                        }

                        using (var shellFolder = new ShellFolder(ptrShellFolder))
                        {
                            parseName = shellFolder.GetShellFolderName(fullPidlPtr, SHGDNF.SHGDN_FORPARSING);
                            name      = shellFolder.GetShellFolderName(fullPidlPtr, SHGDNF.SHGDN_INFOLDER | SHGDNF.SHGDN_FOREDITING);
                            labelName = shellFolder.GetShellFolderName(fullPidlPtr, SHGDNF.SHGDN_NORMAL);
                        }
                    }
                    else
                    {
                        parentPIDLPtr        = PidlManager.IdListToPidl(parentIdList);
                        relativeChildPIDLPtr = PidlManager.IdListToPidl(relativeChildIdList);

                        using (var desktopFolder = new ShellFolderDesktop())
                        {
                            hr = desktopFolder.Obj.BindToObject(parentPIDLPtr, IntPtr.Zero,
                                                                typeof(IShellFolder2).GUID, out ptrShellFolder);
                        }

                        if (hr != HRESULT.S_OK)
                        {
                            return(null);
                        }

                        // This item is not directly under the Desktop root
                        using (var shellFolder = new ShellFolder(ptrShellFolder))
                        {
                            parseName = shellFolder.GetShellFolderName(relativeChildPIDLPtr, SHGDNF.SHGDN_FORPARSING);
                            name      = shellFolder.GetShellFolderName(relativeChildPIDLPtr, SHGDNF.SHGDN_INFOLDER | SHGDNF.SHGDN_FOREDITING);
                            labelName = shellFolder.GetShellFolderName(relativeChildPIDLPtr, SHGDNF.SHGDN_NORMAL);
                        }
                    }
                }

                if (ShellHelpers.IsSpecialPath(parseName) == ShellHelpers.SpecialPath.None)
                {
                    normPath = parseName;
                }

                return(new BrowseItemFromPath(path, parseName, name, labelName,
                                              SpecialPathId, normPath
////                                               ,parentIdList, relativeChildIdList
                                              ));
            }
            finally
            {
                PidlManager.ILFree(parentPIDLPtr);
                PidlManager.ILFree(relativeChildPIDLPtr);

                if (fullPidlPtr != default(IntPtr))
                {
                    NativeMethods.ILFree(fullPidlPtr);
                }
            }
        }