Example #1
0
        private void SetupContextMenu(ShellItem[] files, ShellFolder parentFolder, IntPtr hwndOwner, bool isInteractive, bool canRename, ShellMenuCommandBuilder preBuilder, ShellMenuCommandBuilder postBuilder)
        {
            try
            {
                if (GetIContextMenu(files, parentFolder, hwndOwner, out iContextMenuPtr, out iContextMenu))
                {
                    // get some properties about our file(s)
                    bool allFolders = ItemsAllFolders(files);

                    CMF flags = CMF.EXPLORE |
                                CMF.ITEMMENU |
                                ((Control.ModifierKeys & Keys.Shift) != 0 ? CMF.EXTENDEDVERBS : 0);

                    if (canRename)
                    {
                        flags |= CMF.CANRENAME;
                    }

                    if (!isInteractive)
                    {
                        flags |= CMF.DEFAULTONLY;
                    }

                    nativeMenuPtr = Interop.CreatePopupMenu();

                    uint numPrepended = ConfigureMenuItems(allFolders, nativeMenuPtr, preBuilder);

                    iContextMenu.QueryContextMenu(
                        nativeMenuPtr,
                        numPrepended,
                        Interop.CMD_FIRST,
                        Interop.CMD_LAST,
                        flags);

                    ConfigureMenuItems(allFolders, nativeMenuPtr, postBuilder);

                    if (isInteractive)
                    {
                        if (Marshal.QueryInterface(iContextMenuPtr, ref Interop.IID_IContextMenu2,
                                                   out iContextMenu2Ptr) == NativeMethods.S_OK)
                        {
                            if (iContextMenu2Ptr != IntPtr.Zero)
                            {
                                try
                                {
                                    iContextMenu2 =
                                        (IContextMenu2)Marshal.GetTypedObjectForIUnknown(iContextMenu2Ptr, typeof(IContextMenu2));
                                }
                                catch (Exception e)
                                {
                                    ShellLogger.Error($"ShellItemContextMenu: Error retrieving IContextMenu2 interface: {e.Message}");
                                }
                            }
                        }

                        if (Marshal.QueryInterface(iContextMenuPtr, ref Interop.IID_IContextMenu3,
                                                   out iContextMenu3Ptr) == NativeMethods.S_OK)
                        {
                            if (iContextMenu3Ptr != IntPtr.Zero)
                            {
                                try
                                {
                                    iContextMenu3 =
                                        (IContextMenu3)Marshal.GetTypedObjectForIUnknown(iContextMenu3Ptr, typeof(IContextMenu3));
                                }
                                catch (Exception e)
                                {
                                    ShellLogger.Error($"ShellItemContextMenu: Error retrieving IContextMenu3 interface: {e.Message}");
                                }
                            }
                        }

                        ShowMenu(files, allFolders);
                    }
                    else
                    {
                        uint selected = Interop.GetMenuDefaultItem(nativeMenuPtr, 0, 0);

                        HandleMenuCommand(files, selected, allFolders);
                    }
                }
                else
                {
                    ShellLogger.Error("ShellItemContextMenu: Error retrieving IContextMenu");
                }
            }
            catch (Exception e)
            {
                ShellLogger.Error($"ShellItemContextMenu: Error building context menu: {e.Message}");
            }
            finally
            {
                FreeResources();

                foreach (var subMenu in ShellNewMenus)
                {
                    subMenu.FreeResources();
                }
            }
        }