// Returns: number of menu items inserted. // Ignore Send To menus, shortcuts, defaultonly int IContextMenu.QueryContextMenu(HMenu hMenu, int iMenu, int idCmdFirst, int idCmdLast, CMF uFlags) { int id = 0; if ((uFlags & (CMF.CMF_VERBSONLY | CMF.CMF_DEFAULTONLY | CMF.CMF_NOVERBS)) == 0 || (uFlags & CMF.CMF_EXPLORE) != 0) //if (IsFSItem(uFlags)) { if (Helpers.DragQueryFile(m_hDrop, 0xffffffff, null, 0) > 1) Helpers.InsertMenu(hMenu, iMenu, MFMENU.MF_STRING | MFMENU.MF_ENABLED, new IntPtr(idCmdFirst + 1), "&Rename ..."); // 1 for rename mFolders = Directory.GetDirectories(DropboxDir); // look into implementing caching folder list and hooking to file system watcher // Create the submenu popup, add folder items to it and then finally insert it into the explorer contextmenu. HMenu submenu = Helpers.CreatePopupMenu(); Helpers.AppendMenu(submenu, MFMENU.MF_STRING | MFMENU.MF_ENABLED, new IntPtr(idCmdFirst + 2), "Route"); // 2 for root dropbox folder. id = 2; for (int i = 0; i < mFolders.Length; i++) { Helpers.AppendMenu(submenu, MFMENU.MF_STRING | MFMENU.MF_ENABLED, new IntPtr(idCmdFirst + ++id), mFolders[i].Substring(mFolders[i].LastIndexOf('\\') + 1)); } Helpers.InsertMenu(hMenu, 5, MFMENU.MF_BYPOSITION | MFMENU.MF_POPUP | MFMENU.MF_ENABLED, submenu.handle, "Send to &Dropbox"); } return id; }
/// <summary> /// Called to query the context menu. /// </summary> /// <param name="hMenu">The handle to the parent menu.</param> /// <param name="indexMenu">The index of the menu.</param> /// <param name="idCmdFirst">The first command ID.</param> /// <param name="idCmdLast">The last command ID.</param> /// <param name="uFlags">The flags.</param> /// <returns>An HRESULT indicating success.</returns> int IContextMenu.QueryContextMenu(IntPtr hMenu, uint indexMenu, int idCmdFirst, int idCmdLast, CMF uFlags) { // Log this key event. Log(string.Format("Query Context Menu for items {0}", string.Join(", ", SelectedItemPaths))); // If we've got the defaultonly flag, we're done. if (uFlags.HasFlag(CMF.CMF_DEFAULTONLY)) return WinError.MAKE_HRESULT(WinError.SEVERITY_SUCCESS, 0, 0); // Set the first item id. var firstItemId = (uint)idCmdFirst; // Use the native context menu wrapper to build the context menu. uint lastItemId = 0; try { nativeContextMenuWrapper.ResetNativeContextMenu(); lastItemId = nativeContextMenuWrapper.BuildNativeContextMenu(hMenu, firstItemId, contextMenuStrip.Value.Items); } catch (Exception exception) { // Log the exception. LogError("An exception occured building the context menu.", exception); // Return the failure. return WinError.E_FAIL; } // Return success, passing the the last item ID plus one (which will be the next command id). // MSDN documentation is flakey here - to be explicit we need to return the count of the items added plus one. return WinError.MAKE_HRESULT(WinError.SEVERITY_SUCCESS, 0, (lastItemId - firstItemId) + 1); }
private ShellContextMenuHelper(IWin32Window owner, string[] fileNames, ContextMenuOptions options, EventHandler<ExecuteVerbEventArgs> onExecuteVerb) { this.ItemContainer = new Container(); this.OnExecuteVerb = null; this.Owner = owner; ParseFileNames(fileNames, out this.ParentName, out this.FileNames); this.Options = ((((options & ContextMenuOptions.Explore) > 0) ? (CMF.CMF_NORMAL | CMF.CMF_EXPLORE) : CMF.CMF_NORMAL) | (((options & ContextMenuOptions.CanRename) > 0) ? CMF.CMF_CANRENAME : CMF.CMF_NORMAL)) | (((options & ContextMenuOptions.VerbsOnly) > 0) ? (CMF.CMF_NORMAL | CMF.CMF_VERBSONLY) : CMF.CMF_NORMAL); this.OnExecuteVerb = onExecuteVerb; }
private ShellContextMenuHelper(IWin32Window owner, IContextMenu contextMenu, ContextMenuOptions options, EventHandler<ExecuteVerbEventArgs> onExecuteVerb) { this.ItemContainer = new Container(); this.OnExecuteVerb = null; this.Owner = owner; this.ContextMenu = contextMenu; this.Options = ((((options & ContextMenuOptions.Explore) > 0) ? (CMF.CMF_NORMAL | CMF.CMF_EXPLORE) : CMF.CMF_NORMAL) | (((options & ContextMenuOptions.CanRename) > 0) ? CMF.CMF_CANRENAME : CMF.CMF_NORMAL)) | (((options & ContextMenuOptions.VerbsOnly) > 0) ? (CMF.CMF_NORMAL | CMF.CMF_VERBSONLY) : CMF.CMF_NORMAL); this.OnExecuteVerb = onExecuteVerb; }
bool IsFSItem(CMF uFlags) { if ((uFlags & CMF.CMF_DEFAULTONLY) == 0) { uint nselected = Helpers.DragQueryFile(m_hDrop, 0xffffffff, null, 0); if (nselected >= 1) { StringBuilder sb = new StringBuilder(1024); Helpers.DragQueryFile(m_hDrop, 0, sb, sb.Capacity + 1); string fsi = sb.ToString(); if (Directory.Exists(fsi) || File.Exists(fsi)) return true; } } return false; }
int IContextMenu.QueryContextMenu(HMenu hMenu, uint iMenu, uint idCmdFirst, uint idCmdLast, CMF uFlags) { int id = 0; if ((uFlags & (CMF.CMF_VERBSONLY | CMF.CMF_DEFAULTONLY | CMF.CMF_NOVERBS)) == 0 || (uFlags & CMF.CMF_EXPLORE) != 0) { //创建子菜单 HMenu submenu = ShellLib.Helpers.CreatePopupMenu(); Helpers.AppendMenu(submenu, MFMENU.MF_STRING, new IntPtr(idCmdFirst + id++), "上传"); Helpers.AppendMenu(submenu, MFMENU.MF_STRING, new IntPtr(idCmdFirst + id++), "下载"); Helpers.AppendMenu(submenu, MFMENU.MF_STRING, new IntPtr(idCmdFirst + id++), "查看远程文件"); //将子菜单插入到上下文菜单中 Helpers.InsertMenu(hMenu, 1, MFMENU.MF_BYPOSITION | MFMENU.MF_POPUP, submenu.handle, "FTP管理"); //为菜单增加图标 Bitmap bpCopy = Resource1.copy; Helpers.SetMenuItemBitmaps(submenu, 0, MFMENU.MF_BYPOSITION, bpCopy.GetHbitmap(), bpCopy.GetHbitmap()); Helpers.SetMenuItemBitmaps(submenu, 1, MFMENU.MF_BYPOSITION, bpCopy.GetHbitmap(), bpCopy.GetHbitmap()); Bitmap bpHome = Resource1.home; Helpers.SetMenuItemBitmaps(submenu, 2, MFMENU.MF_BYPOSITION, bpHome.GetHbitmap(), bpHome.GetHbitmap()); } return id; }
int IContextMenu3.QueryContextMenu(IntPtr hMenu, uint indexMenu, int idCmdFirst, int idCmdLast, CMF uFlags) { return ((IContextMenu)this).QueryContextMenu(hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags); }
private void CreateMenu_ValidGitFile(HMenu hMenu, uint iMenu, uint idCmdFirst, uint idCmdLast, CMF uFlags) { Bitmap bpCopy = Resource1.home; //add menu items Helpers.InsertMenu(hMenu, (int)iMenu, MFMENU.MF_BYPOSITION | MFMENU.MF_STRING, new IntPtr(idCmdFirst + 7), "NGit Blame History"); Helpers.SetMenuItemBitmaps(hMenu, (int)iMenu, MFMENU.MF_BYPOSITION, bpCopy.GetHbitmap(), bpCopy.GetHbitmap()); ////add menu items //Helpers.InsertMenu(hMenu, (int)iMenu, MFMENU.MF_BYPOSITION | MFMENU.MF_STRING, new IntPtr(idCmdFirst + 7), "NGit Resolve Conflict"); //Helpers.SetMenuItemBitmaps(hMenu, (int)iMenu+1, MFMENU.MF_BYPOSITION, bpCopy.GetHbitmap(), bpCopy.GetHbitmap()); //Create Sub-Menu HMenu submenu = ShellLib.Helpers.CreatePopupMenu(); Helpers.AppendMenu(submenu, MFMENU.MF_STRING, new IntPtr(idCmdFirst + 3), "Working Area"); Helpers.AppendMenu(submenu, MFMENU.MF_STRING, new IntPtr(idCmdFirst + 4), "Local Storage"); Helpers.AppendMenu(submenu, MFMENU.MF_STRING, new IntPtr(idCmdFirst + 5), "Remote Storage"); Helpers.AppendMenu(submenu, MFMENU.MF_STRING, new IntPtr(idCmdFirst + 6), "Main APP"); Helpers.InsertMenu(hMenu, (int)iMenu + 2, MFMENU.MF_BYPOSITION | MFMENU.MF_POPUP, submenu.handle, "NGit Main"); //add icon into sub-menu //Bitmap bpCopy = Resource1.copy; Helpers.SetMenuItemBitmaps(submenu, 0, MFMENU.MF_BYPOSITION, bpCopy.GetHbitmap(), bpCopy.GetHbitmap()); Helpers.SetMenuItemBitmaps(submenu, 1, MFMENU.MF_BYPOSITION, bpCopy.GetHbitmap(), bpCopy.GetHbitmap()); Helpers.SetMenuItemBitmaps(submenu, 2, MFMENU.MF_BYPOSITION, bpCopy.GetHbitmap(), bpCopy.GetHbitmap()); Helpers.SetMenuItemBitmaps(submenu, 3, MFMENU.MF_BYPOSITION, bpCopy.GetHbitmap(), bpCopy.GetHbitmap()); Helpers.InsertMenu(hMenu, (int)iMenu + 3, MFMENU.MF_BYPOSITION | MFMENU.MF_SEPARATOR, new IntPtr(idCmdFirst + 0), "NGit line"); }
int IContextMenu.QueryContextMenu(HMenu hMenu, uint iMenu, uint idCmdFirst, uint idCmdLast, CMF uFlags) { //if ((uFlags & (CMF.CMF_VERBSONLY | CMF.CMF_DEFAULTONLY | CMF.CMF_NOVERBS)) == 0 || if ((uFlags & (CMF.CMF_DEFAULTONLY | CMF.CMF_NOVERBS)) == 0 || (uFlags & CMF.CMF_EXPLORE) != 0) { uint nselected = Helpers.DragQueryFile(m_hDrop, 0xffffffff, null, 0); if (nselected <= 0 && string.IsNullOrEmpty(m_szFoderPath) ) { CreateMenu_Base(hMenu, iMenu, idCmdFirst, idCmdLast, uFlags); } else if(false==string.IsNullOrEmpty(m_szFoderPath)) //valid blank right click context menu { if (string.IsNullOrEmpty(CHelpFuntions.GetValidWorkingDir(m_szFoderPath))) { CreateMenu_InValidGit(hMenu, iMenu, idCmdFirst, idCmdLast, uFlags); } else { CreateMenu_ValidGit(hMenu, iMenu, idCmdFirst, idCmdLast, uFlags); } } else if(nselected >1) { CreateMenu_Base(hMenu, iMenu, idCmdFirst, idCmdLast, uFlags); } else if(nselected ==1) { StringBuilder sb = new StringBuilder(1024); ShellLib.Helpers.DragQueryFile(m_hDrop, 0, sb, sb.Capacity + 1); string szDir=sb.ToString(); if (Directory.Exists(szDir)) { if (string.IsNullOrEmpty(CHelpFuntions.GetValidWorkingDir(szDir))) { CreateMenu_InValidGit(hMenu, iMenu, idCmdFirst, idCmdLast, uFlags); } else { CreateMenu_ValidGit(hMenu, iMenu, idCmdFirst, idCmdLast, uFlags); } } else { if (string.IsNullOrEmpty(CHelpFuntions.GetValidWorkingDir(szDir))) { CreateMenu_Base(hMenu, iMenu, idCmdFirst, idCmdLast, uFlags); } else { if (m_NgitMgr != null) { FileSccStatus status = m_NgitMgr.GetFileStatus(szDir); if (status == FileSccStatus.ST_CONFLICT) { CreateMenu_ConflictFile(hMenu, iMenu, idCmdFirst, idCmdLast, uFlags); } else if (status != FileSccStatus.ST_NOT_CONTROLLED && status != FileSccStatus.ST_IGNORED && status != FileSccStatus.ST_INVALID_REPO && status != FileSccStatus.ST_NULL) { CreateMenu_ValidGitFile(hMenu, iMenu, idCmdFirst, idCmdLast, uFlags); } else { CreateMenu_Base(hMenu, iMenu, idCmdFirst, idCmdLast, uFlags); } } } } } } return 8; }
/// <summary> /// Shows a context menu for a shell item. /// </summary> /// /// <param name="control"> /// The parent control. /// </param> /// /// <param name="pos"> /// The position on <paramref name="control"/> that the menu /// should be displayed at. /// </param> /// <param name="aditionalFlags"></param> /// <param name="IsOnEmpty"></param> public void ShowContextMenu(Control control, Point pos, CMF aditionalFlags = 0, bool IsOnEmpty = false) { using (ContextMenu mnu = new ContextMenu()) { pos = control.PointToScreen(pos); Populate(mnu, aditionalFlags); ContextMenu view = new ContextMenu(); ContextMenu sortMenu = new ContextMenu(); ContextMenu groupMenu = new ContextMenu(); int count = User32.GetMenuItemCount(mnu.Handle); var itemInfo = new MENUITEMINFO(); itemInfo.cbSize = (uint)Marshal.SizeOf(itemInfo); itemInfo.fMask = MIIM.MIIM_FTYPE | MIIM.MIIM_DATA | MIIM.MIIM_STRING | MIIM.MIIM_SUBMENU; if (User32.GetMenuItemInfo(mnu.Handle, count - 1, true, ref itemInfo)) { if ((itemInfo.fType & 2048) != 0) { User32.DeleteMenu(mnu.Handle, count - 1, MF.MF_BYPOSITION); } } if (IsOnEmpty) { this.RemoveDefaultExplorerItems(mnu, control, ref itemInfo); } User32.GetMenuItemInfo(mnu.Handle, User32.GetMenuItemCount(mnu.Handle) - 3, true, ref itemInfo); if (itemInfo.hSubMenu == IntPtr.Zero) { User32.GetMenuItemInfo(mnu.Handle, User32.GetMenuItemCount(mnu.Handle) - 1, true, ref itemInfo); } this._NewMenuPtr = itemInfo.hSubMenu; if (IsOnEmpty) { this.GenerateExplorerBackgroundMenuItems(view, mnu, sortMenu, groupMenu); } else { if (this._Items.FirstOrDefault()?.IsFolder == true) { this.GenerateMenuItem(mnu, System.Windows.Application.Current?.FindResource("mnuOpenNewTab")?.ToString(), 301, false, 1); } } this.RemoveDuplicatedSeparators(mnu); int command = User32.TrackPopupMenuEx(mnu.Handle, TPM.TPM_RETURNCMD, pos.X, pos.Y, m_MessageWindow.Handle, IntPtr.Zero); if (command > 0 && command < m_CmdFirst) { switch (command) { case 245: this._ShellView.SetGroupOrder(false); break; case 246: this._ShellView.SetGroupOrder(); break; case 247: var colasc = this._ShellView.Collumns.FirstOrDefault(w => w.ID == this._ShellView.LastSortedColumnId); this._ShellView.SetSortCollumn(true, colasc, SortOrder.Ascending); break; case 248: var coldesc = this._ShellView.Collumns.FirstOrDefault(w => w.ID == this._ShellView.LastSortedColumnId); this._ShellView.SetSortCollumn(true, coldesc, SortOrder.Descending); break; case 249: this._ShellView.PasteAvailableFiles(); break; case 250: this._ShellView.RefreshContents(); break; case 251: this._ShellView.View = ShellViewStyle.ExtraLargeIcon; break; case 252: this._ShellView.View = ShellViewStyle.LargeIcon; break; case 253: this._ShellView.View = ShellViewStyle.Medium; break; case 254: this._ShellView.View = ShellViewStyle.SmallIcon; break; case 255: this._ShellView.View = ShellViewStyle.List; break; case 256: this._ShellView.View = ShellViewStyle.Details; break; case 257: this._ShellView.View = ShellViewStyle.Tile; break; case 258: this._ShellView.View = ShellViewStyle.Content; break; case 259: this._ShellView.View = ShellViewStyle.Thumbstrip; break; case 260: if (this._ShellView.IsGroupsEnabled) { this._ShellView.DisableGroups(); } break; case 301: this._ShellView.RaiseMiddleClickOnItem(this._Items.First()); break; default: break; } if (command >= 262 && command <= 262 + this._ShellView.Collumns.Count) { this._ShellView.SetSortCollumn(true, this._ShellView.Collumns[command - 262], SortOrder.Ascending); } else if (command > 260 && command != 301) { if (!this._ShellView.IsGroupsEnabled) this._ShellView.EnableGroups(); this._ShellView.GenerateGroupsFromColumn(this._ShellView.Collumns[command - (262 + this._ShellView.Collumns.Count) - 1], false); } } if (command > m_CmdFirst) { string info = string.Empty; byte[] bytes = new byte[256]; int index; m_ComInterface.GetCommandString(command - (int)m_CmdFirst, 4, 0, bytes, 260); index = 0; while (index < bytes.Length - 1 && (bytes[index] != 0 || bytes[index + 1] != 0)) { index += 2; } if (index < bytes.Length - 1) info = Encoding.Unicode.GetString(bytes, 0, index); switch (info) { case "open": (control as ShellView)?.OpenOrNavigateItem(); break; case "rename": (control as ShellView)?.RenameSelectedItem(); break; case "cut": (control as ShellView)?.CutSelectedFiles(); break; case "copy": (control as ShellView)?.CopySelectedFiles(); break; default: InvokeCommand((IntPtr)(command - m_CmdFirst), pos, (IntPtr)(command - m_CmdFirst)); break; } } //if (command == 0) { // if (this._ShellView != null) // this._ShellView.IsRenameNeeded = false; //} User32.DestroyMenu(mnu.Handle); view.Dispose(); User32.DestroyMenu(view.Handle); sortMenu.Dispose(); User32.DestroyMenu(sortMenu.Handle); groupMenu.Dispose(); User32.DestroyMenu(groupMenu.Handle); } Marshal.ReleaseComObject(m_ComInterface); Marshal.ReleaseComObject(m_ComInterface2); Marshal.ReleaseComObject(m_ComInterface3); Marshal.Release(_Result); _Result = IntPtr.Zero; }
/// <summary> /// Populates a <see cref="Menu"/> with the context menu items for /// a shell item. /// </summary> /// /// <remarks> /// If this method is being used to populate a Form's main menu /// then you need to call <see cref="HandleMenuMessage"/> in the /// Form's message handler. /// </remarks> /// /// <param name="menu">The menu to populate.</param> /// <param name="additionalFlags"></param> public void Populate(Menu menu, CMF additionalFlags) { m_ComInterface.QueryContextMenu(menu.Handle, 0, (int)m_CmdFirst, int.MaxValue, CMF.EXPLORE | additionalFlags | (Control.ModifierKeys == Keys.Shift ? CMF.EXTENDEDVERBS : 0)); }
HResult IContextMenu2.QueryContextMenu(IntPtr hMenu, uint indexMenu, int idCmdFirst, int idCmdLast, CMF uFlags) { return((this as IContextMenu).QueryContextMenu(hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags)); }
/// <summary> /// Called to query the context menu. /// </summary> /// <param name="hMenu">The handle to the parent menu.</param> /// <param name="indexMenu">The index of the menu.</param> /// <param name="idCmdFirst">The first command ID.</param> /// <param name="idCmdLast">The last command ID.</param> /// <param name="uFlags">The flags.</param> /// <returns>An HRESULT indicating success.</returns> HResult IContextMenu.QueryContextMenu(IntPtr hMenu, uint indexMenu, int idCmdFirst, int idCmdLast, CMF uFlags) { // Log this key event. Log(string.Format("Query Context Menu for items: {0}{1}", Environment.NewLine, string.Join(Environment.NewLine, SelectedItemPaths))); // If we've got the defaultonly flag, we're done. if (uFlags.HasFlag(CMF.CMF_DEFAULTONLY)) { return(WinError.MAKE_HResult(WinError.SEVERITY_SUCCESS, 0, 0)); } // Before we build the context menu, determine whether we need to show it. try { // If we can't show the menu, return false. if (!CanShowMenu()) { return(HResult.S_FALSE); } } catch (Exception exception) { // We can't show the menu. LogError("An exception ocurred determining whether the context menu should be shown.", exception); // Return the failure. return(HResult.E_FAIL); } // Set the first item id. var firstItemId = (uint)idCmdFirst; // Use the native context menu wrapper to build the context menu. uint lastItemId = 0; try { nativeContextMenuWrapper.ResetNativeContextMenu(); lastItemId = nativeContextMenuWrapper.BuildNativeContextMenu(hMenu, firstItemId, contextMenuStrip.Value.Items); } catch (Exception exception) { // DebugLog the exception. LogError("An exception occured building the context menu.", exception); // Return the failure. return(HResult.E_FAIL); } // Return success, passing the the last item ID plus one (which will be the next command id). // MSDN documentation is flakey here - to be explicit we need to return the count of the items added plus one. return(WinError.MAKE_HResult(WinError.SEVERITY_SUCCESS, 0, (lastItemId - firstItemId) + 1)); }
HResult IContextMenu3.QueryContextMenu(IntPtr hMenu, uint indexMenu, int idCmdFirst, int idCmdLast, CMF uFlags) { var menu = this as IContextMenu; return(menu == null ? HResult.E_NOTIMPL : menu.QueryContextMenu(hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags)); }