The visible, content portion of Visual Studio is represented by Window objects. Window objects are instances of open windows within the IDE such as the Solution Explorer, the task list window, an open code editor window, and so on. Even the IDE itself is represented by a Window object. Any given window is either a document window or a tool window. Document windows host documents that are editable by the Text Editor. Tool windows contain controls that display information relevant to the current context of the IDE; the Solution Explorer and task list windows are examples of tool windows, and a VB source code file open in an editor is an example of a document window. Referencing Windows If you need to retrieve an instance of a specific window, you have a few different options, each optimal for a given situation. For starters, the main IDE window is always available directly from the DTE object: Dim IDE As Window IDE = DTE.MainWindow Obviously, if you need to perform a specific action against the IDE window, this is your quickest route. The DTE.ActiveWindow property also provides direct and quick access to a Window object, in this case the currently active window: Dim CurrentWindow As Window CurrentWindow = DTE.ActiveWindow The tool windows within the IDEthat is, the command window, the error list window, the output window, the Solution Explorer, the task list window, and the Toolboxalso have a direct way to retrieve their object model instances: You use the DTE.ToolWindows property. This property returns a ToolWindows object that exposes a separate property for each of the tool windows. This Visual Basic code grabs a reference to the task list window and closes it: Dim taskwin As Window taskwin = DTE.ToolWindows.TaskList taskwin.Close() And finally, the fourth way to access an IDE window is through the DTE.Windows collection; this collection holds an entry for each IDE window. You can access a window from the collection by using either an integer representing the window's position within the collection, or by providing an object or string that represents the window you are trying to retrieve. The following code grabs a handle to the Solution Explorer window: Dim windows As Windows2 = DTE.Windows Dim window As Window = windows.Item(Constants.vsWindowKindSolutionExplorer) Interacting with Windows Table 10.6 itemizes the properties and methods available on each Window object. Table 10.6. Window Object MembersProperty | Description |
---|
AutoHides | A Boolean flag indicating whether the window can be hidden (applies only to tool windows). | Caption | The title/caption of the window. | Collection | The Windows collection that the current Window object belongs to. | CommandBars | A CommandBars collection of the command bars implemented by the window. | ContextAttributes | A collection of ContextAttribute objects; they are used to associate the current context of the window with the Dynamic Help window. | Document | If the Window object is hosting a document, this returns a reference to the document. | DTE | A reference to the root DTE object. | Height | The height of the window in pixels. | IsFloating | A Boolean flag indicating whether the window is floating or docked. | Left | The distance, in pixels, between the window's left edge and its container's left edge. | Linkable | A Boolean flag indicating whether the window can be docked with other windows. | LinkedWindowFrame | Returns a reference to the Window object that is acting as the frame for a docked window. | LinkedWindows | A collection of Window objects representing the windows that are linked together within the same frame. | Object | Returns an object proxy that represents the window and can be referenced by name. | ObjectKind | A GUID indicating the type of the object returned from Window.Object. | Project | A Project instance representing the project containing the Window object. | ProjectItem | A ProjectItem instance representing the project item containing the Window object. | Selection | Returns an object representing the currently selected item in the window (for document windows, this might be text; for tool windows, this might be an item in a list, and so on). | Top | The distance, in pixels, between the window's top edge and its parent's top edge. | Visible | A Boolean flag indicating whether the window is visible or hidden. | Width | The width of the window in pixels. | WindowState | Gets or sets the current state of the window (via a vsWindowState enum value: vsWindowStateMaximize, vsWindowStateMinimize, vsWindowStateNormal). |
Method | Description |
---|
Activate | Gives the window focus. | Close | Closes the window; you can indicate, with a vsSaveChanges enum value, whether the window's hosted document should be saved or not saved, or whether the IDE should prompt the user to make that decision. | SetSelectionContainer | Passes an array of objects to the Properties window when the Window object has focus. This property is mainly used for custom tool windows where you need to control what is displayed in the Properties window. | SetTabPicture | Specifies an object to use as a tab image; this image is displayed whenever the window is part of a tab group within the IDE. |
Beyond the basics (such as using the Height and Width properties to query or affect a window's dimensions, or setting focus to the window with the SetFocus method), a few properties deserve special mention: The Document property gives you a way to programmatically interact with the document that the window is hosting (if any). The Project and ProjectItem properties serve to bridge the Window portion of the API with the Project/Solution portion; in a similar vein as the Document property, you can use these properties to interact with the project that is related to the window, or the project item (such as the VB code file, text file, resource file, and so on). If you are dealing with a tool window, the SetTabPicture method provides a way to set the tab icon that is displayed when the tool window is part of a group of tabbed windows (for instance, the Toolbox window displays a wrench and hammer picture on its tab when part of a tabbed group). Again, specifically for tool windows only, the SetSelectionContainer can be used to supply one or more objects for display within the Properties window. This capability is useful if you have a custom window where you need to control what is displayed in the Properties window when the window has focus (all the standard VS windows already do this for you). Listing 10.2 contains a simple macro illustrating the use of the Window object; in this example, each window is queried to determine its type, and then a summary of each window is output in a simple message box. Listing 10.2. VB Macro for Querying the Windows Collection Imports EnvDTE Imports EnvDTE80 Imports System.Diagnostics Imports System.Windows.Forms Public Module MacroExamples Public Sub InventoryWindows() ' Get collection of all open windows Dim windows As Windows2 = DTE.Windows ' Count the nbr of open windows Dim windowCount As Integer = windows.Count ' Local vars for looping and holding window and string ' results Dim idx As Integer Dim results As String Dim window As Window2 results = windowCount.ToString + " windows open..." + vbCrLf ' Iterate the collection of windows For idx = 1 To windowCount window = windows.Item(idx) Dim title As String = window.Caption ' If the window is hosting a document, a valid Document ' object will be returned through Window.Document If Not (window.Document Is Nothing) Then ' Write this out as a document window Dim docName As String = window.Document.Name results = results + "Window '" + title + "' is a document window" + vbCrLf Else ' If no document was present, this is a tool window ' (tool windows don't host documents) results = results + "Window '" + title + "' is a tool window" + vbCrLf End If Next ' Show the results MessageBox.Show(results, "Window Documents", MessageBoxButtons.OK, _ MessageBoxIcon.Information) End Sub End Module | Note If you want to embed your own custom control inside a tool window, you have to write an add-in and use the Windows.CreateToolWindow method. We cover this scenario in Chapter 11. Text Windows and Window Panes Text windows have their own specific object abstraction in addition to the generic Window object: The TextWindow object is used to represent text editor windows. To obtain a reference to a window's TextWindow object, you retrieve the Window object's value and assign it into a TextWindow type: Dim textWindow As TextWindow textWindow = DTE.ActiveWindow.Object The TextWindow object doesn't provide much functionality over and above the functionality found in the Window type; its real value is the access it provides to window panes. Text editor windows in Visual Studio can be split into two panes; with a text editor open, simply select Split from the Window menu to create a new pane within the window. The TextWindow.ActivePane property returns a TextPane object representing the currently active pane in the window, and the TextWindow.Panes property provides access to all the panes within a text window: ' Get pane instance from collection Dim newPane As TextPane2 newPane = textWindow.Panes.Item(1) ' Get currently active pane Dim currPane As TextPane2 currPane = textWindow.ActivePane One of the more useful things you can do with the TextPane object is to scroll the client area of the pane (for example, the visible portion of the document within the pane) so that a specific range of text is visible. This is done via the TextPane.TryToShow method. Here is the definition for the method: Function TryToShow(Point As TextPoint, Optional How As vsPaneShowHow, _ PointOrCount As Object) The TextPoint parameter represents the specific location within the text document that you want visible in the text pane (we discuss TextPoint objects in depth in a later section of this chapter; see "Editing Text Documents"). The vsPaneShowHow value specifies how the pane should behave when scrolling to the indicated location: vsPaneShowHow.vsPaneShowCentered will cause the pane to center the text/text selection in the middle of the pane (horizontally and vertically). vsPaneShowHow.vsPaneShowTop will place the text point at the top of the viewable region in the pane. vsPaneShowHow.vsPaneShowAsIs will show the text point as is with no changes in horizontal or vertical orientation within the viewable region in the pane. The last parameter, the PointOrCount object, is used to specify the end of the text area that you want displayed. If you provide an integer here, this represents a count of characters past the original text point; if you provide another text point, then the selection is considered to be that text that resides between the two text points. The TextPane object is also used to access the Incremental Search feature for a specific window pane. Listing 10.3 shows an example of this feature in action. Listing 10.3. Controlling Incremental Search Imports EnvDTE Imports EnvDTE80 Imports Microsoft.VisualStudio.CommandBars Imports System.Diagnostics Imports System.Windows.Forms Public Module MacroExamples Public Sub IncrementalSearch() ' Grab references to the active window; ' we assume, for this example, that the window ' is a text window. Dim window As Window2 = DTE.ActiveWindow ' Grab a TextWindow instance that maps to our ' active window Dim txtWindow As TextWindow = window.Object ' Get the active pane from the text window Dim pane As TextPane2 = txtWindow.ActivePane 'Using the active pane, get an IncrementalSearch object ' for the pane Dim search As IncrementalSearch = pane.IncrementalSearch ' Try to find our IMessageMapper interface by looking ' for the string "IM" ' Configure the search: ' search forward in the document ' append the chars that we are searching for ' quit the search search.StartForward() search.AppendCharAndSearch(AscW("I")) search.AppendCharAndSearch(AscW("M")) ' To remove us from incremental search mode, ' we can call IncrementalSearch.Exit()... 'search.Exit() End Sub End Module | The Tool Window Types In addition to having a Window object abstraction, each default tool window in the IDEthe command window, output window, Toolbox window, and task list windowis also represented by a discrete type that exposes methods and properties unique to that tool window. Table 10.7 lists the default tool windows and their underlying type in the automation object model. Table 10.7. Tool Windows and Their TypesTool Window | Type |
---|
Command Window | CommandWindow | Output Window | OutputWindow | Task List Window | TaskList | Toolbox Window | ToolBox |
To reference one of these objects, you first start with its Window representation and then cast its Window.Object value to the matching type. For instance, this VB snippet starts with a Window reference to the task list window and then uses that Window object to obtain a reference to the TaskList object: Dim windows As Windows = DTE.Windows Dim twindow As Window = _ DTE.Windows.Item(EnvDTE.Constants.vsWindowKindTaskList) Tasks and the Task List Window The TaskList object enables you to access the items currently displayed in the task list window; each item in the window is represented by its own TaskItem object. The TaskItem object exposes methods and properties that allow you to manipulate the task items. For instance, you can mark an item as complete, get or set the line number associated with the task, and change the priority of the task. You remove tasks from the list by using the TaskItem.Delete method and add them by using the TaskItems.Add method. The Add method allows you to specify the task category, subcategory, description, priority, icon, and so on: Dim tlist As TaskList = CType(twindow.Object, TaskList) tlist.TaskItems.Add("Best Practices", "Coding Style", _ "Use of brace indenting is inconsistent", _ vsTaskPriority.vsTaskPriorityMedium, _ vsTaskIcon.vsTaskIconUser, True, _ "S:\ContosoCommonFramework\Contoso.Fx.Common\Class1.cs", _ 7, True, True) Table 10.8 provides an inventory of the TaskItem members. Table 10.8. TaskItem MembersProperty | Description |
---|
Category | The category of the task. | Checked | A Boolean flag indicating whether the task is marked as completed (a check mark appears in the check box next to the task). | Collection | The TaskList collection that the current TaskItem object belongs to. | Description | The description of the task. | Displayed | A Boolean flag indicating whether the task is currently visible in the task list window. | DTE | A reference to the root DTE object. | FileName | The name of the file associated with the task (if any). | IsSettable | By passing in a vsTaskListColumn enum value to this property, you can determine whether that column is editable or not. | Line | The line number associated with the task. | Priority | A vsTaskPriority value indicating the task's priority level. Possible values include vsTaskPriorityHigh, vsTaskPriorityMedium, and vsTaskPriorityLow. | SubCategory | The subcategory of the task. | LinkedWindows | A collection of Window objects representing the windows that are linked together within the same frame. | Object | Returns an object proxy that represents the Window and can be referenced by name. | ObjectKind | A GUID indicating the type of the object returned from Window.Object. | Project | A Project instance representing the project containing the Window object. | ProjectItem | A ProjectItem instance representing the project item containing the Window object. | Selection | Returns an object representing the currently selected item in the Window (for document windows, this might be text; for tool windows, this might be an item in a list, and so on). | Top | The distance, in pixels, between the window's top edge and its parent's top edge. | Visible | A Boolean flag indicating whether the window is visible or hidden. | Width | The width of the window in pixels. | WindowState | Gets or sets the current state of the window (via a vsWindowState enum value: vsWindowStateMaximize, vsWindowStateMinimize, vsWindowStateNormal). |
Method | Description |
---|
Delete | Removes the task from the task list window. | Navigate | Causes the IDE to navigate to the location (for example, file and line) associated to the task. | Select | Selects or moves the focus to the task within the task list window. |
Listing 10.4 contains a short VB macro demonstrating the use of the TaskList, TaskItems, and TaskItem objects to iterate the tasks and toggle their completed status. Listing 10.4. Toggling Task Item Completion Imports EnvDTE Imports EnvDTE80 Imports Microsoft.VisualStudio.CommandBars Imports System.Diagnostics Imports System.Windows.Forms Public Module MacroExamples Public Sub ToggleAllTasks() ' Reference the windows collection Dim windows As Windows = DTE.Windows ' Pluck the task list window from the collection Dim twindow As Window = _ DTE.Windows.Item(EnvDTE.Constants.vsWindowKindTaskList) ' Convert the window object to a TaskList instance by ' casting its Object property Dim tlist As TaskList = CType(twindow.Object, TaskList) ' Iterate all of the task items in the task list For Each task As TaskItem In tlist.TaskItems ' Toggle the "completed" check mark on each item task.Checked = Not task.Checked Next End Sub End Module | The ToolBox Four objects are used to programmatically interface with the Toolbox: ToolBoxAn object representing the Toolbox itself ToolBoxTabsA collection representing the tab panes on the Toolbox ToolBoxItemsA collection representing the items within a tab on the Toolbox ToolBoxItemA discrete item displayed within a Toolbox tab Figure 10.3 illustrates the Toolbox object hierarchy. Figure 10.3. ToolBox object hierarchy. These objects are used primarily to add, remove, or alter the items hosted by the Toolbox. For instance, you can easily add a custom tab to the Toolbox by using the ToolBoxTabs collection: Dim tBox As ToolBox Dim myTab As ToolBoxTab tBox = DTE.Windows.Item(Constants.vsWindowKindToolbox).Object myTab = tBox.ToolBoxTabs.Add("My TBox Tab") You can also add items to any tab with the ToolBoxItems.Add method, which accepts a name for the item to add, a "data" object representing the item, and a vsToolBoxItem-Format enum, which specifies the format of the item. The Add method uses the vsToolBoxItemFormat to determine how to interpret the "data" object value. For instance, if you wanted to add a .NET control to the tab created in the previous code snippet, you could accomplish that with just one line of code: tlBoxTab.ToolBoxItems.Add("ContosoControl", _ "C:\Contoso\Controls\CalendarControl.dll", _ vsToolBoxItemFormat.vsToolBoxItemFormatDotNETComponent) Notice that the item, in this case, is represented by a path to the assembly that implements the control and that it has an item format of vsToolBoxItemFormatDotNET-Component. Listing 10.5 contains a VB function that adds a tab to the Toolbox, adds a control and a text fragment to the tab, and then removes the tab. Listing 10.5. Adding and Removing Items in the Toolbox Window Imports EnvDTE Imports EnvDTE80 Imports Microsoft.VisualStudio.CommandBars Imports System.Diagnostics Imports System.Windows.Forms Public Sub AddAToolBoxTab() Dim toolBox As ToolBox Dim tabs As ToolBoxTabs Dim tab As ToolBoxTab Dim tabItems As ToolBoxItems Dim win As Window Try ' Get a reference to the toolbox win = DTE.Windows.Item(Constants.vsWindowKindToolbox) toolBox = win.Object ' Get a reference to the toolbox tabs collection tabs = toolBox.ToolBoxTabs ' Add a new tab to the ToolBox tab = tabs.Add("New ToolBox Tab") ' Make the added tab the active tab tab.Activate() tabItems = tab.ToolBoxItems With tabItems ' Add a piece of text to the toolbox. ' Clicking on the text will add it to ' the active document... .Add("Code Comment", _ "This is some text to add to the toolbox", _ vsToolBoxItemFormat.vsToolBoxItemFormatText) 'Now add a control to the toolbox. 'When adding a control, you need to specify 'the path to the assembly; you can add all 'classes from the assembly (shown below) 'or just one of the classes (see MSDN 'docs for that syntax) .Add("My Login Control", _ "C:\MyComponents\Contoso\LoginControl.dll", _ vsToolBoxItemFormat.vsToolBoxItemFormatDotNETComponent) 'For demonstration purposes, let's remove 'the items that we had just added, and then 'remove the newly created tab... 'Put up a messagebox to confirm the deletes MessageBox.Show("Click OK to delete the tab and added items.", _ "Delete Toolbox Tab Items", MessageBoxButtons.OK, _ MessageBoxIcon.Information) 'Delete the tab tab.Delete() End With Catch ex As Exception MsgBox("Error: " & ex.ToString()) End Try End Sub | Executing Commands in the Command Window The command window is a tool window used to execute IDE commands or aliases. IDE commands are essentially ways to tell the IDE to perform some action. Some commands map directly to menu items (such as File Open), whereas others don't have menu equivalents. The CommandWindow object permits you to programmatically pipe commands into the command window and execute them. You can also output a text string (for informational purposes) to the window and clear its current content: ' Get a reference to the command window Dim cmdWindow As CommandWindow = _ DTE.Windows.Item(Constants.vsWindowKindCommandWindow).Object ' Display some text in the command window cmdWindow.OutputString("Hello, World!") ' Clear the command window cmdWindow.Clear() Listing 10.6 shows how to programmatically execute commands in the CommandWindow object. Listing 10.6. Executing Commands in the Command Window Imports EnvDTE Imports EnvDTE80 Imports Microsoft.VisualStudio.CommandBars Imports System.Diagnostics Imports System.Windows.Forms Public Module MacroExamples Public Sub ExecCommandWindow() Dim cmdWindow As CommandWindow = _ DTE.Windows.Item(Constants.vsWindowKindCommandWindow).Object ' Display some text in the command window cmdWindow.OutputString("Executing command from the automation OM...") ' Send some command strings to the command window and execute ' them... ' This command will start logging all input/output in the ' command window to the specified file cmdWindow.SendInput("Tools.LogCommandWindowOutput cmdwindow.log", True) ' Open a file in a code editor: ' 1. We use an alias, 'of', for the File.OpenFile command ' 2. This command takes quote-delimited parameters (in this case, ' the name of the editor to load the file in) Dim cmd As String = "of " cmd = cmd & """C:\Contoso\ContosoCommonFramework\Integration\Integration.cs""" cmd = cmd & "/e:""CSharp Editor""" cmdWindow.SendInput(cmd, True) cmdWindow.SendInput("Edit.Find MessageTrxId", True) ' Turn off logging cmdWindow.SendInput("Tools.LogCommandWindowOutput /off", True) End Sub End Module | Output Window The output window displays messages generated from a variety of different sources in the IDE. A prime example is the messages generated by the compiler when a project is being built. For a deeper look at the functionality provided by the output window, see Chapter 9, "Debugging with Visual Studio 2005." The output window is controlled through three objects: OutputWindow is the root object representing the output window. OutputWindowPanes is a collection of OutputWindowPane objects. OutputWindowPane represents one of the current panes within the output window. Using these objects, you can add or remove panes from the output window, output text to any one of the panes, and respond to events transpiring in the window. The following VB code fragment retrieves a reference to the output window and writes a test string in the Build pane: Dim outWindow As OutputWindow = _ DTE.Windows.Item(Constants.vsWindowKindOutput).Object Dim pane As OutputWindowPane = _ outWindow.OutputWindowPanes.Item("Build") pane.OutputString("test") Using the OutputWindowPane object, you can also add items simultaneously to a specific output pane and the task list window. The OutputWindowPane.OutputTaskItemString method writes text into the output window and simultaneously adds that text as a task to the task list window: Dim output As String = "Exception handler not found" Dim task As String = "Add exception handler" pane.OutputTaskItemString(output, _ vsTaskPriority.vsTaskPriorityMedium, "", vsTaskIcon.vsTaskIconNone, _ "", 0, task, True) Because most of the output window actions are conducted against a specific pane, most of the useful methods are concentrated in the OutputWindowPane object. For your reference, the OutputWindowPane members are itemized in Table 10.9. Table 10.9. OutputWindowPane MembersProperty | Description |
---|
Collection | The OutputWindowPanes collection that the current OutputWindowPane object belongs to | DTE | A reference to the root DTE object | Guid | The GUID for the output window pane | Name | The name of the output window pane | Textdocument | A Textdocument object representing the window pane's content |
Method | Description |
---|
Activate | Moves the focus to the output window | Clear | Clears the contents of the window pane | ForceItemsToTaskList | Writes all task items not yet written to the task list window | OutputString | Writes a string to the output window pane | OutputTaskItemString | Writes a string to the output window pane and simultaneously adds a task to the task list window |
Listing 10.7 demonstrates controlling the output window by adding a new pane to the window, writing text into that pane, and then clearing its content. Listing 10.7. Writing to the Output Window Imports EnvDTE Imports EnvDTE80 Imports Microsoft.VisualStudio.CommandBars Imports System.Diagnostics Imports System.Windows.Forms Public Module MacroExamples Public Sub WriteToOutputWindow() ' Grab a reference to the output window Dim outWindow As OutputWindow = _ DTE.Windows.Item(Constants.vsWindowKindOutput).Object ' Create a new pane in the output window Dim pane As OutputWindowPane = _ outWindow.OutputWindowPanes.Add("New Pane") pane.OutputString("Text in the 'New Pane'") pane.Clear() End Sub End Module | Linked Windows Tool windows can be positioned in a variety of ways within the IDE: You can float tool windows around within the overall IDE container; you can dock a tool window to one of the sides of the IDE; you can join windows together, pin and unpin them; and so on (see the section "Managing the Many Windows of the IDE" in Chapter 2, "A Quick Tour of the IDE," for an introduction to window layout). A linked window refers to two or more tool windows that have been aggregated together. Figure 10.4 shows one common example of this: The Toolbox and Solution Explorer and the Data Sources window have all been joined together in a common frame. Each window that is part of the frame can be viewed by clicking on its tab. Figure 10.4. Linked windows. By joining together two or more tool windows, you actually create an additional window objectcalled a linked window or window framethat functions as the container for its hosted tool windows and is available as a part of the DTE.Windows collection. By using the Window.LinkedWindows and Window.WindowFrame properties and the Windows2.CreateLinkedWindowFrame method, you can programmatically link and unlink any available tool windows. The Visual Basic code in Listing 10.8 demonstrates this process by doing the following: You grab the window objects for the Toolbox window and the Solution Explorer window. You programmatically join these two windows together, effectively creating the linked window that you see in Figure 10.4. After joining the windows together, you get a reference to the newly created linked window and use its LinkedWindows property to unlink the windows that were previously just linked together. Listing 10.8. Linking and Unlinking Tool Windows Imports EnvDTE Imports EnvDTE80 Imports System.Diagnostics Imports System.Windows.Forms Public Module MacroExamples Public Sub LinkUnLink() Dim windows As Windows2 = DTE.Windows ' Grab references to the solution explorer and the toolbox Dim solExplorer As Window2 = _ windows.Item(Constants.vsWindowKindSolutionExplorer) Dim toolbox As Window2 = windows.Item(Constants.vsWindowKindToolbox) ' Use the Windows2 collection to create a linked window/window ' frame to hold the toolbox and solution explorer windows Dim windowFrame As Window2 windowFrame = windows.CreateLinkedWindowFrame(solExplorer, _ toolbox, vsLinkedWindowType.vsLinkedWindowTypeTabbed) ' At this point, we have created a linked window with two tabbed ' "interior" windows: the solution explorer, and the toolbox... MessageBox.Show("Press OK to Unlink the windows", "LinkUnLink", _ MessageBoxButtons.OK, MessageBoxIcon.None) ' To unlink the windows: ' -- Use the window frame's ' -- Remove the window objects from this collection windowFrame.LinkedWindows.Remove(toolbox) windowFrame.LinkedWindows.Remove(solExplorer) End Sub End Module | |