Because an add-in is a Visual Studio project in its own right, it can takeadvantage of the full power of the development environment.Snippets An IntelliSense code snippet or just snippet
Trang 1Part IIMeta-Development
Trang 3Like macros, add-ins let you generate complicated pieces of code Add-ins have the additionaladvantage that they are compiled, so you can write an add-in for developers while not allowingthem to view or modify it Because an add-in is a Visual Studio project in its own right, it can takeadvantage of the full power of the development environment.
Snippets
An IntelliSense code snippet (or just snippet) is a piece of code stored in a special XML format, so it is
easy to insert into your applications Visual Studio comes with several hundreds of pre-built pets that you can use to generate code for such tasks as activating a running application, clearingthe console window, creating a sorted dictionary, or calculating the sine of an angle:
Many of the pre-built snippets are quite simple For example, the following code shows the pet that calculates the sine of an angle:
snip-Dim radians As Double = 120 * Math.PI / 180Dim sin As Double = Math.Sin(radians)
Trang 4When you insert this snippet, the code’s “120” is highlighted by a green box and the cursor is positionedthere This is a replacement area You should replace the default angle 120with the angle you’re inter-ested in If you hover the mouse over the replacement area, a tooltip gives you a hint about what you aresupposed to do by saying, “Replace with the measurement in degrees.”
Snippets can help you remember how to write the code for common programming tasks They can mate tedious, repetitive chores, and can help you remember the little details that are so easy to forget.For example, they can automatically add the appropriate Importsstatements when you use routinesthat require them They build the pieces of property procedures, including the procedures themselves,the private variables that store procedure values, attributes to give descriptions of the procedures andcategories in the Properties window, and even comments
auto-Snippets can even help you standardize your code For example, suppose you have a standard commentblock that you want every developer on the project to use at the beginning of every file This block mightinclude a copyright statement, the name of the module, the name of the developer who created the file,and places for revision history You can help developers follow the standard by creating a snippet thatcontains the comment template If developers insert the snippet into their modules, all of the files willhave module-level comments in exactly the same format The snippet’s replacement areas even help thedevelopers insert the module’s name and the name of the developer who created the file
The following section describes in greater detail how to insert snippets The sections after that oneexplain how to write your own snippets
Trang 5Scroll down to the folder that contains the snippet you want and double-click it In some cases, the initialsnippet folder will contain subfolders Continue delving into the snippet folders until you find a list ofactual snippets similar to the one shown in Figure 8-2 Then double-click the snippet you want to insert.
Figure 8-2: Double-click the snippet that you want to insert
Figure 8-3 shows the code inserted by the Public Property snippet Colored boxes indicate values that youshould replace In this example, the replacement values include the strings FirstName, String, and Misc.They also include blank values inside the quotes in the code’s Descriptionand DefaultValueattributes
Trang 6If you hover the mouse over a replacement area, a tooltip tells you what value you should put there.Initially, the first replacement area for FirstNameis highlighted Enter the name you want to give thisproperty When you press the Tab key, the value you entered is copied to all of the FirstNamereplace-ment fields and the next replacement area is highlighted Continue making replacements until you havereplaced all of the values.
If there is a shortcut assigned to a snippet, then you can use it to insert the snippet more quickly Typethe first several letters in the shortcut, followed by a question mark (?), and press Tab Visual Studio dis-plays a pop-up list of snippets with the one matching the string you entered selected Figure 8-4 showsthe list displayed when I typed “propertysn?”
Figure 8-4: Using snippet shortcuts you can insert snippets very quickly
If you use a snippet frequently, it will be faster to insert it using its shortcut than by navigating throughthe snippet folders
Actually, snippets are just text files in XML format, so you could write them using any text editor.
However, when the Visual Studio IDE opens a snippet, it uses a special XML editor that makes editing
the files easier For example, it knows which tags should be allowed at different points If you type “<”
Trang 7inside a Literalelement, the editor displays a pop-up that lists the allowed sub-items: ! (for ments), ?(for XML processor instructions), Default, Function, ID, ToolTip, and Type The edi- tor also flags XML errors such as unclosed tags, mismatched open and close tags, and so forth.
com-Double-click the file to open it Initially, the file only contains an XML declaration After the declaration,you must add a series of XML tags to define the snippet Rather than wading through all of the uglydetails, take a look at the following example The text that follows describes the key sections that youneed to modify:
GetMessageBox.Show(“In $name$.Get”)Return m_$name$
End GetSet(ByVal value As $data_type$)
Trang 8MessageBox.Show(“In $name$.Set”)m_$name$ = value
End SetEnd Property]]>
The Snippetsection contains several key subsections The Importssection contains information aboutimports that the code in the snippet requires This example contains one import: System.ComponentModel.When you use this snippet, if the module does not already have an Importsstatement for this namespace,the snippet adds it at the top of the module In this example, the statements would be as follows:
Imports System.ComponentModel
Imports System.Windows.Forms
This example needs the System.ComponentModelnamespace because it uses the Browsableattribute
It needs the Systems.Windows.Formsnamespace to use the MessageBoxclass
The Referencessection contains references that the snippet’s code needs If the project doesn’t alreadyhave a reference to the indicated assembly, the snippet adds it This example requires a reference to
System.Windows.Forms.dllbecause that library contains the MessageBoxclass
The Declarationssection defines replacement variables Each Literaltag defines a word in the pet code that the developer can replace This example’s first Literaldefines a token called “name.” Thesnippet code indicates a replacement value by enclosing the token’s ID in dollar signs, as in $name$.Tags within the Literalgive the tooltip to display and the item’s default value You should give a
snip-Literala default value whenever possible, because it makes the value easier for the developer to see.The Declarationssection can also contain Objecttags to define replacements representing objectsthat are usually defined outside of the snippet’s code
Finally, the Codetag contains the snippet’s actual code In this example, the tag’s Languageattributeindicates that this is a Visual Basic snippet The <![CDATA[string allows an XML file to contain justabout any text, including white spaces and carriage returns, until reaching the corresponding ]]>.Microsoft has produced a free snippet editor that lets you avoid the details of writing an XML file.Download it at http://msdn.microsoft.com/vbasic/downloads/tools/snippeteditor
Trang 9Installing Snippets
After you create a snippet file, put it in a directory where you want to store snippets The cascadingsnippet menus shown in Figures 8-1 and 8-2 display the directory’s name, so give the directory a mean-ingful name
Next, open Visual Studio’s Tools menu and select the Code Snippets Manager command to display thetool shown in Figure 8-5 Click the Add button, browse to your snippets directory, and click Open Back
in the Code Snippets Manager, click OK
Figure 8-5: Use the Code Snippets Manager to add and remove snippet directories
Now, Visual Studio is ready to use the snippets in that directory When you right-click in a code editorand select the Insert Snippet command, you should see the directory and any snippets defined in
.snippetfiles within the directory
Sharing Snippets
Because snippets are plain old text files, they are easy to share You can email them to other developers,
or post them on your Web site You can put them in a shared snippet directory to ensure that everydeveloper on your project uses the same snippets so that they get the benefit of consistency
You can also search the Web for snippets You can download code snippets for Visual Studio at
http://msdn.microsoft.com/vstudio/downloads/codesnippets As of this writing, these are thesnippets that come with Visual Studio 2005, so they should already be installed on your system This isprobably a good place to check for updates, however
Trang 10You can search this book’s snippet library at www.vb-helper.com/snippets.html If you come upwith a good snippet that you’d like to share, send it to me at RodStephens@vb-helper.comand I’lladd it to the library.
Macros
Snippets are a fantastic way to automate building certain chunks of code in a fixed format, while ing you to make simple replacements By using snippets, you can simplify moderately complicated tasksand add some useful consistency to a development project
allow-Although snippets are easy, they are fairly limited They use a “design by example” approach, whereyou write code and then turn it into a snippet This approach is extremely simple, but it’s not very flexi-ble For example, the previous example that creates property procedures won’t work if you want to add
a parameter to the property, as shown in the following code:
‘ Get or set a test score
Private m_Scores(0 To 9) As Double
Public Property Score(ByVal test_number As Integer) As Double
GetReturn m_Scores(test_number)End Get
Set(ByVal value As Double)m_Scores(test_number) = valueEnd Set
End Property
Snippets also only create code; they don’t modify it or the Visual Studio IDE
Macros give you much greater flexibility They let you write new code, modify existing code, and controlthe development environment
Visual Studio lets you record, write, edit, debug, and play back macros later, much as the MicrosoftOffice applications do (although the Microsoft Office applications use VBA as their macro language,whereas Visual Basic 2005 uses Visual Basic 2005 for macros) You can use macros to automate tasks thatyou need to perform frequently, such as the following:
❑ Writing a series of Visual Basic statements that are mostly the same
❑ Performing an action on similar code entities (for example, commenting functions or printingcode documents)
❑ Altering the project’s structure (for example, adding files to it)
❑ Modifying the Visual Studio environment
The following sections briefly describe how to record, edit, and use macros in Visual Studio
Trang 11Recording Macros
To record a macro, open the Tools menu, go to the Macros submenu, and select the Record
TemporaryMacrocommand Visual Studio displays the Macro Recorder shown in Figure 8-6, and startsrecording a macro
Figure 8-6: The Macro Recorder lets you pause, stop, or cancel macro recording
While the Macro Recorder is running, you can add, edit, and delete code Unfortunately, the MacroRecorder does not capture any changes to a form’s properties and controls, so you may as well stay in acode editor
When you have finished recording, click the Stop Recording button in the middle of the Macro Recorder.Visual Studio stores the new macro in a macro module To see the macro, open the Tools menu, go to theMacros submenu, and the select the Macro Explorer command to display the Macro Explorer shown inFigure 8-7
Figure 8-7: The Macro Explorer lets you view,edit, and run macros
The new macro is the RecordingModuleand is named TemporaryMacro To execute the macro, click it, or right-click it and select Run from the context menu
double-If you record a new temporary macro, the previous one is overwritten double-If you want to save a temporarymacro for later use, right-click it in Macro Explorer, select Rename, and give the macro a new name.Now, if you record a new macro, it is named TemporaryMacroand your old macro is saved
Trang 12Editing Macros
To edit a macro, right-click it in Macro Explorer, and select Edit to make Visual Studio open the MacroIDE shown in Figure 8-8
Figure 8-8: Visual Studio lets you edit macros much as it lets you edit Visual Basic projects
You can modify the macro’s code in the code editor shown in Figure 8-8 much as you can modify VisualBasic code in the Visual Studio IDE You can even set breakpoints in the editor, and step through thecode to debug it
To organize your macros, you can use the Project Explorer shown on the left in Figure 8-8 Right-clickand add folders and modules to the projects Then you can copy the renamed temporary macro into one
of those modules
Modifying Macros
Unfortunately, recorded macros are often not very useful because they perform exactly the same stepsthat you performed already If you need to perform an extremely repetitive and mechanical task, youmight get some mileage out of repeating the same sequence of commands again and again
Usually, it’s more useful to do something similar to the recorded macro, and not repeat exactly the same
steps each time Start by recording a macro that is as similar as possible to what you need to do Thenedit the macro to suit your needs
For example, suppose you have 16 TextBoxcontrols named TextBox0, TextBox1, , TextBox15
arranged in a grid on a form, and you want to set references to them in a two-dimensional array Youcould record a macro while typing the following code:
m_TextBoxes(0, 0) = TextBox0
Trang 13The following code shows the recorded macro:
Sub TemporaryMacro()DTE.ActiveDocument.Selection.Text = “m_TextBoxes(0, 0) = TextBox0”
DTE.ActiveDocument.Selection.NewLine()End Sub
DTE stands for “development tools environment.” The DTEobject sits at the top of the Visual Studio extensibility object model It is similar to the Applicationobject used by some other programs such
as the Microsoft Office applications
ActiveDocumentis an object that represents the currently active editor document, in this case the code in the code editor Selectionis a property of the ActiveDocumentthat represents the cur- rently selected text The previous code sets this text and then adds a new line to it.
The extensibility object model is enormous, so there will barely be time to introduce it here Look in the online help for “DTE” for more information.
You don’t want to repeat exactly this statement 16 times, but it’s easy to modify the recorded code Thefollowing code loops through the four rows and columns, adding code for each control Notice how itadds to the code the values of the row and column variables and the number in the control’s name
Sub SaveTextBoxes()For r As Integer = 0 To 3For c As Integer = 0 To 3DTE.ActiveDocument.Selection.Text = “m_TextBoxes(“ & _r.ToString() & “, “ & c.ToString() & _
“) = TextBox” & (r * 4 + c).ToString()DTE.ActiveDocument.Selection.NewLine()Next c
Next rEnd Sub
The following code shows the result added to the form’s Loadevent handler, plus the code that definesthe m_TextBoxesarray:
Public Class Form1Private m_TextBoxes(0 To 4, 0 To 4) As TextBoxPrivate Sub Form1_Load(ByVal sender As System.Object, _ByVal e As System.EventArgs) Handles MyBase.Loadm_TextBoxes(0, 0) = TextBox0
m_TextBoxes(0, 1) = TextBox1m_TextBoxes(0, 2) = TextBox2m_TextBoxes(0, 3) = TextBox3m_TextBoxes(1, 0) = TextBox4m_TextBoxes(1, 1) = TextBox5m_TextBoxes(1, 2) = TextBox6m_TextBoxes(1, 3) = TextBox7m_TextBoxes(2, 0) = TextBox8m_TextBoxes(2, 1) = TextBox9m_TextBoxes(2, 2) = TextBox10m_TextBoxes(2, 3) = TextBox11m_TextBoxes(3, 0) = TextBox12
Trang 14m_TextBoxes(3, 1) = TextBox13m_TextBoxes(3, 2) = TextBox14m_TextBoxes(3, 3) = TextBox15End Sub
For example, the following code comments out a selected section of code by placing it in an #If
#End Ifblock It first prompts you for the name of the variable to use in the #Ifstatement It composesthe block by concatenating the #Ifstatement, the currently selected text, and the #End Ifstatement Itthen uses the current selection object’s Insertmethod to replace the selected text with the block
‘ Surround the selected code with an #If #End If block
Public Sub PoundIfOut()
‘ Get the variable name
Dim variable_name As String = InputBox(“Variable Name”, “Variable Name”, “”)
If variable_name.Length < 1 Then Exit SubDim sel As EnvDTE.TextSelection = DTE.ActiveDocument.SelectionDim txt As String = “#If “ & variable_name & “ Then” & vbCrLf & sel.Text
If Not txt.EndsWith(vbCrLf) Then txt &= vbCrLftxt &= “#End If ‘ “ & variable_name & vbCrLf
‘ Replace the selected text with the result
sel.Insert(txt, vsInsertFlags.vsInsertFlagsContainNewText)End Sub
The following code shows a sample result Here I selected the two lines used by the MessageBoxment, ran the macro, and entered the variable name SHOW_MESSAGESwhen prompted
state-#If SHOW_MESSAGES Then
MessageBox.Show(“I’ve been commented out!”, “Commented”, _MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
#End If ‘ SHOW_MESSAGES
In this example, it wouldn’t have been hard to just type in the #Ifand #End Ifstatements, but this is ahandy macro when you want to quickly comment out a large block of code Simply select the code, runthe macro, and enter a variable name
The following macro uses a similar technique to place code in a new region It starts by prompting youfor the region’s name It concatenates a #Regionstatement, the selected code, and an #End Regionstate-ment, and then inserts the result into the code
‘ Put the selected code in a region
Public Sub MakeRegion()
Trang 15‘ Get the region name.
Dim region_name As String = InputBox(“Region Name”, “Region Name”, “”)
If region_name.Length < 1 Then Exit Sub
‘ Compose the new text
Dim sel As EnvDTE.TextSelection = DTE.ActiveDocument.SelectionDim txt As String = _
“#Region “”” & region_name & “””” & vbCrLf & _sel.Text
If Not txt.EndsWith(vbCrLf) Then txt &= vbCrLftxt &= “#End Region ‘ “ & region_name
‘ Replace the selected text with the result
sel.Insert(txt, vsInsertFlags.vsInsertFlagsContainNewText)End Sub
The following macro shows how you can loop through an array of names to make property proceduresfor each Writing each of these by hand, even using copy and paste or code snippets, would be tiresome
‘ Make a series of property procedures for contact information
Public Sub MakeContactInfoProperties()Dim property_names() As String = { _
“FirstName”, “LastName”, “Street”, “Street2”, “City”, “State”, “Zip”, _
“WorkPhone”, “HomePhone”, “Email”, “WebPage”}
Dim txt As String = “”
For Each property_name As String In property_namestxt &= “Private m_” & property_name & “ As String = “”””” & vbCrLftxt &= “Public Property “ & property_name & “() As String” & vbCrLftxt &= vbTab & “Get” & vbCrLf
txt &= vbTab & vbTab & “Return m_” & property_name & vbCrLftxt &= vbTab & “End Get” & vbCrLf
txt &= vbTab & “Set(ByVal value As String)” & vbCrLftxt &= vbTab & vbTab & “m_” & property_name & “ = value” & vbCrLftxt &= vbTab & “End Set” & vbCrLf
txt &= “End Property” & vbCrLf & vbCrLfNext property_name
‘ Replace the selected text with the result
Dim sel As EnvDTE.TextSelection = DTE.ActiveDocument.Selectionsel.Insert(txt, vsInsertFlags.vsInsertFlagsContainNewText)End Sub
When a macro inserts code, the code editor does not automatically reformat the code to fix its tion These macros finish with the new code selected If you press the Tab key immediately after runningthe macros, the code editor will fix the code’s indentation
indenta-Unfortunately, the extensibility object model is enormous (too big to cover here), extremely complicated,and not very well-documented Look in the online help’s index for “extensibility” for information aboutthe classes that represent the IDE and the loaded project
Though the documentation isn’t great, Microsoft has provided a large number of sample macros thatyou can study when designing your own macros
Trang 16Using Sample Macros
Notice the Samplesproject in the Project Explorer shown in Figure 8-8 and in the Macro Explorer shown
in Figure 8-7 That project contains sample macros provided by Microsoft that demonstrate ratheradvanced techniques The samples demonstrate various techniques for manipulating the developmentenvironment For example, they show how to:
❑ Change the code editor’s font size
❑ Change the code editor’s colors
❑ Add the files in a directory sub-tree to a solution
❑ Print all open documents
❑ Comment out C++ code with #ifdefstatements
❑ Save and restore window layouts
❑ Turn line numbers and word wrap on and off
❑ Catch events raised by the project, documents, windows, the task list, and so forth
❑ Convert a macro project into an add-in
❑ Add comments to all functions in a file
❑ List macros, breakpoints, modified files, and so forth
❑ Evaluate an expression
❑ Dump all threads’ stacks
❑ List the languages that the debugger supports (Visual Basic, C#, C++, VJ#, and so on)
❑ Save a backup of the current document
To learn more about the samples in the online help, look in the index for “macros [Visual Studio
Macros]” and select the sub-topic “samples.”
Customizing Visual Studio
Special-purpose macros (such as MakeContactInfoPropertiesshown earlier in this chapter) aremacros you will probably run only once or twice In those cases, it’s easy enough to run the macro bydouble-clicking it in the Macro Explorer, or by opening it in the Macro IDE and selecting the Debugmenu’s Run command
Other macros (such as PoundIfOutand MakeRegion) can be useful on many occasions In those cases,you may want to make the macro more accessible by customizing Visual Studio
In Visual Studio, select the Tools menu’s Customize command to display the Customize dialog shown inFigure 8-9 On the Toolbars tab, you can click the New button to make a toolbar to hold buttons forlaunching your macros
Trang 17Figure 8-9: You can use the Toolbars tab’s New button to make a new toolbar toprovide easy access to macros.
On the Commands tab shown in Figure 8-10, scroll the list on the left down and select the Macros entry.Then, click and drag macros from the list on the right onto menus and toolbars
Figure 8-10: The Commands tab lets you drag commands (including macros) ontomenus and toolbars