| < Free Open Study > |
|
In Listing 6-2, you will see that I have added a lot of code to the Exec method of the add-in. When the user clicks the WinFormsAutomation menu option, the Exec method will receive control. This method is where the actual demonstration of the Windows Forms automation objects will be executed. Listing 6-2 shows all of the code for the add-in, including the wizard-generated code and the code I have added to demonstrate the use of the many automation objects that I discuss in this chapter. There is a lot of code, so do not be dismayed by the objects and their usage. I discuss each segment of the code as you progress through the remainder of the chapter.
Listing 6-2: Automation Code
Imports Microsoft.Office.Core Imports Extensibility Imports System.Runtime.InteropServices Imports EnvDTE Imports System.ComponentModel.Design Imports System.ComponentModel Imports System.Drawing Imports System.Windows.Forms #Region " Read me for Add-in installation and setup information. " ' When run, the Add-in wizard prepared the registry for the Add-in. ' At a later time, if the Add-in becomes unavailable for reasons such as: ' 1) You moved this project to a computer other than the one it was ' originally created on. ' 2) You chose 'Yes' when presented with a message asking if you wish ' to remove the Add-in. ' 3) Registry corruption. ' you will need to re-register the Add-in by building the ' WinFormsAutomationSetup project ' by right-clicking the project in the Solution Explorer, then ' choosing install. #End Region <GuidAttribute("B404B902-65A3-4335-8BA3-24CE23DA3E24"), ProgIdAttribute("WinFormsAutomation.Connect")> _ Public Class Connect Implements Extensibility.IDTExtensibility2 Implements IDTCommandTarget Dim oVB As EnvDTE.DTE Dim addInInstance As EnvDTE.AddIn Dim CommandObj As Command 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 Try ' remove the add-ins UI menu CommandObj.Delete() Catch e As System.Exception MsgBox("OnDisconnection: " & e.Message) End Try 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) If connectMode = Extensibility.ext_ConnectMode.ext_cm_AfterStartup Or _ connectMode = Extensibility.ext_ConnectMode.ext_cm_Startup _ Then Dim objAddIn As AddIn = CType(addInInst, AddIn) ' When run, the Add-in wizard prepared the registry for the Add-in. ' At a later time, the Add-in or its commands may become ' unavailable for reasons such as: ' 1) You moved this project to a computer other than the one it ' was originally created on. ' 2) You chose 'Yes' when presented with a message asking if ' you wish to remove the Add-in. ' 3) You add new commands or modify commands already defined. ' You will need to re-register the Add-in by building the ' WinFormsAutomationSetup project, ' right-clicking the project in the Solution Explorer, ' and then choosing install. ' Alternatively, you could execute the ReCreateCommands.reg file ' the Add-in Wizard generated in ' the project directory, or run 'devenv /setup' from a command prompt. Try CommandObj = oVB.Commands.AddNamedCommand(objAddIn, _ "WinFormsAutomation", _ "WinFormsAutomation", _ "Executes the command for WinFormsAutomation", _ True, 59, Nothing, 1 + 2) _ '1+2 == vsCommandStatusSupported+vsCommandStatusEnabled CommandObj.AddControl(oVB.CommandBars.Item("Tools")) Catch e As System.Exception MsgBox("OnConnection, Can't Add Command: " & e.Message) End Try End If End Sub "' Exec -- This is the add-in wizard's template function " Here we have placed the WinForms Automation Demo Code Public Sub Exec(ByVal cmdName As String, _ ByVal executeOption As vsCommandExecOption, _ ByRef varIn As Object, _ ByRef varOut As Object, _ ByRef handled As Boolean) _ Implements IDTCommandTarget.Exec handled = False " WinForms Automation Demo Code Dim s As String If (executeOption = vsCommandExecOption. vsCommandExecOptionDoDefault) Then If cmdName = "WinFormsAutomation.Connect.WinFormsAutomation" Then ' if the creation of the project fails, it probably ' means that you have run this test before and you ' merely need to delete the WinFormPrj from wherever ' your default projects are stored... MsgBox("A windows project with one form is about to be created.") Try " Winforms automation sample code starts here... " Create a Windows Forms project and give the " designer focus " uncomment the next line and comment the 2nd line " down to create ' a VC# project instead of a VB project 'Dim templatePath As String = _ ' oVB.Solution.TemplatePath ("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") & _ ' "CSharpEXE.vsz" Dim templatePath As String = _ oVB.Solution.TemplatePath ("{F184B08F-C81C-45f6-A57F- 5ABD9991F28F}" ) & _ "WindowsApplication.vsz" Dim targetDir As String = _ CStr(oVB.Properties("Environment", _ "ProjectsAndSolution") .Item("ProjectsLocation").Value) & _ "\WinFormPrj" oVB.Solution.AddFromTemplate(templatePath, _ targetDir, "WinFormPrj") Catch e As System.Exception MsgBox("You probably need to delete WinFormPrj") Exit Sub End Try MsgBox("The Windows Application Project " & _ has been added to the IDE.") oVB.Windows.Item("Form1.vb [Design]").Activate() " uncomment the next line and comment " the previous line " to work with a VC# form instead of vb 'oVB.Windows.Item("Form1.cs [Design]").Activate() " Get IDesignerHost, the root of the forms " designer object model Dim fdHost As IDesignerHost fdHost = CType(oVB.ActiveWindow.Object, IDesignerHost) " Add two buttons, enumerate and print components. Dim btn1 As IComponent s = fdHost.RootComponent.Site.Name btn1 = fdHost.CreateComponent(fdHost.GetType ("System.Windows.Forms.Button, System.Windows.Forms")) Dim btn2 As IComponent btn2 = fdHost.CreateComponent(fdHost.GetType ("System.Windows.Forms.Button, System.Windows.Forms")) Dim parent As PropertyDescriptor = TypeDescriptor.GetProperties(btn1)("Parent") parent.SetValue(btn1, fdHost.RootComponent) parent.SetValue(btn2, fdHost.RootComponent) ListComponents("form with two buttons...", _ fdHost.Container.Components) " Get the properties of the remaining component, " then print their names Dim pdc As PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(btn1) ListProperties(pdc) " Get and set the value of the size property, " showing values " before and after. Dim pd As PropertyDescriptor pd = pdc("Size") MsgBox("Default Button size = " & _ pd.GetValue(btn1).ToString()) ' resize the button Dim sz As System.Drawing.Size sz = New Size(100, 60) pd.SetValue(btn1, sz) MsgBox("custom Button size = " & _ pd.GetValue(btn1).ToString()) " reposition the button Try pd = pdc("Location") Dim loc As System.Drawing.Point loc = New Point(30, 30) pd.SetValue(btn1, loc) MsgBox("New button location = " & _ pd.GetValue(btn1).ToString()) Catch e As System.Exception MsgBox(e.Message) End Try " add text property Dim s2 As String s = "&Test Button" pd = pdc("Text") s2 = pd.GetValue(btn1).ToString() pd.SetValue(btn1, s) MsgBox("Default Text = " & s2 & Chr(10) & _ "New Text = " & pd.GetValue(btn1).ToString()) " change Name property s = "txtTestButton" pd = pdc("Name") s2 = pd.GetValue(btn1).ToString() pd.SetValue(btn1, s) MsgBox("Default Name = " & s2 & Chr(10) & _ "New Name = " & pd.GetValue(btn1).ToString()) " Then remove one of the components, enumerate " and print again. dfHost.DestroyComponent(btn2) ListComponents("form after removing one button...", fdHost.Container.Components) " Select a component on a form MsgBox("Selecting button component...") Dim sel As ISelectionService sel = CType(fdHost.GetService(Type.GetType ("System.ComponentModel.Design. ISelectionService,System")), _ System.ComponentModel.Design.ISelectionService) sel.SetSelectedComponents(New Object() {btn1}) ' get the count of selected components Dim i As Integer = sel.SelectionCount MsgBox("Selected Component Count = " & CStr(i)) ' loop through the selected component collection ' listing properties Dim ic As IComponent Dim c As Component For Each c In sel.GetSelectedComponents ic = CType(c, IComponent) pdc = TypeDescriptor.GetProperties(ic) pd = pdc("Text") s = pd.GetValue(ic).ToString pd = pdc("Name") s2 = pd.GetValue(ic).ToString MsgBox("Component Text = " & s & Chr(10) & _ "Component Name = " & s2) Next Try 'Access designer properties MsgBox("Accessing designer grid size...") Dim opt As IDesignerOptionService opt = CType(fdHost.GetService(Type.GetType ("System.ComponentModel.Design. IDesignerOptionService,System")), _ System.ComponentModel.Design. IDesignerOptionService) Dim siz As Size = CType(opt.GetOptionValue ("WindowsFormsDesigner\General", "GridSize"), _ Size) MsgBox(siz.ToString()) Catch e As System.Exception MsgBox("failed accessing designer props") MsgBox(e.tostring()) End Try 'Assign event handler to btn1 click Try Dim click As EventDescriptor click = TypeDescriptor.GetEvents(btn1)("Click") Dim eventSvc As IEventBindingService eventSvc = CType(fdHost.GetService (Type.GetType("System.ComponentModel.Design. IEventBindingService,System")), System.ComponentModel.Design. IEventBindingService) Dim clickProp As PropertyDescriptor clickProp = eventSvc.GetEventProperty(click) clickProp.SetValue(btn1, "btnTestButton_OnClick") Catch e As System.Exception MsgBox("assign event handler") MsgBox(e.tostring) End Try ' Link event to component Try Dim addSvc As IComponentChangeService addSvc = CType(fdHost.GetService(Type.GetType ("System.ComponentModel.Design. IComponentChangeService,System")), System.ComponentModel.Design.IComponentChangeService) Catch e As System.Exception MsgBox("hooking comp event") MsgBox(e.tostring) End Try 'Create a menu on the form Try Dim mainMenuComp As IComponent = fdHost.CreateComponent(Type.GetType ("System.Windows.Forms.MainMenu, System.Windows.Forms"), "mainMenu1") Dim fileMenuItemComp As IComponent = _ fdHost.CreateComponent(Type.GetType ("System.Windows.Forms.MenuItem, System.Windows.Forms"), "fileMenuItem") Dim menuItem2Comp As IComponent = fdHost.CreateComponent(Type.GetType ("System.Windows.Forms.MenuItem, System.Windows.Forms"), "mainItem2") Dim menuItem3Comp As IComponent = fdHost.CreateComponent(Type.GetType ("System.Windows.Forms.MenuItem, System.Windows.Forms"), "mainItem3") Dim menuItem4Comp As IComponent = fdHost.CreateComponent(Type.GetType ("System.Windows.Forms.MenuItem, System.Windows.Forms"), "mainItem4") Dim mainMenu1 As MainMenu = CType(mainMenuComp, _ MainMenu) Dim fileMenuItem As MenuItem = _ CType(fileMenuItemComp, MenuItem) Dim menuItem2 As MenuItem = CType(menuItem2Comp, _ MenuItem) Dim menuItem3 As MenuItem = CType(menuItem3Comp, _ MenuItem) Dim menuItem4 As MenuItem = CType(menuItem4Comp, _ MenuItem) fileMenuItem.Text = "&File" menuItem2.Text = "&Edit" menuItem3.Text = "&Open" menuItem4.Text = "&Save" mainMenu1.MenuItems.Add(fileMenuItem) mainMenu1.MenuItems.Add(menuItem2) fileMenuItem.MenuItems.Add(menuItem3) fileMenuItem.MenuItems.Add(menuItem4) Catch e As System.Exception MsgBox("adding menu") MsgBox(e.tostring) End Try handled = True Exit Sub End If End If End Sub Public Sub QueryStatus(ByVal cmdName As String, _ ByVal neededText As _ vsCommandStatusTextWanted, _ ByRef statusOption As vsCommandStatus, _ ByRef commandText As Object) _ Implements IDTCommandTarget.QueryStatus If neededText = _ EnvDTE.vsCommandStatusTextWanted. vsCommandStatusTextWantedNone _ Then If cmdName = _ "WinFormsAutomation.Connect. WinFormsAutomation" _ Then statusOption = CType(vsCommandStatus. vsCommandStatusEnabled + _ vsCommandStatus.vsCommandStatusSupported, _ vsCommandStatus) Else statusOption = _ vsCommandStatus.vsCommandStatusUnsupported End If End If End Sub " ' " ' The following methods were not constructed by the "' add-in wizard "' they provide utility functionality for this winforms "' automation sample. " ' Public Sub ListComponents(ByVal title As String, _ ByVal Components As _ ComponentCollection) Dim comp As Component Dim message As String For Each comp In Components message = message & _ Microsoft.VisualBasic.Constants.vbCrLf + _ comp.ToString() Next MsgBox(title & Microsoft.VisualBasic.Constants.vbCrLf & _ message) End Sub Public Sub ListProperties(ByVal Properties As _ PropertyDescriptorCollection) Dim pd As PropertyDescriptor Dim message As String = "First ten properties..." & _ Microsoft.VisualBasic.Constants.vbCrLf Dim i As Integer For i = 0 To 9 Try message = message & _ Microsoft.VisualBasic.Constants.vbCrLf & _ CType(Properties.Item(i).DisplayName, String) & _ " = " & _ Properties.Item(i).Attributes.ToString Catch e As System.Exception MsgBox(e.Message) End Try Next MsgBox(message) End Sub End Class
In addition to the code added to the Exec method, I have added some additional namespaces, which are boldfaced under the Imports section.
| < Free Open Study > |
|