private MenuCommand FindCommand(Guid guid, int id, ref int hrReturn) { hrReturn = (int)Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_UNKNOWNGROUP; MenuCommand result = null; //first query the IMenuCommandService and ask it to FindCommand IMenuCommandService menuCommandService = GetService(typeof(IMenuCommandService)) as IMenuCommandService; if (menuCommandService != null) { result = menuCommandService.FindCommand(new CommandID(guid, (int)id)); } //if the IMenuCommandService cames back w/o a command, then ask ourselves if (result == null && this != menuCommandService) { result = FindCommand(guid, (int)id); } if (result == null) { ICollection commands = GetCommandList(guid); if (commands != null) { // The default error now must be "Not Supported" because the command group is known hrReturn = (int)Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED; Debug.WriteLineIf(MENUSERVICE.TraceVerbose, "\t...VSMCS Found group"); // Get the list of command inside this group foreach (MenuCommand command in commands) { // we are looping again on the list of commands to check the DynamicItemMatch // but this is unavoidable in this context.... // If the command is a OleMenuCommand, then we can try to do a dynamic match IOleMenuCommand vsCommand = command as IOleMenuCommand; if ((null != vsCommand) && (vsCommand.DynamicItemMatch(id))) { Debug.WriteLineIf(MENUSERVICE.TraceVerbose, "\t...VSMCS Found command2"); hrReturn = NativeMethods.S_OK; result = command; } } } } else { Debug.WriteLineIf(MENUSERVICE.TraceVerbose, "\t... VSMCS Found command"); hrReturn = NativeMethods.S_OK; } return(result); }
/// <include file='doc\OleMenuCommandService.uex' path='docs/doc[@for="OleMenuCommandService.IOleCommandTarget.Exec"]/*' /> /// <internalonly/> /// <devdoc> /// Executes the given command. /// </devdoc> int IOleCommandTarget.Exec(ref Guid guidGroup, uint nCmdId, uint nCmdExcept, IntPtr pIn, IntPtr vOut) { const uint vsCmdOptQueryParameterList = 1; Guid commandGroup = Guid.Empty; try { commandGroup = guidGroup; } catch (NullReferenceException) { // Here we assume that the only reason for the exception is a null guidGroup. // We do not handle the default command group as definied in the spec for IOleCommandTarget, // so we have to return OLECMDERR_E_NOTSUPPORTED. return((int)Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED); } int hr = NativeMethods.S_OK; MenuCommand cmd = FindCommand(commandGroup, (int)nCmdId, ref hr); // If the command is not supported check if it can be handled by the parent command service if ((cmd == null || !cmd.Supported) && _parentTarget != null) { return(_parentTarget.Exec(ref commandGroup, nCmdId, nCmdExcept, pIn, vOut)); } else if (cmd != null) { // Try to see if the command is a IOleMenuCommand. IOleMenuCommand vsCmd = cmd as IOleMenuCommand; // Check the execution flags; uint loWord = LoWord(nCmdExcept); // If the command is not an OleMenuCommand, it can not handle the show help option. if (((uint)OLECMDEXECOPT.OLECMDEXECOPT_SHOWHELP == loWord) && (null == vsCmd)) { return(NativeMethods.S_OK); } object o = null; if (pIn != IntPtr.Zero) { o = Marshal.GetObjectForNativeVariant(pIn); } if (null == vsCmd) { cmd.Invoke(o); } else { switch (loWord) { // Default execution of the command: call the Invoke method case (uint)OLECMDEXECOPT.OLECMDEXECOPT_PROMPTUSER: case (uint)OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER: case (uint)OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT: { IMenuCommandInvokeEx invokeEx = vsCmd as IMenuCommandInvokeEx; if (null != invokeEx) { invokeEx.Invoke(o, vOut, (OLECMDEXECOPT)loWord); } else { vsCmd.Invoke(o, vOut); } } break; case (uint)OLECMDEXECOPT.OLECMDEXECOPT_SHOWHELP: // Check the hi word of the flags to see what kind of help // is needed. We handle only the request for the parameters list. if (vsCmdOptQueryParameterList == HiWord(nCmdExcept) && IntPtr.Zero != vOut) { // In this case vOut is a pointer to a VARIANT that will receive // the parameters description. if (!string.IsNullOrEmpty(vsCmd.ParametersDescription)) { Marshal.GetNativeVariantForObject(vsCmd.ParametersDescription, vOut); } } break; default: break; } } } return(hr); }