|< Free Open Study >|| |
Visual Studio .NET provides a general extensibility model for all languages sharing the IDE. Additionally, it provides a specific object model that pertains only to Visual Basic and Visual C#. The VSLangProj namespace provides the ability to manipulate project attributes, which are found only in Visual Basic and Visual C#.
DTE stands for Development Tools Extensibility. The DTE object is the most important object in extensibility because it is the root object. It is literally a pointer to the IDE through which all other objects that are exposed by the IDE are referenced. An instance of the DTE object is passed to the OnConnection method that you implement when you create an add-in. The DTE object is the Application object in VBA. The OnConnection method will be described in Chapter 2 and explored again in Chapter 3. When the Add-in Wizard, which is described in detail in Chapter 2, creates an add-in project, one of the objects that it references is the EnvDTE namespace. In the declarations section of the file Connect.vb, you will see the following code:
The Add-in Wizard will add a reference to the file DTE.OLB, which is the object library for the DTE. Including this object library in your add-in project allows you access to all of the methods, properties, and events exposed by the IDE. If you have never written an add-in before, the code snippets in this chapter may not mean a lot to you. If that is the case, do not be alarmed. The code will make sense as you get into the details of coding in later chapters. The code shown in Listing 1-1 is just a small example of how the DTE object will be used once it is passed into the add-in. This subroutine will comment the block of code selected in the active code window (or active document, as it is known in .NET).
Listing 1-1: Comment Selected Block
Sub CommentSelected Block Dim sel As TextSelection = DTE.ActiveDocument.Selectioon() Dim stPtr As EditPoint = sel.TopPoint.CreateEditPoint() Dim endPtr TextPoint = sel.BottomPoint Dim commentChar As String = "***" Try Do While (stPtr.LessThan(endPtr)) stPtr.Insert(commentChar) stPtr.LineDown() stPtr.StartOfLine() Loop Finally ' we could insert code here for undoing if an error were encountered End Try End Sub
The subroutine in Listing 1-1 was extracted from sample macro code, and references to the DTE object would be made by a reference to the application variable in an actual add-in. Chapter 3 illustrates this process in detail.
Because access to everything in the extensibility model begins at the DTE, or root object, you can begin there and drill down a level or two in the model to look at some of the components of the DTE object. Obviously, this is neither the time nor the place to examine the whole DTE object. If you search for the word "extensibility" in MSDN, the search will return around 500 topics. Additionally, if you search for the word "DTE", the search will return around 400 topics. The DTE object is truly huge.
Let's explore a few of the DTE's basic properties to give you a feel for what's available at the root level. In order to do that, you'll start two instances of Visual Basic (VB) .NET. One will have the add-in that you're debugging, and the other will use the add-in. The second copy of VB .NET will have another project open, a new Windows application. Connecting to the add-in, which you're debugging, allows you to stop in the add-in to examine objects within the IDE. Please don't be concerned with what the add-in is doing or how it was created and run. You'll deal with this in detail in Chapter 2. Suffice it to say that at this point you have two copies of VB .NET running, just as you would in the debugging of a COM DLL. You've stopped the add-in with a breakpoint in the Click Event method of its menu option. This allows you to display as many properties as you like before allowing the Click Event to continue.
I don't show images to illustrate the demonstration in this section, as I cover the Add-in Wizard and step through a basic add-in in Chapter 2.
For example, you will just print some of the properties from the Command (Immediate) window. Remember that the pointer to the DTE was passed to you in the OnConnection method as the parameter "application". The code in that method has typecast the parameter to type EnvDTE.DTE with the following code:
Dim applicationObject As EnvDTE.DTE applicationObject = Ctype(application, EnvDTE.DTE)
As you are probably already aware of .NET, you no longer use the Set command to set an object. Rather, you just use the syntax shown in the preceding example: obj = object.
Now you can use the applicationObject to qualify any reference to a component of the IDE. The code in Listing 1-2 simply displays several basic properties of the applicationObject (DTE). In each case, a print command (?) will be followed by the value echoed back from the IDE.
Listing 1-2: Displaying DTE Properties
?applicationObject.Name "Microsoft Development Environment" ?applicationObject.Mode vsIDEModeDesign ' response above indicates we are in design mode ' display the number of add-ins listed with the Add-in Manager ?applicationObject.Addins.Count 3 ' display the ActiveDocument Name ?applicationObject.ActiveDocument.Name "Form1.vb" ' display the ActiveDocument path ?applicationObject.ActiveDocument.Path "E:\VSProjs\WindowsApplication1\" ' display the ReadOnly property of the document ?applicationObject.ActiveDocument.ReadOnly False ' there are two documents open in the project that the add-in is ' connected to, verify it ?applicationObject.Documents.Count 2 ' display the fullname of the development environment exe ?applicationObject.FullName "E:\Program Files\Microsoft Visual Studio.NET\Common7\IDE\devenv.exe" ' display the IDE MainWindow Caption ?applicationObject.MainWindow.Caption "WindowsApplication1 -- Microsoft Visual Basic.NET [design] -- Form1.vb"
The displays shown in Listing 1-2 are the result of a simple exercise to demonstrate how you use the DTE object to access the components of the IDE. It would be difficult to go much further in this context. Drilling down into the multitude of objects, methods, and events requires the creation of objects. One of the sad things that you'll discover (if you haven't already) as you begin debugging in VB .NET is that the powerful features of editing, changing, and executing the changed code in the IDE are no longer possible in Visual Basic .NET. I believe that this is due to the fact that VB and C# are compiled to Microsoft intermediate language (IL), and the just-in-time (JIT) compiler compiles the code just before it's executed. C++, on the other hand, initially compiles to native code, and there's no such limitation in the C++ debugger. This is real negative for VB developers, but it appears that we're stuck with it. In any case, you can't insert new code and execute it (the new code) without rebuilding the application. However, depending on the Debug option settings, you can change code and continue debugging; you just can't execute the changed code until the project is rebuilt.
Another method of exploring and executing methods in the extensibility model is to use the Macros IDE. This new feature is an excellent way to learn how to manipulate the objects of the IDE. You'll explore this new functionality in Chapter 8 of this book.
The automation object model consists of a few distinct, but related, groups of objects that provide the major functionality of the IDE. To understand the model, you must understand how these functional groups work.
All of these functional groups are fully outlined in the Visual Studio .NET Automation Object Model chart, which you can find in the Visual Studio Help file. Some of these groups are as follows:
Solution- and project-related objects
Tool window objects, such as the Task List, Output window, and Toolbox
Code editor objects
Code manipulation objects
Window and document manipulation objects
Add-in management objects
Each functional group consists of one or more objects, collections, and interfaces that comprise a component's functionality. For example, the primary function of the event objects group is to provide access to events occurring in the IDE. You can monitor such things as files being saved, new files being added, and so forth.
One such object in this group is the TaskListEvents object, which allows you to respond to events that occur in the Task List. Another object in this group is the BuildEvents object, which allows you to respond to events that occur in a build operation, such as when a build begins or completes.
The TaskList object represents the Task List and has associated objects that allow you to add and remove items from it. The Project object represents items in a project, and objects in its functional group allow you to add, remove, and save items in projects, as well as obtain information about them, such as the paths and names of all of the files in the project and the number of files.
|< Free Open Study >|| |