Making Good Use of DTE Events

 < Free Open Study > 



Trapping IDE Events

A number of top-level EnvDTE events can be trapped simply by declaring an event object variable using the WithEvents keyword and then providing and setting an event handler. However, by no means do they represent all of the events that can occur. They are simply the ones that are obvious and easy to trap. These top-level events are as follows:

  • EnvDTE.ProjectsEvents

  • EnvDTE.WindowEvents

  • EnvDTE.TextEditorEvents

  • EnvDTE.TaskListEvents

  • EnvDTE.SolutionEvents

  • EnvDTE.SelectionEvents

  • EnvDTE.OutputWindowEvents

  • EnvDTE.FindEvents

  • EnvDTE.DTEEvents

  • EnvDTE.DocumentEvents

  • EnvDTE.DebuggerEvents

  • EnvDTE.CommandEvents

  • EnvDTE.BuildEvents

  • EnvDTE.ProjectItemsEvents

Two additional events that pertain to the VSLangProj namespace are as follows:

  • VSLangProj.ReferencesEvents

  • VSLangProj.ImportsEvents

Associating an Event with a Handler

Before you can trap events, you have to associate the event with a handler. The WithEvents statement and the Handles clause are used to declare event handlers. The WithEvents statement is used to declare an object that can raise events. The event can be handled by a subroutine with a Handles clause that names the event. The Handles clause is a static method of linking the event object to the event handler at compile time.

The AddHandler and RemoveHandler are used to dynamically link and unlink the events with one or more event handlers at runtime. These clauses do not require the use of the WithEvents clause to declare an event object.

When you are working in a regular Windows application, Visual Studio .NET will automatically create an empty event handler and associate it with an event. An example of this would be when you double-click a Label control in design mode. Visual Basic .NET will create an empty event handler. Additionally, it will create a WithEvents object variable for the Label. Examples of these two code snippets are as follows:

Friend WithEvents lblDate As System.Windows.Forms.Label

Private Sub lblDate_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles lblDate.Click
End Sub
 

In case you are programming in Visual C#, the compiler will create an empty event handler and associate it with an event. However, it does not use the WithEvents keyword to declare the event. Rather, it uses the following code. The empty event handler is listed below the event object.

this.lblDate.Click += new System.EventHandler(this.lblDate_Click);
private void lblDate_Click(object sender, System.EventArgs e)
{

}
 

Four separate snippets of code are involved in the trapping of IDE events in Visual Basic. First, an event object variable must be declared as shown in the following line of code:

Public WithEvents eventWindows As EnvDTE.WindowEvents
 

Next, an event handler must be coded. You can do anything you want to in the event handler, but I am simply writing a record of the occurrence in the Output window. The OWP object is assumed to have been created by another process that will be shown later in this chapter.

Note 

The Output window of the client instance of the IDE is used for displaying information passed to the respective event handlers throughout this chapter. In a production add-in, you would not want to do this. Instead, you could write to the Debug window of the add-in for use while in debug mode.

Private Sub eventWindows_WindowActivated(ByVal GotFocus As 
   EnvDTE.Window, _
   ByVal LostFocus As EnvDTE.Window) 
   Handles eventWindows.WindowActivated
   OWP.OutputString("WindowEvents.WindowActivated" & vbCrLf)
   OWP.OutputString(vbTab & "Window getting focus: " & _
      GotFocus.Caption & vbCrLf)
   OWP.OutputString(vbTab & _
      "Window losing focus: " & _
      LostFocus.Caption & vbCrLf)
End Sub
 

Now that you have an event handler, you need to link the event object variable, eventWindows, to the event handler. To do that, use the following line of code:

eventWindows = CType(events.WindowEvents(Nothing), 
   EnvDTE.WindowEvents)
 

When the add-in is terminating, destroy the event object by placing the following line of code in the OnDisconnection method:

eventWindows = Nothing
 

In the following topics I use an add-in to demonstrate the handling of events. Ialso describe each of the previously listed events.

Note 

It is not my intention to go into great detail with respect to each type of event described in the following sections. The intent here is to present a high-level overview of the various events occurring in the IDE. Please refer to MSDN for further detail.

Event Handling Add-in

I am going to create a new add-in and use code from it as I describe the various events raised by the IDE. Once again, I will use the Add-in Wizard to create the framework for the add-in. The add-in will be named Chap11EventHandling and will be based on Visual Basic code. It will be just like all of the Visual Basic add-ins that I created previously in the book, except that it will not have a user interface (UI). If you are creating an add-in instead of simply running the code, don't check the box to have the wizard create a user interface.

As I describe the events raised by the various event objects, I will describe the object, list its events, and show you the respective event handlers from the add-in. For that reason, I will not show the Connect class assembled together. However, if you were to take all of the code from each event topic and place it into the Connect class, you would have all of the code for the class.

You will note that each of the event handlers is calling the WriteOutputWindow method of the ow object. This is a class that is used to insert text into the Output window of the client instance of the IDE. The code for this class is shown in Listing 11-1.

Listing 11-1: ProjectsEvents Event Handlers

start example

Private Sub prjEvents_ItemAdded( 
   ByVal Project As EnvDTE.Project) 
   Handles prjEvents.ItemAdded
   ow.WriteOutputWindow("ProjectsEvents::ItemAdded", 
      vbTab & "Project: " & Project.Name)
End Sub
Private Sub prjEvents_ItemRemoved(ByVal Project As 
   EnvDTE.Project) _
   Handles prjEvents.ItemRemoved
   ow.WriteOutputWindow("ProjectsEvents::ItemRemoved",
      vbTab & "Project: " & Project.Name)
End Sub
Private Sub prjEvents_ItemRenamed( 
   ByVal Project As EnvDTE.Project, 
   ByVal OldName As String) 
   Handles prjEvents.ItemRenamed
   ow.WriteOutputWindow("ProjectsEvents::ItemRenamed", 
      vbTab & "OldProjectName: " & OldName, 
      vbTab & "NewProjectName: " & Project.Name)
End Sub
 
end example

ProjectsEvents

The ProjectsEvents object raises events when a project is added, removed, or renamed in a solution. It also can raise the same events when an item is added, removed, or renamed in a project. The ProjectsEvents object can raise three possible events, which are described in Table 11-1. The code for the events is shown in Listing 11-1.

Table 11-1: ProjectsEvents

EVENT

DESCRIPTION

ItemAdded

Raised when a project is added to a solution or when an item is added to a project

ItemRemoved

Raised when a project is removed from a solution or when an item is removed from a project

ItemRenamed

Raised when a project is renamed in a solution or an item in a project is renamed

WindowEvents

The WindowEvents object provides events for changes made to Windows in the environment. These events fire when the user clicks a different window other than the currently active window. It also raises events when a window is closed or opened. It has four events, which are described in Table 11-2.

Table 11-2: WindowEvents

EVENT

DESCRIPTION

WindowActivated

Raised when a window receives focus

WindowClosing

Raised just before a window is closed

WindowCreated

Raised when a new window is created

WindowMoved

Raised when a window is removed or resized

The code for handing the WindowEvents object events is shown in Listing 11-2.

Listing 11-2: WindowEvents Event Handlers

start example
Private Sub eventWindows_WindowActivated(ByVal GotFocus As EnvDTE.Window, _
   ByVal LostFocus As EnvDTE.Window) Handles 
      eventWindows.WindowActivated
   ow.WriteOutputWindow("WindowEvents::WindowActivated", 
      vbTab & "Window receiving focus: " & 
      GotFocus.Caption, 
      vbTab & "Window that lost focus: " & 
      LostFocus.Caption)
End Sub
Private Sub winEvents_WindowClosing( 
   ByVal Window As EnvDTE.Window) 
   Handles eventWindows.WindowClosing
   ow.WriteOutputWindow("WindowEvents::WindowClosing", 
      vbTab & "Window: " & Window.Caption)
End Sub
Private Sub winEvents_WindowCreated( 
   ByVal Window As EnvDTE.Window) 
   Handles eventWindows.WindowCreated
   ow.WriteOutputWindow("WindowEvents::WindowCreated", 
      vbTab & "Window: " & Window.Caption)
End Sub
Private Sub winEvents_WindowMoved( 
   ByVal Window As EnvDTE.Window, 
   ByVal Top As Integer, 
   ByVal Left As Integer, 
   ByVal [Width] As Integer, 
   ByVal Height As Integer) Handles eventWindows.WindowMoved
   ow.WriteOutputWindow("WindowEvents::WindowMoved", 
      vbTab & "Window: " & Window.Caption, 
      vbTab & "Location: (" & Top.ToString() & 
      " , " & Left.ToString() & 
      " , " & Width.ToString() & 
      " , " & Height.ToString() & ")")
End Sub
 
end example

TextEditorEvents

The TextEditorEvents object provides events for changes made in the Text/Code Editor. Something as simple as pressing the Enter key in the Editor will cause the object to raise an event. The TextEditorEvents object has one event: the LineChanged event. The LineChanged event is raised when changes are made to a line in the Text/Code Editor that move the insertion point. The event provides both a TextPoint and an EndPoint object. Chapter 5 discussed these objects. Listing 11-3 shows the code for handling the TextEditorEvents object.

Listing 11-3: TextEditorEvents Object Event Handler

start example
Private Sub textEditorEvents_LineChanged( 
   ByVal StartPoint As 
   EnvDTE.TextPoint, 
   ByVal EndPoint As EnvDTE.TextPoint, 
   ByVal Hint As Integer) _
   Handles textEditorEvents.LineChanged
   Dim textChangedHint As EnvDTE.vsTextChanged = CType(  
      Hint, 
      EnvDTE.vsTextChanged)
   ow.WriteOutputWindow("TextEditorEvents::LineChanged", 
      vbTab & "Document: " & 
      StartPoint.Parent.Parent.Name, 
      vbTab & "Change hint: " & 
      textChangedHint.ToString())
End Sub
 
end example

TaskListEvents

The TaskListEvents object provides events for changes made to the Task List. It raises four events, which are described in Table 11-3. The code for handling the events of the TaskListEvents object is shown in Listing 11-4.

Table 11-3: TaskListEvents

EVENT

DESCRIPTION

TaskAdded

Raised when a new item is added to the Task List

TaskModified

Raised when a Task List item is modified

TaskNavigated

Raised immediately before you navigate to the source of an item in the Task List

TaskRemoved

Raised when a Task List item is removed from the Task List

Listing 11-4: TaskListEvents Object Event Handler

start example

Private Sub taskListEvents_TaskAdded(ByVal TaskItem As EnvDTE.TaskItem) _
   Handles taskListEvents.TaskAdded
   ow.WriteOutputWindow("TaskListEvents::TaskAdded", 
       vbTab & "Task description: " 
       & TaskItem.Description)
End Sub
Private Sub taskListEvents_TaskModified(  
   ByVal TaskItem As EnvDTE.TaskItem, 
   ByVal ColumnModified As EnvDTE.vsTaskListColumn) 
   Handles taskListEvents.TaskModified
   ow.WriteOutputWindow("TaskListEvents::TaskModified", 
      vbTab &
      "Task description: " & TaskItem.Description)
End Sub
Private Sub taskListEvents_TaskNavigated( 
   ByVal TaskItem As EnvDTE.TaskItem, 
   ByRef NavigateHandled As Boolean) 
   Handles taskListEvents.TaskNavigated
   ow.WriteOutputWindow("TaskListEvents::TaskNavigated", 
      vbTab &"Task description: " & 
      TaskItem.Description)
End Sub
Private Sub taskListEvents_TaskRemoved( 
   ByVal TaskItem As EnvDTE.TaskItem) 
   Handles taskListEvents.TaskRemoved
   ow.WriteOutputWindow("TaskListEvents::TaskRemoved", 
      vbTab & "Task description: " & 
      TaskItem.Description)
End Sub
 
end example

SolutionEvents

The SolutionEvents object raises events when changes are made to the solution. The object can raise eight events, which are described in Table 11-4. Listing 11-5 shows the code to handle the events raised by the SolutionEvents object.

Table 11-4: SolutionEvents

EVENT

DESCRIPTION

AfterClosing

Raised after a solution is closed

BeforeClosing

Raised before a solution is closed

Opened

Raised after a solution is opened

ProjectAdded

Raised after a project is added to a solution

ProjectRemoved

Raised after a project is removed from a solution

ProjectRenamed

Raised after a project is renamed

QueryCloseSolution

Raised before the BeforeClosing event

Renamed

Raised after the solution is renamed

Listing 11-5: SolutionEvents Object Event Handler

start example

Private Sub solutionEvents_AfterClosing() 
   Handles solutionEvents.AfterClosing
   ow.WriteOutputWindow("SolutionEvents::AfterClosing")
End Sub
Private Sub solutionEvents_BeforeClosing() 
   Handles solutionEvents.BeforeClosing
   ow.WriteOutputWindow("SolutionEvents::BeforeClosing")
End Sub
Private Sub solutionEvents_Opened() 
   Handles solutionEvents.Opened
   ow.WriteOutputWindow("SolutionEvents::Opened")
End Sub
Private Sub solutionEvents_ProjectAdded( 
   ByVal Project As EnvDTE.Project) 
   Handles solutionEvents.ProjectAdded
   ow.WriteOutputWindow("SolutionEvents::ProjectAdded", 
       vbTab & "Project: "
       & Project.UniqueName)
End Sub
Private Sub solutionEvents_ProjectRemoved( 
   ByVal Project As EnvDTE.Project) 
   Handles solutionEvents.ProjectRemoved
   ow.WriteOutputWindow("SolutionEvents::ProjectRemoved", 
       vbTab & "Project: " 
       & Project.UniqueName)
End Sub
Private Sub solutionEvents_ProjectRenamed( 
   ByVal Project As EnvDTE.Project, _
   ByVal OldName As String) 
   Handles solutionEvents.ProjectRenamed
   ow.WriteOutputWindow("SolutionEvents::ProjectRenamed", 
       vbTab & "Project: " 
       & Project.UniqueName)
End Sub
Private Sub solutionEvents_QueryCloseSolution( 
   ByRef fCancel As Boolean) 
   Handles solutionEvents.QueryCloseSolution
   ow.WriteOutputWindow("SolutionEvents::QueryCloseSolution")
End Sub
Private Sub solutionEvents_Renamed( 
   ByVal OldName As String) 
   Handles solutionEvents.Renamed
   ow.WriteOutputWindow("SolutionEvents::Renamed")
End Sub
Private Sub selectionEvents_OnChange() 
   Handles selectionEvents.OnChange
   OWP.OutputString("SelectionEvents::OnChange" & vbCrLf)
   Dim count As Integer = oVB.SelectedItems.Count
   Dim i As Integer
   For i = 1 To oVB.SelectedItems.Count
      ow.WriteOutputWindow("Item name: " & _
         oVB.SelectedItems.Item(i).Name)
   Next
End Sub
 
end example

SelectionEvents

The SelectionEvents object provides events for changes to a selection. Whenever something is selected in the development environment, a model of what the user has selected is created. A change in this model causes the OnChanged event to occur. The following code snippet is the event handler for the OnChanged event:

Private Sub selectionEvents_OnChange() 
    Handles selectionEvents.OnChange
    ow.WriteOutputWindow("SelectionEvents::OnChange")
    Dim count As Integer = oVB.SelectedItems.Count
    Dim i As Integer
    For i = 1 To oVB.SelectedItems.Count
    ow.WriteOutputWindow("Item name: " & 
       oVB.SelectedItems.Item(i).Name)
   Next
End Sub
 

OutputWindowEvents

Numerous IDE tools use the Output window for display of output text. Initially, the IDE has two basic Output window panes: Debug and Build. However, it is possible for each tool in the IDE to use a different Output window pane. For example, build errors could go to the Build Errors pane and debug messages could go to the Debug pane. You can select panes with the drop-down box at the top of the Output window. The Output window raises three events, as described in Table 11-5. Listing 11-6 shows the code for the OutputWindowEvents object events.

Table 11-5: OutputWindowEvents Events

EVENT

DESCRIPTION

PaneAdded

Raised when a new pane is added to the OutputWindow object

PaneClearing

Raised just before an Output window pane is cleared

PaneUpdate

Raised when text is added to the Output window

Caution 

You must be careful if you are attempting to write to the Output window from the PaneUpdated event of the OutputWindow.You can cause a recursion loop if you do not protect against it.

Tip 

When a new pane is added to the OutputWindow object, it will remain there until the IDE is closed. However, the Debug and Build panes are closed when the solution is closed.

Listing 11-6: OutputWindowEvents Event Handlers

start example
Private Sub outputWindowEvents_PaneAdded( 
   ByVal pane As EnvDTE.OutputWindowPane) 
   Handles outputWindowEvents.PaneAdded
   ow.WriteOutputWindow("OutputWindowEvents::PaneAdded", 
       vbTab & "Pane: " & pane.Name)
End Sub
Private Sub outputWindowEvents_PaneClearing( 
   ByVal pane As EnvDTE.OutputWindowPane) 
   Handles outputWindowEvents.PaneClearing
   ow.WriteOutputWindow("OutputWindowEvents::PaneClearing", 
       vbTab & "Pane: " & pane.Name)
End Sub
Private Sub outputWindowEvents_PaneUpdated( 
   ByVal pPane As EnvDTE.OutputWindowPane) 

   Handles outputWindowEvents.PaneUpdated
   Static Busy As Boolean
   'If Busy Then Exit Sub
   'Busy = True
   'Don't want to do this one, causes too much output
   'ow.WriteOutputWindow("OutputWindowEvents::PaneUpdated", 
   '    vbTab & "Pane: " & pPane.Name)
   'Busy = False
End Sub
 
end example

FindEvents

The FindEvents object provides events for Find-in-Files operations. The FindEvents object raises only one event, the FindDone event. The FindDone event is raised after a Find-in-Files with a results list operation completes. The following code snippet handles the code for the FindEvents object:

Private Sub findEvents_FindDone( 
   ByVal Result As EnvDTE.vsFindResult, 
   ByVal Cancelled As Boolean) Handles findEvents.FindDone
   ow.WriteOutputWindow("FindEvents::FindDone")
End Sub
Private Sub dteEvents_ModeChanged( 
   ByVal LastMode As EnvDTE.vsIDEMode) 
   Handles dteEvents.ModeChanged
   ow.WriteOutputWindow("DTEEvents::ModeChanged", 
       "LastMode: " & LastMode.ToString)
End Sub
 

DTEEvents

The DTEEvents object raises events relating to the state of the environment. The DTEEvents object raises four events, which are described in Table 11-6. Listing 11-7 shows the code for handling the events of the DTEEvents object.

Table 11-6: DTEEvents Object Event Handlers

EVENT

DESCRIPTION

ModeChanged

Raised when the mode of the development environment (build, run, or debug) is changed. The LastMode is passed to the ModeChanged event.

OnBeginShutdown

Raised when the development environment is closing.

OnMacrosRuntimeReset

Raised when the macro runtime execution engine resets. When this happens, all global variable data and all event connections are lost.

OnStartupComplete

Raised when the development environment has completed initialization.

Listing 11-7: DTEEvents Object Event Handlers

start example
Private Sub dteEvents_OnBeginShutdown() 
   Handles dteEvents.OnBeginShutdown
   ow.WriteOutputWindow("DTEEvents::OnBeginShutdown")
End Sub
Private Sub dteEvents_OnMacrosRuntimeReset() 
   Handles dteEvents.OnMacrosRuntimeReset
   ow.WriteOutputWindow("DTEEvents::OnMacrosRuntimeReset")
End Sub
Private Sub dteEvents_OnStartupComplete() 
   Handles dteEvents.OnStartupComplete
   ow.WriteOutputWindow("DTEEvents::OnStartupComplete")
End Sub
 
end example

DocumentEvents

The DocumentEvents object raises four events relating to activity in the Documents object. These events are described in Table 11-7. Listing 11-8 shows the code for handling the events of the DocumentEvents object.

Table 11-7: DocumentEvents Object Events

EVENT

DESCRIPTION

DocumentClosing

Raised just before a document is closed. Passes the document that is being closed.

DocumentOpening

Raised just before a document is opened. Passes the document that is being opened along with a parameter denoting whether the document is read-only.

DocumentOpened

Raised after a document is opened. Passed the document that was opened.

DocumentSaved

Raised after a document is saved. Passed the document that was saved.

Listing 11-8: DocumentEvents Object Event Handlers

start example
Private Sub documentEvents_DocumentClosing( 
   ByVal Document As EnvDTE.Document) 
   Handles documentEvents.DocumentClosing
   ow.WriteOutputWindow("DocumentEvents::DocumentClosing", 
       vbTab & "Document: " & Document.Name)
End Sub
Private Sub documentEvents_DocumentOpened( 
   ByVal Document As EnvDTE.Document) 
   Handles documentEvents.DocumentOpened
   ow.WriteOutputWindow("DocumentEvents::DocumentOpened", 
       vbTab & "Document: " & Document.Name)
End Sub
Private Sub documentEvents_DocumentOpening( 
   ByVal DocumentPath As String, 
   ByVal [ReadOnly] As Boolean) 
   Handles documentEvents.DocumentOpening
   ow.WriteOutputWindow("DocumentEvents::DocumentOpening", 
       vbTab & "Path: " & DocumentPath)
End Sub
Private Sub documentEvents_DocumentSaved( 
   ByVal Document As EnvDTE.Document) 
   Handles documentEvents.DocumentSaved
   ow.WriteOutputWindow("DocumentEvents::DocumentSaved", 
       vbTab & "Document: " & Document.Name)
End Sub
 
end example

DebuggerEvents

The DebuggerEvents object provides events supported by the debugger. Table 11-8 describes the six events that are raised by the DebuggerEvents object. Listing 11-9 shows the code for handling the events for the DebuggerEvents object.

Table 11-8: DebuggerEvents Object Events

EVENT

DESCRIPTION

OnContextChanged

Raised whenever the current process, program, thread, or stack is changed through either the user interface or the automation model.

OnEnterBreakMode

Raised when the debugger enters break mode regardless of how the break mode was established.

OnEnterDesignMode

Raised when run mode is terminated and design mode is reentered.

OnEnterRunMode

Raised when run mode is entered. This event may not fire when stepping.

OnExceptionNotHandled

Raised before OnEnterBreakMode. Setting the ExceptionAction parameter allows the handler to affect the development environment's user interface when the handler exits.

OnExceptionThrown

Thrown before OnEnterBreakMode. Setting the ExecuteAction parameter allows the handler to affect the development environment's user interface when the handler exits.

Listing 11-9: DebuggerEvents Object Event Handlers

start example
Private Sub debuggerEvents_OnContextChanged( 
   ByVal NewProcess As EnvDTE.Process, 
   ByVal NewProgram As EnvDTE.Program, 
   ByVal NewThread As EnvDTE.Thread, 
   ByVal NewStackFrame As EnvDTE.StackFrame) 
   Handles debuggerEvents.OnContextChanged
   ow.WriteOutputWindow("DebuggerEvents::OnContextChanged")
End Sub
Private Sub debuggerEvents_OnEnterBreakMode( 
   ByVal Reason As EnvDTE.dbgEventReason, 
   ByRef ExecutionAction As 
   EnvDTE.dbgExecutionAction) 
   Handles debuggerEvents.OnEnterBreakMode
   ExecutionAction = 
      EnvDTE.dbgExecutionAction.dbgExecutionActionDefault
   ow.WriteOutputWindow("DebuggerEvents::OnEnterBreakMode")
End Sub
Private Sub debuggerEvents_OnEnterDesignMode( 
   ByVal Reason As 
   EnvDTE.dbgEventReason) 
   Handles debuggerEvents.OnEnterDesignMode
   ow.WriteOutputWindow("DebuggerEvents::OnEnterDesignMode")
End Sub
Private Sub debuggerEvents_OnEnterRunMode( 
   ByVal Reason As _ EnvDTE.dbgEventReason)
   Handles debuggerEvents.OnEnterRunMode 
   ow.WriteOutputWindow("DebuggerEvents::OnEnterRunMode")
End Sub
Private Sub debuggerEvents_OnExceptionNotHandled 
   (ByVal ExceptionType As String, _
   ByVal [Name] As String, ByVal Code As Integer, 
   ByVal Description As String, 
   ByRef ExceptionAction As EnvDTE.dbgExceptionAction) 
   Handles debuggerEvents.OnExceptionNotHandled
   ExceptionAction = 
      EnvDTE.dbgExceptionAction.dbgExceptionActionDefault
   ow.WriteOutputWindow("DebuggerEvents::OnExceptionNotHandled")
End Sub
Private Sub debuggerEvents_OnExceptionThrown( 
   ByVal ExceptionType As String, 
   ByVal [Name] As String, ByVal Code As Integer, 
   ByVal Description As String, _
   ByRef ExceptionAction As EnvDTE.dbgExceptionAction) 
   Handles debuggerEvents.OnExceptionThrown
   ExceptionAction = 
      EnvDTE.dbgExceptionAction.dbgExceptionActionDefault
   ow.WriteOutputWindow("DebuggerEvents::OnExceptionThrown")
End Sub
 
end example

CommandEvents

The CommandEvents object provides events for the Command object to automation clients. This object raises two events, BeforeExecute and AfterExecute, which are raised just before and after the command is executed, respectively. Listing 11-10 shows the code for handling the CommandEvents object.

Listing 11-10: CommandEvents Object Event Handlers

start example
Private Sub commandEvents_AfterExecute( 
   ByVal Guid As String, 
   ByVal ID As Integer, ByVal CustomIn As Object, 
   ByVal CustomOut As Object) 
   Handles commandEvents.AfterExecute
   Dim commandName As String
   Try
      commandName = oVB.Commands.Item(Guid, ID).Name
   Catch excep As System.Exception
   End Try
   ow.WriteOutputWindow("CommandEvents::AfterExecute")
   If (commandName <> "") Then
      ow.WriteOutputWindow(vbTab & "Command name: " 
          & commandName)
   End If
   ow.WriteOutputWindow(vbTab & "Command GUID/ID: " & 
      Guid & ", " & ID.ToString())
End Sub
Private Sub commandEvents_BeforeExecute( 
   ByVal Guid As String, 
   ByVal ID As Integer, ByVal CustomIn As Object, 
   ByVal CustomOut As Object, 
   ByRef CancelDefault As Boolean) 
   Handles commandEvents.BeforeExecute
   Dim commandName As String
   Try
      commandName = oVB.Commands.Item(Guid, ID).Name
   Catch excep As System.Exception
   End Try
   ow.WriteOutputWindow("CommandEvents::BeforeExecute")
   OWP.OutputString("CommandEvents::BeforeExecute" & 
      vbCrLf)
   If (commandName <> "") Then
      ow.WriteOutputWindow(vbTab & 
         "Command name: " & commandName)
   End If
   ow.WriteOutputWindow(vbTab & "Command GUID/ID: " & 
      Guid & ", " & ID.ToString())
End Sub
 
end example

BuildEvents

The BuildEvents object raises events for solution builds. Table 11-9 describes the four events raised by the BuildEvents object. Listing 11-11 shows the code for handling the events of the BuildEvents object. The BuildEvents object was described and exploited in Chapter 9.

Table 11-9: BuildEvents Object Events

EVENT

DESCRIPTION

OnBuildBegin

Raised just before a project, solution, or batch build begins. Passed variables representing the scope and type of build taking place.

OnBuildDone

Raised after a build is complete. Passed variables representing the scope and type of build that has completed.

OnBuildProjConfigBegin

Raised when a project configuration build begins.

OnBuildProjConfigDone

Raised when a project configuration build is completed.

Listing 11-11: BuildEvents Object Event Handlers

start example
Private Sub buildEvents_OnBuildBegin( 
   ByVal Scope As EnvDTE.vsBuildScope, 
   ByVal Action As EnvDTE.vsBuildAction) 
   Handles buildEvents.OnBuildBegin
   ow.WriteOutputWindow("BuildEvents::OnBuildBegin")
End Sub
Private Sub buildEvents_OnBuildDone( 
   ByVal Scope As EnvDTE.vsBuildScope, 
   ByVal Action As EnvDTE.vsBuildAction) 
   Handles buildEvents.OnBuildDone
   ow.WriteOutputWindow("BuildEvents::OnBuildDone")
End Sub
Private Sub buildEvents_OnBuildProjConfigBegin( 
   ByVal Project As String, 
   ByVal ProjectConfig As String, 
   ByVal Platform As String, 
   ByVal SolutionConfig As String) 
   Handles buildEvents.OnBuildProjConfigBegin
   ow.WriteOutputWindow( 
      "BuildEvents::OnBuildProjConfigBegin", 
      vbTab & "Project: " & Project, 
      vbTab & "Project Configuration: " & ProjectConfig, 
      vbTab & "Platform: " & Platform, 
      vbTab & "Solution Configuration: " & SolutionConfig)
End Sub
Private Sub buildEvents_OnBuildProjConfigDone( 
   ByVal Project As String, 
   ByVal ProjectConfig As String, 
   ByVal Platform As String, 
   ByVal SolutionConfig As String, 
   ByVal Success As Boolean) 
   Handles buildEvents.OnBuildProjConfigDone
   ow.WriteOutputWindow( 
      "BuildEvents::OnBuildProjConfigDone", 
      vbTab & "Project: " & Project, 
      vbTab & "Project Configuration: " & ProjectConfig, 
      vbTab & "Platform: " & Platform, 
      vbTab & "Build success: " & Success.ToString())
End Sub
 
end example

ProjectItemsEvents

The ProjectItemsEvents object provides the base interface from which the various project types derive their specific project item event interfaces. The ProjectItemsEvents object raises three events. Table 11-10 describes the events for the ProjectItemsEvents object. Listing 11-12 shows the code for handling the events of the ProjectItemsEvents object.

Table 11-10: ProjectItemsEvents Object Events

EVENT

DESCRIPTION

ItemAdded

Raised immediately after adding a project to a solution or an item to a project

ItemRemoved

Raised immediately after removing a project from a solution or a project item from a project

ItemRenamed

Raised immediately after renaming a project in a solution or a project item in a project

Listing 11-12: ProjectItemsEvents Object Event Handlers

start example
Private Sub prjEvents_ItemAdded( 
   ByVal Project As EnvDTE.Project) 
   Handles prjEvents.ItemAdded
   ow.WriteOutputWindow("ProjectsEvents::ItemAdded", 
       vbTab & "Project: " & Project.Name)
End Sub
Private Sub prjEvents_ItemRemoved( 
   ByVal Project As EnvDTE.Project) 
   Handles prjEvents.ItemRemoved
   ow.WriteOutputWindow("ProjectsEvents::ItemRemoved", 
       vbTab & "Project: " & Project.Name)
End Sub
Private Sub prjEvents_ItemRenamed( 
   ByVal Project As EnvDTE.Project, _
   ByVal OldName As String) 
   Handles prjEvents.ItemRenamed
   ow.WriteOutputWindow("ProjectsEvents::ItemRenamed", 
       vbTab & "OldProjectName: " & OldName, 
       vbTab & "NewProjectName: " 
       & Project.Name)
End Sub
 
end example

Connect Class

The remainder of the Connect class is shown in Listing 11-13. You have already seen the event handlers in Listings 11-1 through 11-11. The event objects are declared and associated with the event handlers in the OnConnection method of the class. The event objects are set to Nothing in the OnDisconnection method of the class as the add-in is being shut down. The code for connecting and destroying the events is highlighted in boldface font.

Listing 11-13: Connect Class Declaration Section

start example
Imports Microsoft.Office.Core
Imports Extensibility
Imports System.Runtime.InteropServices
Imports EnvDTE

<GuidAttribute("65DCDC37-6A98-4862-A91C-81F8B5B83073"), 
   ProgIdAttribute("Chap11EventHandling.Connect")> _
Public Class Connect
   Implements Extensibility.IDTExtensibility2

   Dim ow As WinOutput

   Dim oVB As EnvDTE.DTE
   Dim addInInstance As EnvDTE.AddIn
   Public WithEvents refEvents As VSLangProj.ReferencesEvents
   Public WithEvents importEvents As VSLangProj.ImportsEvents
   Public WithEvents prjEvents As EnvDTE.ProjectsEvents
   Public WithEvents eventWindows As EnvDTE.WindowEvents
   Public WithEvents textEditorEvents As EnvDTE.TextEditorEvents
   Public WithEvents taskListEvents As EnvDTE.TaskListEvents
   Public WithEvents solutionEvents As EnvDTE.SolutionEvents
   Public WithEvents selectionEvents As EnvDTE.SelectionEvents
   Public WithEvents outputWindowEvents As 
      EnvDTE.OutputWindowEvents
   Public WithEvents findEvents As EnvDTE.FindEvents
   Public WithEvents dteEvents As EnvDTE.DTEEvents
   Public WithEvents documentEvents As EnvDTE.DocumentEvents
   Public WithEvents debuggerEvents As EnvDTE.DebuggerEvents
   Public WithEvents commandEvents As EnvDTE.CommandEvents
   Public WithEvents buildEvents As EnvDTE.BuildEvents
   Public WithEvents solutionItemsEvents As EnvDTE.ProjectItemsEvents

   Public Sub OnBeginShutdown(ByRef custom As System.Array) 
      Implements Extensibility.IDTExtensibility2.OnBeginShutdown
   End Sub

   Public Sub OnAddInsUpdate(ByRef custom As System.Array) 
      Implements Extensibility.IDTExtensibility2.OnAddInsUpdate
   End Sub
   Public Sub OnStartupComplete(ByRef custom As System.Array) 
      Implements Extensibility.IDTExtensibility2.OnStartupComplete
   End Sub

   Public Sub OnDisconnection(ByVal RemoveMode As 
      Extensibility.ext_DisconnectMode, 
      ByRef custom As System.Array) 
      Implements 
      Extensibility.IDTExtensibility2.OnDisconnection
      eventWindows = Nothing
      textEditorEvents = Nothing
      taskListEvents = Nothing
      solutionEvents = Nothing
      selectionEvents = Nothing
      outputWindowEvents = Nothing
      findEvents = Nothing
      dteEvents = Nothing
      documentEvents = Nothing
      debuggerEvents = Nothing
      commandEvents = Nothing
      buildEvents = Nothing
      solutionItemsEvents = Nothing
      ow = Nothing
   End Sub

   Public Sub OnConnection(ByVal application As Object, 
      ByVal connectMode As 
      Extensibility.ext_ConnectMode, 
      ByVal addInInst As Object, 
      ByRef custom As System.Array) 
      Implements 
      Extensibility.IDTExtensibility2.OnConnection

      oVB = CType(application, EnvDTE.DTE)
      addInInstance = CType(addInInst, EnvDTE.AddIn)
      ' set up my output window object
      ow = New WinOutput(oVB)

      Dim events As EnvDTE.Events
      events = oVB.Events
      eventWindows = CType(events.WindowEvents(Nothing), EnvDTE.WindowEvents)
      textEditorEvents = 
      CType(events.TextEditorEvents(Nothing), 
         EnvDTE.TextEditorEvents)
      taskListEvents = CType(events.TaskListEvents(""), 
      EnvDTE.TaskListEvents)
      solutionEvents = CType(events.SolutionEvents, 
         EnvDTE.SolutionEvents)
      selectionEvents = CType(events.SelectionEvents, 
         EnvDTE.SelectionEvents)
      outputWindowEvents = 
         CType(events.OutputWindowEvents(""), 
         EnvDTE.OutputWindowEvents)
      findEvents = CType(events.FindEvents, EnvDTE.FindEvents)
      dteEvents = CType(events.DTEEvents, EnvDTE.DTEEvents)
      documentEvents = CType(events.DocumentEvents(Nothing), _
         EnvDTE.DocumentEvents)
      debuggerEvents = CType(events.DebuggerEvents, 
         EnvDTE.DebuggerEvents)
      commandEvents = 
         CType(events.CommandEvents( 
         "{00000000-0000-0000-0000-000000000000}", 
         0), EnvDTE.CommandEvents)
      buildEvents = CType(events.BuildEvents, EnvDTE.BuildEvents)
      solutionItemsEvents = CType(events.SolutionItemsEvents, 
         EnvDTE.ProjectItemsEvents)
   End Sub
End Class
 
end example

WinOutput Class

The WinOutput class handles the insertion of text into the IDE's Output window. It has six overloaded methods named WriteOutputWindow. The event handlers in the Connect class write information about their respective event into the Output window by calling these methods. The only difference between these methods is the number of parameters passed to the respective methods.

Note 

The Overloads keyword is new to Visual Basic developers in Visual Studio .NET. It has been in Visual C++ for a long time. It allows you to have multiple procedures with the same name differentiated by the number or type of parameters passed to the procedure.

Listing 11-13: WinOutput Class

start example

Imports EnvDTE
Public Class WinOutput
   Private OWP As OutputWindowPane
   Public Overloads Sub WriteOutputWindow(ByVal s1 As String)
      OWP.OutputString(s1 & vbCrLf)
   End Sub
   Public Overloads Sub WriteOutputWindow(ByVal s1 As String, 
      ByVal s2 As String)
      OWP.OutputString(s1 & vbCrLf)
      OWP.OutputString(s2 & vbCrLf)
   End Sub
   Public Overloads Sub WriteOutputWindow(ByVal s1 As String, 
      ByVal s2 As String, _
      ByVal s3 As String)
      OWP.OutputString(s1 & vbCrLf)
      OWP.OutputString(s2 & vbCrLf)
      OWP.OutputString(s3 & vbCrLf)
   End Sub
   Public Overloads Sub WriteOutputWindow( 
      ByVal s1 As String, 
      ByVal s2 As String, 
      ByVal s3 As String, 
      ByVal s4 As String)
      OWP.OutputString(s1 & vbCrLf)
      OWP.OutputString(s2 & vbCrLf)
      OWP.OutputString(s3 & vbCrLf)
      OWP.OutputString(s4 & vbCrLf)
   End Sub
   Public Overloads Sub WriteOutputWindow( 
      ByVal s1 As String, 
      ByVal s2 As String, 
      ByVal s3 As String, 
      ByVal s4 As String, 
      ByVal s5 As String)
      OWP.OutputString(s1 & vbCrLf)
      OWP.OutputString(s2 & vbCrLf)
      OWP.OutputString(s3 & vbCrLf)
      OWP.OutputString(s4 & vbCrLf)
      OWP.OutputString(s5 & vbCrLf)
   End Sub
   Public Overloads Sub WriteOutputWindow( 
      ByVal s1 As String, 
      ByVal s2 As String, 
      ByVal s3 As String, 
      ByVal s4 As String, 
      ByVal s5 As String, 
      ByVal s6 As String)
      OWP.OutputString(s1 & vbCrLf)
      OWP.OutputString(s2 & vbCrLf)
      OWP.OutputString(s3 & vbCrLf)
      OWP.OutputString(s4 & vbCrLf)
      OWP.OutputString(s5 & vbCrLf)
      OWP.OutputString(s6 & vbCrLf)
   End Sub
   Public Sub New(ByRef oVB As EnvDTE.DTE)
      Dim outputWindow As OutputWindow
      outputWindow = 
         CType(oVB.Windows.Item
         (Constants.vsWindowKindOutput).Object, 
         EnvDTE.OutputWindow)
      OWP = outputWindow.OutputWindowPanes. 
         Add("DTE Event Information")
   End Sub
End Class
 
end example



 < Free Open Study >