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
{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}
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 >