Inside Microsoft® Visual Studio® .NET 2003 [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Inside Microsoft® Visual Studio® .NET 2003 [Electronic resources] - نسخه متنی

Brian Johnson

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید










Editor Windows


If you want to edit text in the IDE, you need a document; if you have a document, you also have an editor window. In Visual Studio .NET, documents and editor windows are like Siegfried and Roytogether, they work magic; apart, they're just a couple of sequined guys with pet tigers. (OK, we admit the analogy isn't perfect.) The point is that you can't have one without the other, so it pays to know a little about editor windows even if editing text in documents is your ultimate goal. Figure 11-1 gives a sneak preview of the editor windows of interest to us in this chapter.


Figure 11-1. Editor windows




The Window Object


There's not much to say about the Window objectit's just a short stop on the way to more specialized windows. Finding a window is straightforward: if you want the window that has the focus, the DTE.ActiveWindow property returns it to you; if you want some other window and you know its caption, use DTE.Windows.Item(<caption>). (Figure 11-1 shows the code for retrieving the Connect.cs and HTMLPage1 windows.)

Once you have a Window object, the most important property for finding other windows is Object, which returns the corresponding TextWindow or HTMLWindow object for editor windows. If you don't know for certain which type the Object property holds, you'll have to check using the TypeOf…Is (Visual Basic) or is (C#) keyword, as in


If TypeOf DTE.ActiveWindow.Object Is TextWindow Then

End If

Of course, if you don't check and you use the wrong object, you'll receive an exception courtesy of the common language runtime (CLR).


The TextWindow and HTMLWindow Objects


The TextWindow and HTMLWindow objects represent the editor windows in the IDE. Each type offers a small set of properties that give you access to editor-window-specific features. Table 11-1 lists the TextWindow properties. The two properties of note are ActivePane and Panes, which give you access to the panes in a given editor window.

Table 11-1.
TextWindow Properties

Property


Description


ActivePane


Returns the TextPane object associated with the active pane.


DTE


Returns the top-level DTE object.


Panes


Returns a TextPanes collection containing the panes in the window.


Parent


Returns the parent Window object.


Selection


Returns the TextSelection object for the active pane. (It is equivalent to Parent.Selection.)

Essentially, an HTMLWindow object is just a TextWindow objectexcept when it isn't. Table 11-2 shows the HTMLWindow properties.

Table 11-2.
HTMLWindow Properties

Property


Description


CurrentTab


Sets or returns the currently selected tab (HTML or Design)


CurrentTabObject


Returns a TextWindow object when the HTML tab is selected or returns an IHTMLDocument2 interface when the Design tab is selected


DTE


Returns the top-level DTE object


Parent


Returns the parent Window object

The CurrentTab property uses values from the EnvDTE.vsHTMLTabs enumeration: vsHTMLTabsSource when setting or returning the HTML tab and vsHTMLTabsDesign when setting or returning the Design tab. The CurrentTab­Object property returns a TextWindow object when the HTML tab is selected, which is why we suggested earlier that an HTMLWindow is just a TextWindow in disguise. When the Design tab is selected, however, CurrentTabObject returns an mshtml­.IHTMLDocument2 interface, which provides access to the Dynamic HTML (DHTML) object model of the underlying document. Be aware that the views offered by the Design tab and HTML tab aren't synchronized: changes in one view won't propagate to the other until you switch views. In practical terms, this means that you should use references only to the current view.

Note

To use the mshtml namespace, you need its primary interop assembly: Microsoft.mshtml.dll. You can find this assembly at (of all places) Program Files\Microsoft.NET\Primary Interop Assemblies. Add-in writers can add a reference to this assembly by browsing to it from the Add Reference dialog box; macro writers first need to copy the DLL file to Visual Studio .NET's PublicAssemblies folder before they can access the assembly.

As you now know, it takes several steps to discover whether a text window hides inside an arbitrary window. If you think it would be nice to have a function that takes care of these steps for you, you're in luck:


Function GetTextWindow(ByVal win As Window) As TextWindow
' Description: Returns the TextWindow object for a given window,
' or Nothing if not a text window
Dim txtWin As TextWindow = Nothing
' Check for TextWindow
If TypeOf win.Object Is TextWindow Then
txtWin = win.Object
' Otherwise, check for HTMLWindow, then TextWindow
ElseIf TypeOf win.Object Is HTMLWindow Then
Dim htmlWin As HTMLWindow = win.Object
If htmlWin.CurrentTab = vsHTMLTabs.vsHTMLTabsSource Then
txtWin = htmlWin.CurrentTabObject
End If
End If
Return txtWin
End Function


The TextPane Object


The TextPane object represents a pane in an editor window. Every editor window can be split into two panes to allow you to juxtapose two locations in a text file. You can split the view manually either by double-clicking the splitter barthe thin rectangle at the top of the scroll baror by clicking and dragging the splitter bar to the desired location. Afterwards, you can make changes to the same document through either pane.

Finding TextPane Objects


The automation object model makes it easy to find TextPane objects if you already have a TextWindow object: just use the ActivePane property or iterate through the Panes collection until you find the TextPane you want. Unfortunately, the TextWindow object's alter ego, HTMLWindow, doesn't offer similar properties directly, so you first have to use logic like that found in the GetTextWindow function from the previous section to extract a TextWindow from an HTMLWindow.

An alternative way of retrieving a TextPane is through the TextSelection object. TextSelection has a TextPane property that returns the pane to which the selection belongs. (TextPane has an orthogonal property, Selection, that returns the TextSelection in the pane.) TextWindow and HTMLWindow both have a Selection property, as does Window, which means there's an indirect path to TextPane that all window objects can travel. For most purposes, however, using a TextWindow to find a TextPane works just fine.

One pane-related question you might ask is whether a second pane is open in an editor window. The following code gives you the answer:


Function IsSecondPaneOpen(ByVal txtWin As TextWindow) As Boolean
' Description: Returns whether a second pane is open in a text window
Return (txtWin.Panes.Count = 2)
End Function

The TextPanes collection returned by Panes has one TextPane object for each pane in the window, so its Count property returns 2 when a second pane is open.

Here's a more interesting problemfinding the top or bottom pane in a window. The problem would be intractable except for the fact that the bottom pane is always at index 1 of its TextPanes collection. Given that bit of information, here are two functions that return the appropriate pane:


Function GetTopPane(ByVal txtWin As TextWindow) As TextPane
' Description: Returns the top pane in the text window
Dim txtPane As TextPane = Nothing
If txtWin.Panes.Count = 1 Then
' Only one pane, so return it
txtPane = txtWin.ActivePane
Else
' Top pane is always index 2
txtPane = txtWin.Panes.Item(2)
End If
Return txtPane
End Function
Function GetBottomPane(ByVal txtWin As TextWindow) As TextPane
' Description: Returns the bottom pane in a text window. Returns
' top pane if only one pane is open
' Bottom pane is always index 1
Return txtWin.Panes.Item(1)
End Function

The ActivateTopPane and ActivateBottomPane macros included with the book's sample files let you test the previous code on live windows.

One last question you might want answered is which pane a given TextPane belongs to. At first, it might seem easy enough to compare the given TextPane with its corresponding member in the TextPanes collection, but for the reasons given in the Chapter 10 sidebar "Is It What It Says It Is?" you can't compare TextPane references and expect a straight answer. Fortunately, you can compare TextSelection references successfully, which is all the help you need to write the following functions:


Function IsTopPane(ByVal txtPane As TextPane) As Boolean
' Description: Returns whether the given TextPane is the top pane
Dim result As Boolean = False
If txtPane.Collection.Count = 1 Then
result = True
Else
If txtPane.Selection Is txtPane.Collection.Item(2).Selection Then
result = True
End If
End If
Return result
End Function
Function IsBottomPane(ByVal txtPane As TextPane) As Boolean
' Description: Returns whether the given TextPane is the bottom pane
Dim result As Boolean = False
If txtPane.Collection.Count = 2 Then
result = _
(txtPane.Selection Is txtPane.Collection.Item(1).Selection)
End If
Return result
End Function


A Splitting Headache


Search all you want, but you won't find a Split method in the automation object model. However, Visual Studio .NET defines a Windows.Split command that works on the active window. For fun, here's a macro that splits every splittable window in the IDE. (If you don't think it's fun to have to unsplit all those windows, you'll find the corresponding UnsplitAllWindows macro in the book's sample files):

[View full width]

Sub SplitAllWindows()
' Description: Splits all text windows
Dim win As Window
Dim txtWin As TextWindow
Dim saveWin As Window = DTE.ActiveWindow
For Each win In DTE.Windows
txtWin = GetTextWindow(win)
If Not txtWin Is Nothing Then
SplitWindow(txtWin)
End If
Next
saveWin.Activate()
End Sub
Sub SplitWindow(ByVal txtWin As TextWindow, _
Optional ByVal restoreActive As Boolean = False)
' Description: Splits a text window and optionally restores the

' active window when finished
Dim split As Command = DTE.Commands.Item("Window.Split")
Dim saveWin As Window
If restoreActive Then
saveWin = DTE.ActiveWindow
End If
txtWin.Parent.Activate()
If split.IsAvailable And Not IsSecondPaneOpen(txtWin) Then
DTE.Commands.Raise(split.Guid, split.ID, Nothing,
Nothing)
End If
If restoreActive Then
saveWin.Activate()
End If
End Sub



/ 118