Working with Microsoft Visual Studio 2005
Whereas text-editing objects tell you what you can do within the editor windows, text editor events tell you when you can do it. The automation object model defines several events that allow you to monitor editor window activities and take action based on what you find out. Together with text editor objects, text editor events allow you to achieve hands-free control over every important aspect of the editor windows.
The BeforeKeyPress and AfterKeyPress Events
The first two text editor events—BeforeKeyPress and AfterKeyPress—are new to Visual Studio 2005. Both of these events allow you to examine and act on the user's keystrokes in real time, which makes possible a vast selection of dynamic editing features.
The BeforeKeyPress and AfterKeyPress events have three parameters in common: KeyPress, Selection, and InStatementCompletion. The KeyPress parameter give you a string representation of the character that fired the event. The keypress events fire in response to any alphanumeric characters that the user types; in addition, the events fire for the Backspace, Delete, Space, Tab, and Enter keys, and Ctrl+Enter key combination.
Warning | The keypress events don't fire for just keyboard input—they also fire once for each character added through the TextSelection.Text property. If you're tempted to use the TextSelection.Text property inside a keypress event handler, take care to guard against a runaway recursion. |
The Selection parameter gives you a reference to the active document's TextSelection object, which you can use to determine the location of the keypress and whether the keypress replaces existing text. Finally, the InStatementCompletion parameter warns you when the keypress coincides with an IntelliSense® statement completion.
In addition to the aforementioned event parameters, the BeforeKeyPress event has a CancelKeypress parameter. As you might guess, setting this parameter to True stops the keypress from ever reaching the editor window (and, consequently, prevents the AfterKeyPress event from firing).
To get a feel for how these keypress events work, Listing 10-1 shows how to implement keypress event handlers as macros.
Listing 10-1: Handling the BeforeKeyPress and AfterKeyPress events
<System.ContextStaticAttribute()> Public WithEvents _ TextDocumentKeyPressEvents As EnvDTE80.TextDocumentKeyPressEvents Private DTE2 As EnvDTE80.DTE2 = CType(DTE, EnvDTE80.DTE2) Private output As OutputWindowPane Public Sub EnableKeyPressEventMacros() ' Description: Creates an Output window pane and initializes ' the TextDocumentKeyPressEvents variable. Try output = _ DTE2.ToolWindows.OutputWindow.OutputWindowPanes.Item( _ "KeyPress Events") Catch ex As System.Exception output = _ DTE2.ToolWindows.OutputWindow.OutputWindowPanes.Add( _ "KeyPress Events") Finally output.Activate() End Try TextDocumentKeyPressEvents = _ DTE2.Events.GetObject("TextDocumentKeyPressEvents") End Sub Public Sub DisableKeyPressEventMacros() ' Description: Clears the Output window pane and resets the ' TextDocumentKeyPressEvents variable. TextDocumentKeyPressEvents = Nothing If Not IsNothing(output) Then output.Clear() output = Nothing End If End Sub Private Sub TextDocumentKeyPressEvents_BeforeKeyPress( _ ByVal Keypress As String, _ ByVal Selection As EnvDTE.TextSelection, _ ByVal InStatementCompletion As Boolean, _ ByRef CancelKeypress As Boolean) _ Handles TextDocumentKeyPressEvents.BeforeKeyPress ' Description: Handles the BeforeKeyPress event by displaying ' the event's parameters. output.OutputString("BeforeKeyPress: ") output.OutputString("KeyPress = " & Keypress & ", ") output.OutputString("Selection = '" & Selection.Text & "', ") output.OutputString("InStatementCompletion = " & _ InStatementCompletion.ToString) output.OutputString(vbCrLf) If KeyPress.ToUpper() = "W" Then CancelKeypress = True output.OutputString(vbCrLf) End If End Sub Private Sub TextDocumentKeyPressEvents_AfterKeyPress( _ ByVal Keypress As String, _ ByVal Selection As EnvDTE.TextSelection, _ ByVal InStatementCompletion As Boolean) _ Handles TextDocumentKeyPressEvents.AfterKeyPress ' Description: Handles the AfterKeyPress event by displaying ' the event's parameters. output.OutputString("AfterKeyPress: ") output.OutputString("KeyPress = " & Keypress & ", ") output.OutputString("Selection = '" & Selection.Text & "', ") output.OutputString("InStatementCompletion = " & _ InStatementCompletion.ToString) output.OutputString(vbCrLf & vbCrLf) End Sub
If you run the EnableKeyPressEventMacros in Listing 10-1 and start typing in an editor window, you'll see the values of the BeforeKeyPress and AfterKeyPress event parameters displayed in the Output window. To show how CancelKeypress might be used to make mischief, the BeforeKeyPress event handler effectively removes the W key without having to pry it loose from the keyboard.
The LineChanged Event
The automation object model defines a third event specific to editing: the LineChanged event. If your application needs only to process text line-by-line, sampling every keystroke might be overkill. In those instances, the LineChanged event offers a low-overhead alternative to the keystroke events.
The LineChanged event has three parameters to help you figure out why the event fired. The first two parameters, StartPoint and EndPoint, mark the beginning and end of the changes to the text buffer. You can use these TextPoint values to retrieve the changes, like so:
Dim text As String text = StartPoint.CreateEditPoint.GetText(EndPoint)
The third parameter, Hint, is a bit flag that holds values from the vsTextChanged enumeration (shown in Table 10-8). The flags set in Hint are evidence that you can piece together to recreate the actions leading up to the event. (In practice, the Hint parameter doesn't give you quite enough information to figure out exactly what led to the event—but then, if it did, it wouldn't be called a hint.)
Field | Description |
---|---|
vsTextChangedMultiLine | The changes affected multiple lines of text. |
vsTextChangedSave | The changes were saved to disk. |
vsTextChangedCaretMoved | The insertion point moved off the line containing the changes. |
vsTextChangedReplaceAll | The entire text buffer was replaced by an insertion. |
vsTextChangedNewLine | A new line was entered. |
vsTextChangedFindStarting | A find operation moved the insertion point off the line containing changes. |
The LineChanged event doesn't really fire when the line changes—that is, it doesn't fire for each new character added to or deleted from a line. Instead, the event fires when changes to a line are committed in some way, such as when the insertion point moves off the line, changes are saved to disk, or the document window loses focus. An undo context effectively disables this event until the undo context closes; afterward, the event fires if any of the changes made within the undo context would have caused it to fire under normal circumstances (the insertion point moves off a changed line, the entire text buffer is replaced by an insert, and so forth). The event handler receives StartPoint and EndPoint values that reflect all uncommitted changes from before and during the undo context.
Категории