private void RichTextSelectionChanged(object sender, EventArgs e) { ReadingRichTextBox richText = (ReadingRichTextBox)sender; bool newHasSelection = richText.SelectionLength != 0; bool newIsProtected = richText.SelectionPartiallyProtected; if (newHasSelection ^ myRichTextSelected || newIsProtected ^ myRichTextProtected) { myRichTextSelected = newHasSelection; myRichTextProtected = newIsProtected; IVsUIShell service = myCtorServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell; if (service != null) { service.UpdateCommandUI(1); } } }
/// <summary> /// Provides a first chance to handle any command that MSOLE.IOleCommandTarget.QueryStatus /// informed the shell to pass to this window. Implements IOleCommandTarget.Exec /// </summary> protected int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { int hr = 0; bool handled = true; // Only handle commands from the Office 97 Command Set (aka VSStandardCommandSet97). if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97) { ReadingsViewForm form = myForm; ReadingEditor editor = form.ReadingEditor; ReadingRichTextBox activeRichTextEditor = myActiveInlineEditor as ReadingRichTextBox; // Default to a not-supported status. switch ((VSConstants.VSStd97CmdID)nCmdID) { case VSConstants.VSStd97CmdID.Cut: if (activeRichTextEditor != null) { activeRichTextEditor.Cut(); hr = VSConstants.S_OK; } else { goto default; } break; case VSConstants.VSStd97CmdID.Copy: if (activeRichTextEditor != null) { activeRichTextEditor.Copy(); hr = VSConstants.S_OK; } else { goto default; } break; case VSConstants.VSStd97CmdID.Paste: if (activeRichTextEditor != null) { activeRichTextEditor.Paste(); hr = VSConstants.S_OK; } else { goto default; } break; case VSConstants.VSStd97CmdID.SelectAll: if (activeRichTextEditor != null) { activeRichTextEditor.SelectAll(); hr = VSConstants.S_OK; } else { goto default; } break; case VSConstants.VSStd97CmdID.Undo: if (activeRichTextEditor != null) { activeRichTextEditor.Undo(); hr = VSConstants.S_OK; } else { goto default; } break; case VSConstants.VSStd97CmdID.Delete: // If we aren't in label edit (in which case the commands should be passed down to the // VirtualTreeView control), handle the delete command and set the hresult to a handled status. if (!editor.EditingFactType.IsEmpty) { if (!editor.InLabelEdit) { if (editor.IsReadingPaneActive && editor.CurrentReading != null) { editor.OnMenuDeleteSelectedReading(); } } else { Control editControl = editor.LabelEditControl; if (editControl != null) { HandleRef editHandle = new HandleRef(editControl, editControl.Handle); // WM_KEYDOWN == 0x100 SendMessage(editHandle, 0x100, (int)Keys.Delete, 1); // WM_KEYUP == 0x101 SendMessage(editHandle, 0x101, (int)Keys.Delete, 0x40000001); } } // We enabled the command, so we say we handled it regardless of the further conditions hr = VSConstants.S_OK; } else { goto default; } break; case VSConstants.VSStd97CmdID.EditLabel: // If we aren't in label edit (in which case the commands should be passed down to the // VirtualTreeView control), handle the edit command and set the hresult to a handled status. if (!editor.EditingFactType.IsEmpty) { if (!editor.InLabelEdit) { if (editor.IsReadingPaneActive) { editor.EditSelection(); } } else { Control editControl = editor.LabelEditControl; if (editControl != null) { HandleRef editHandle = new HandleRef(editControl, editControl.Handle); // WM_KEYDOWN == 0x100 SendMessage(editHandle, 0x100, (int)Keys.F2, 1); // WM_KEYUP == 0x101 SendMessage(editHandle, 0x101, (int)Keys.F2, 0x40000001); } } } // We enabled the command, so we say we handled it regardless of the further conditions hr = VSConstants.S_OK; break; default: // If the command is from our command set, but not explicitly handled, inform the shell // that we didn't handle the command. handled = false; hr = (int)MSOLE.Constants.OLECMDERR_E_NOTSUPPORTED; break; } } // The command is from an unknown group. else { handled = false; hr = (int)MSOLE.Constants.OLECMDERR_E_UNKNOWNGROUP; } if (!handled) { Debug.Assert(ErrorHandler.Failed(hr)); ModelingDocData docData = CurrentDocument; Microsoft.VisualStudio.Modeling.Shell.UndoManager undoManager; MSOLE.IOleCommandTarget forwardTo; if ((docData != null && null != (undoManager = docData.UndoManager) && null != (forwardTo = undoManager.VSUndoManager as MSOLE.IOleCommandTarget)) || null != (forwardTo = GetService(typeof(MSOLE.IOleCommandTarget)) as MSOLE.IOleCommandTarget)) { // If the command wasn't handled already, give the undo manager a chance to handle the command. hr = forwardTo.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); } } return(hr); }
/// <summary> /// Provides a first chance to tell the shell that this window is capable of handling certain commands. Implements IOleCommandTarget.QueryStatus /// </summary> protected int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, MSOLE.OLECMD[] prgCmds, IntPtr pCmdText) { int hr = VSConstants.S_OK; bool handled = true; // Only handle commands from the Office 97 Command Set (aka VSStandardCommandSet97). if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97) { // There typically is only one command passed in to this array - in any case, we only care // about the first command. MSOLE.OLECMD cmd = prgCmds[0]; MSOLE.OLECMDF flags = 0; ReadingRichTextBox activeRichTextEditor = myActiveInlineEditor as ReadingRichTextBox; switch ((VSConstants.VSStd97CmdID)cmd.cmdID) { case VSConstants.VSStd97CmdID.Cut: if (activeRichTextEditor != null) { flags = (myRichTextSelected && !myRichTextProtected) ? MSOLE.OLECMDF.OLECMDF_SUPPORTED | MSOLE.OLECMDF.OLECMDF_ENABLED : MSOLE.OLECMDF.OLECMDF_SUPPORTED; } break; case VSConstants.VSStd97CmdID.Copy: if (activeRichTextEditor != null) { flags = myRichTextSelected ? MSOLE.OLECMDF.OLECMDF_SUPPORTED | MSOLE.OLECMDF.OLECMDF_ENABLED : MSOLE.OLECMDF.OLECMDF_SUPPORTED; } break; case VSConstants.VSStd97CmdID.Paste: if (activeRichTextEditor != null) { flags = (!myRichTextProtected && (Clipboard.ContainsText(TextDataFormat.Text) || Clipboard.ContainsText(TextDataFormat.UnicodeText))) ? MSOLE.OLECMDF.OLECMDF_SUPPORTED | MSOLE.OLECMDF.OLECMDF_ENABLED : MSOLE.OLECMDF.OLECMDF_SUPPORTED; } break; case VSConstants.VSStd97CmdID.SelectAll: if (activeRichTextEditor != null) { flags = MSOLE.OLECMDF.OLECMDF_SUPPORTED | MSOLE.OLECMDF.OLECMDF_ENABLED; } break; case VSConstants.VSStd97CmdID.Redo: case VSConstants.VSStd97CmdID.MultiLevelRedo: case VSConstants.VSStd97CmdID.MultiLevelUndo: if (activeRichTextEditor != null) { flags = MSOLE.OLECMDF.OLECMDF_SUPPORTED; } break; case VSConstants.VSStd97CmdID.Undo: if (activeRichTextEditor != null) { flags = activeRichTextEditor.CanUndo ? MSOLE.OLECMDF.OLECMDF_SUPPORTED | MSOLE.OLECMDF.OLECMDF_ENABLED : MSOLE.OLECMDF.OLECMDF_SUPPORTED; } break; case VSConstants.VSStd97CmdID.Delete: // Inform the shell that we should have a chance to handle the delete command. if (!this.myForm.ReadingEditor.EditingFactType.IsEmpty) { flags = MSOLE.OLECMDF.OLECMDF_SUPPORTED | MSOLE.OLECMDF.OLECMDF_ENABLED; } break; case VSConstants.VSStd97CmdID.EditLabel: // Support this command regardless of the current state of the inline editor. // If we do not do this, then an F2 keypress with an editor already open will // report the command as disabled and we would need to use IVsUIShell.UpdateCommandUI // whenever an editor closed to reenable the command. flags = MSOLE.OLECMDF.OLECMDF_SUPPORTED | MSOLE.OLECMDF.OLECMDF_ENABLED; break; } if (flags == 0) { // Inform the shell that we don't support the command. handled = false; hr = (int)MSOLE.Constants.OLECMDERR_E_NOTSUPPORTED; } else { cmd.cmdf = (uint)flags; prgCmds[0] = cmd; } } else { // Inform the shell that we don't recognize this command group. handled = false; hr = (int)MSOLE.Constants.OLECMDERR_E_UNKNOWNGROUP; } if (!handled) { Debug.Assert(ErrorHandler.Failed(hr)); ModelingDocData docData = CurrentDocument; Microsoft.VisualStudio.Modeling.Shell.UndoManager undoManager; MSOLE.IOleCommandTarget forwardTo; if ((docData != null && null != (undoManager = docData.UndoManager) && null != (forwardTo = undoManager.VSUndoManager as MSOLE.IOleCommandTarget)) || null != (forwardTo = GetService(typeof(MSOLE.IOleCommandTarget)) as MSOLE.IOleCommandTarget)) { // If the command wasn't handled already, forward it to the undo manager. hr = forwardTo.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText); } } return(hr); }