예제 #1
0
        public bool InitFolder(IShellFolder folder, IntPtr itemPidl)
        {
            var relativePidl = ILShell32.ILFindLastID(itemPidl);

            if (comInterface != null && messageWindow != null)
            {
                return(true);
            }

            IntPtr result = IntPtr.Zero;

            IntPtr[] apidls = new IntPtr[] { itemPidl };

            var refGuid = typeof(IContextMenu).GUID;

            try
            {
                //PUIDLIST_RELATIVE ILFindChild(
                //  _In_ PCIDLIST_ABSOLUTE pidlParent,
                //  _In_ PCIDLIST_ABSOLUTE pidlChild
                //);

                PidlHandle handle   = new PidlHandle(relativePidl);
                var        itemPath = handle.Path;

                var relPidls = new IntPtr[] { relativePidl };

                folder.GetUIObjectOf(IntPtr.Zero,
                                     (uint)relPidls.Length,
                                     relPidls, // [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
                                     ref refGuid, 0, out result);

                if (result != IntPtr.Zero)
                {
                    comInterface = (IContextMenu)
                                   Marshal.GetTypedObjectForIUnknown(result,
                                                                     typeof(IContextMenu));

                    comInterface2 = comInterface as IContextMenu2;
                    comInterface3 = comInterface as IContextMenu3;
                    messageWindow = new MessageWindow(this);
                }
                else
                {
                    var handle2 = new PidlHandle(itemPidl);
                }
            }
            catch (Exception ex)
            {
                // Value does not fall within the expected range.
                this.LastError = ex;
            }

            return(result != IntPtr.Zero);
        }
예제 #2
0
        /// <summary>
        /// Shows a context menu for a shell item.
        /// </summary>
        public void ShowContextMenu(Control control, Point pos)
        {
            if (messageWindow == null || messageWindow.Handle == IntPtr.Zero)
            {
                return;
            }

            using (ContextMenu menu = new ContextMenu())
            {
                pos = control.PointToScreen(pos);
                Populate(menu);

                int command = ILShell32.TrackPopupMenuEx(menu.Handle,
                                                         TPM.TPM_RETURNCMD, pos.X, pos.Y, messageWindow.Handle,
                                                         IntPtr.Zero);
                if (command > 0)
                {
                    InvokeCommand(command - cmdFirst);
                }
            }
        }
예제 #3
0
        public bool InitFolderPath(IShellFolder folder, IShellItem parent, IntPtr itemPidl, string path)
        {
            IntPtr pidl = itemPidl;

            if (path != null && Directory.Exists(path))     // if item is directory
            {
                IntPtr combine      = IntPtr.Zero;
                string parentFolder = Path.GetFullPath(path + @"\..");
                try
                {
                    // IntPtr result;
                    //var folderParent = (IShellFolder)Marshal.GetTypedObjectForIUnknown(result,
                    //    typeof(IShellFolder));
                    //ComAliasNameAttribute <

                    var parentPidl = ShPidlSystem.FromPath(parentFolder);
                    // clone = PidlClone.Of(itemPidl);

                    combine = ILShell32.ILCombine(parentPidl.Handle.pidl, itemPidl);

                    // ILShell32.ILRemoveLastID(combine);
                }
                catch (Exception ex)
                {
                    this.LastError = ex;
                }

                if (combine == IntPtr.Zero)
                {
                    return(false);
                }

                pidl = combine;
                var check = new PidlHandle(pidl);
            }

            return(InitFolder(folder, pidl));
        }
예제 #4
0
        //  pidl array Initialize retry
        public static IntPtr[] GetFolderPidlRetry(string path, ref IShellFolder folder, ref IShellItem parent,
                                                  IntPtr?itemPidl = null)
        {
            string path2 = null;
            IntPtr pidl  = IntPtr.Zero;

            if (itemPidl != null)
            {
                pidl = itemPidl.Value;
            }
            else
            {
                var item = ShPidlSystem.FromPath(path);
                pidl = item.Handle.pidl;
            }

            IShellItem parentInfo = null;

            folder = null;
            IntPtr[] pidls     = EmptyPidls;
            String   pathCheck = null;

            try
            {
                // if (RunningVista)
                IShellItem i = ILShell32.SHCreateItemFromParsingName(path, IntPtr.Zero,
                                                                     typeof(IShellItem).GUID);
                i.GetParent(out parentInfo);

                StringBuilder path2Ref = new StringBuilder(FileSystem.MAX_PATH);
                if (Shell32.SHGetPathFromIDList(pidl, path2Ref) > 0) // == WinError.S_OK)
                {
                    path2 = path2Ref.ToString();
                }
                //return Marshal.StringToHGlobalUni(result.ToString());

                folder = GetIShellFolderCom <IShellFolder>(i);
                IntPtr relativePidl = ILShell32.ILFindLastID(pidl);
                pidls = new IntPtr[] { relativePidl };

                StringBuilder resultStr = new StringBuilder(FileSystem.MAX_PATH);
                if (!ILShell32.SHGetPathFromIDList(relativePidl, resultStr))
                {
                    pathCheck = resultStr.ToString();
                }

                if (relativePidl != IntPtr.Zero)
                {
                    parent = parentInfo;
                }
            }
            catch (Exception)
            {
                // Free the PIDL, reset the result.
                // Marshal.FreeCoTaskMem(relativePidl);
                // throw new InvalidOperationException("Failed to initialise child.", exception);
                folder = null;
                pidls  = EmptyPidls;
            }

            return(pidls);
        }
예제 #5
0
        void Initialize(ShellItem[] items)
        {
            IntPtr[]  pidls  = new IntPtr[items.Length];
            ShellItem parent = null;

            for (int n = 0; n < items.Length; ++n)
            {
                pidls[n] = ILShell32.ILFindLastID(items[n].Pidl); // RelPidl

                if (parent == null)
                {
                    if (items[n] == ShellItem.Desktop)
                    {
                        parent = ShellItem.Desktop;
                    }
                    else
                    {
                        parent = items[n].Parent;
                    }
                }
                else
                {
                    if (items[n].Parent != parent)
                    {
                        throw new Exception("All shell items must have the same parent");
                    }
                }
            }

            IShellFolder folder     = null;
            IShellItem   parentItem = null;
            var          item       = items[0];
            var          path       = item.Path;

            if (parent != null && parent.IsFileSystem)
            {
                folder = GetIShellFolder(parent);
            }
            else
            {
                GetFolderPidlRetry(path, ref folder, ref parentItem, item.Pidl);
            }

            if (folder == null ||
                parent != null && parent.Parent == ShellItem.Desktop && !parent.IsFileSystem && !item.IsFolder)
            {
                if (item.IsFolder)
                {
                    return;
                }
                // GetUIObjectOf : has exited with code -1073741819 (0xc0000005) 'Access violation'.
            }

            if (item.IsFolder)
            {
                InitFolderPath(folder, parentItem, pidls[0], path);
            }
            else
            {
                InitFolder(folder, pidls[0]);
            }
        }