EventSample VB for VSTA v 2


posted by Melody
09-02-2008

Downloads: 809
File size: 235kB
Views: 3,502
EventSample VB for VSTA v 2
Filed under: , ,

Overview:

This sample is intended to expose several common tasks in VSTA, including: declaring an object, using and manipulating a form, and handling form events and event args.  This sample contains a very simple object, form, application with a basic VSTA integration, and an add-in.  An EventHelper is used to prevent any errors in add-in event handling.

To run the sample, extract the files, open and build the EventSample solution, then run the setup file included (double click or use the command “cscript SetupEventSample.js” from a command prompt).  Next, open and build the add-in solution included in the Samples folder.  Run the EventSample application, which should now automatically find and load the sample add-in included.

The EventSample application records button clicks and input from a text box in a list box.  The sample add-in responds to mouse clicks on any of the buttons on the form, to adding input through the add button, clearing the display, and selecting the Open button.  Event handling for the Save and Close buttons in the add-in is not implemented.

Included in this sample:

Item

Description

MainForm

Main user form and empty code class.

Program

Starting point in the host application.

MainApplication

Main application class.  All application specific code is here.

MainObject

Main object used by the MainApplication class.  Consists of a string.

EventArgs

Contains class definitions for custom event used by the MainApplication.

EventHelper

Class taken from ShapeApp samples to manage events from the host application and add-ins.

VstaRunTimeIntegration

Class based on the ShapeApp samples which uses the VSTA pipeline to load and manage add-ins.

HostItemProvider

Class based on the ShapeApp samples which allows add-ins to access the host object model.

HostTypeMapProvider

HTMP file generated by ProxyGen and translated into Visual Basic.  Maps the types to canocial names for translation between the host and add-ins.

EventSampleProxy

Proxy file generated by ProxyGen and updated to allow generic event handling.

EventSampleProject1

A sample add-in that interacts with the events of the host application.

 


I)  Declaring Objects in VSTA

VSTA cannot access constructors from the host application.  The constructors included in the proxy file are for internal use only.  To create an object in VSTA, a public method must be available in the add-in entry point, in this case the MainApplication class, which constructs the object, then returns it.  The code below shows an object class, MainObject, the MainApplication class, and an add-in.  In the MainApplication class, the method NewObject is used by the add-in to create a MainObject in the add-in.

''' HOST

''' <summary>

''' Simple object used by the main application.

''' </summary>

Public Class MainObject

 

    ''' <summary>

    ''' Holds a message which is displayed on the main form.

    ''' </summary>

    Private mMessage As String

    Public Property Message() As String

        Get

            Return mMessage

        End Get

        Set(ByVal value As String)

            mMessage = value

        End Set

    End Property

 

    ''' <summary>

    ''' Creates a new MainObject with the message passed in.

    ''' </summary>

    Public Sub New(ByVal messageIn As String)

        Message = messageIn

    End Sub

 

End Class

 

''' HOST

''' <summary>

''' Main class of the application.

''' VSTA entry point.

''' </summary>

Public Class MainApplication

 

    ''' <summary>

    ''' Factory method used to create a new MainObject.

    ''' </summary>

    ''' <remarks>VSTA requires objects to be created on the host side

    ''' using a factory method instead of using the "New" operator</remarks>

    Public Function NewObject(ByVal inMessage As String) As MainObject

        Return New MainObject(inMessage)

    End Function

               

End Class

 

    ''' ADD-IN

    Private Sub AppAddIn_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup

 

        'create a new MainObject

        Dim myObject As MainObject = Me.NewObject("New MainObject for VSTA add-in")

 

    End Sub
II)  Using Forms in VSTA

Forms and other objects under System.Windows.Forms cannot be passed through the proxy layer because they are not serializable.  To include a form, or any System.Windows.Forms object, make it an internal property in the main application and exclude the form’s class in the descriptor file.  The code below demonstrates how to start a windows form based application.  The starting point of the host application, the Program class, contains a MainApplication property.  The MainApplication class contains a MyForm property which is run by the Program class.

''' HOST

''' <summary>

''' Startup object of the host application.

''' </summary>Public Class Program

 

    <STAThread()> _

    Shared Sub Main()

 

        'prepare to use forms

        Application.EnableVisualStyles()

        Application.SetCompatibleTextRenderingDefault(False)

 

        'create the application

        Dim thisApplication As MainApplication = New MainApplication()

 

        'run the form

        Application.Run(thisApplication.MyForm)

 

    End Sub

 

End Class

 

''' HOST

''' <summary>

''' Main class of the application.

''' VSTA entry point.

''' </summary>

Public Class MainApplication

 

    ''' <summary>

    ''' Form used internally only.

    ''' </summary>

    Private mMyForm As MainForm

    Friend ReadOnly Property MyForm() As MainForm

        Get

            Return mMyForm

        End Get

    End Property

 

 

End Class


III)  Manipulating a form in VSTA

With the form set as an internal property in the MainApplication class, VSTA cannot directly interact with the form or its controls.  To interact with these, the AddInEntryPoint (in this case the MainApplication class) must contain public methods which handle these interactions.  The code below shows the MainApplication’s addTextToListBox method which takes in a string and adds it to the list box lstDisplay contained on the form.  The add-in calls this method and the string passed in from the add-in is displayed in the list box on the form.

''' HOST

''' <summary>

''' Main class of the host application.

''' VSTA entry point.

''' </summary>

Public Class MainApplication

 

    Public Sub addTextToListBox(ByVal message As String)

        'display the message in the list box

        MyForm.lstDisplay.Items.Add(message)

    End Sub

 

End Class

 

    ''' ADD-IN

    Private Sub AppAddIn_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup

 

        'add a message to the list box

        addTextToListBox("Message from VSTA add-in")

    End Sub
IV)  Form Events in VSTA

In order for an add-in to catch an event on a form, the host application must catch the event and fire a public event that VSTA can see.  In the code below, the constructor of the MainApplication calls the method HookUpEvents which associates a method in the host application, DisplayClear, with an event generated by the form, a button click.  The method in the host application hooked up to this form event, DisplayClear, fires the public event, DisplayClearedEvent, which VSTA can see.  The add-in hooks up a method, AddIn_DisplayClear, with the event and displays a line of text on the form.

Note: When firing events accessible from VSTA it is important to use the host application (or object within the host application) as the sender, by specifying “me” (“this” in C#).  Using the original sender will not work. 

''' HOST

''' <summary>

''' Main class of the host application.

''' VSTA entry point.

''' </summary>

Public Class MainApplication

 

    ''' <summary>

    ''' Prepares the host application to run. 

    ''' Sets up the list of objects and the form.

    ''' Hooks up form events to methods that will raise VSTA visible events.

    ''' </summary>

    Public Sub New()

 

        'instantiate the form and lis tof messages

        mMyForm = New MainForm

        mMyObjects = New List(Of MainObject)

 

        'hook up the event handling to the form

        HookUpEvents()

 

    End Sub

 

    ''' <summary>

    ''' Event raised when the display is cleared

    ''' </summary>

    Public Event DisplayClearedEvent As EventHandler

 

    ''' <summary>

    ''' Associates form events with methods that will raise

    '''  VSTA visible events.

    ''' </summary>

    Private Sub HookUpEvents()

 

        'Event handling for the form, not exposed to VSTA

        '   VSTA accessable events are raised in the methods hooked into

        AddHandler MyForm.cmdClear.Click, AddressOf RaiseDisplayClear

 

    End Sub

 

    ''' <summary>

    ''' Raises the DisplayClearedEvent visible to VSTA

    ''' </summary>

    ''' <remarks>Notice the event delegate passed to the EventHelper is EventNameEvent not EventName. 

    ''' This is due to VB syntax.</remarks>

    Private Sub RaiseDisplayClear()

        EventHelper.Invoke(DisplayClearedEventEvent, Me, EventArgs.Empty)

    End Sub

 

End Class

 

    ''' ADD-IN

    Private Sub AppAddIn_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup

        AddHandler DisplayClearedEvent, AddressOf AddIn_DisplayClear

    End Sub

 

    'manually added event handling

    Private Sub AddIn_DisplayClear()

        addTextToListBox("Add-in saw display clear")

    End Sub

 

    'event handling added through the drop down menus

Private Sub AppAddIn_DisplayClearedEvent(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.DisplayClearedEvent

        addTextToListBox("Add-in saw display clear (twice)")

    End Sub


V)  Using EventArgs in VSTA

Like forms, EventArgs based on the System.Windows.Forms class cannot be passed between the host application and add-ins because they are not serializable.  One work around for this is to use custom event args.  The custom event args should have serializable public properties to hold information from the event args based on System.Windows.Forms.  Below is the ButtonClickEventArgs class is used in place of System.Windows.Forms.MouseEventArgs to pass information about button clicks on the form to the add-ins.

''' HOST

''' <summary>

''' Custom event args to hold button click information

''' to expose to VSTA.

''' </summary>

''' <remarks>This wrapper class is used to pass information instead of

'''  passing the MouseEventArgs directly because System.Windows.Forms is

'''  not serializable therefore cannot be passed.</remarks>

Public Class ButtonClickEventArgs

    Inherits EventArgs

 

    ''' <summary>

    ''' Name of the button which was clicked

    ''' </summary>

    Public ReadOnly Property ButtonName() As String

        Get

            Return mButtonName

        End Get

    End Property

    Private mButtonName As String

 

    ''' <summary>

    ''' Which mouse button was used- right or left.

    ''' </summary>

    Public ReadOnly Property MouseButton() As String

        Get

            Return mMouseButton

        End Get

    End Property

    Private mMouseButton As String

 

    ''' <summary>

    ''' Creates a new ButtonClickEventArgs storing which button was clicked

    '''  and which mouse button was used.

    ''' </summary>

    Public Sub New(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)

 

        'determine which button was clicked and with which mouse button

        Dim Button As System.Windows.Forms.Button = CType(sender, System.Windows.Forms.Button)

        mButtonName = Button.Name

        mMouseButton = e.Button.ToString()

 

    End Sub

 

End Class

''' HOST

''' <summary>

''' An event handler type for button clicks.

''' </summary>

Public Delegate Sub ButtonClickEventHandler(ByVal sender As Object, ByVal e As ButtonClickEventArgs)

 

''' HOST

''' <summary>

''' Main class of the host application.

''' VSTA entry point.

''' </summary>

Public Class MainApplication

 

    ''' <summary>

    ''' Prepares the host application to run. 

    ''' Sets up the list of objects and the form.

    ''' Hooks up form events to methods that will raise VSTA visible events.

    ''' </summary>

    Public Sub New()

 

        'instantiate the form and lis tof messages

        mMyForm = New MainForm

        mMyObjects = New List(Of MainObject)

 

        'hook up the event handling to the form

        HookUpEvents()

 

    End Sub

 

    ''' <summary>

    ''' Event raised when any button is selected

    ''' </summary>

    ''' <remarks>Exposed to VSTA and not used by the host</remarks>

    Public Event ButtonClickEvent As ButtonClickEventHandler

 

    ''' <summary>

    ''' Associates form events with methods that will raise

    '''  VSTA visible events.

    ''' </summary>

    Private Sub HookUpEvents()

 

        'Event handling for all buttons- any button click raises

        'the ButtonClickEvent which is exposed to VSTA and called

        'in RecordClick

        AddHandler MyForm.cmdOpen.Click, AddressOf RecordClick

 

    End Sub

 

    ''' <summary>

    ''' Records any button clicks in the display.   

    ''' </summary>

    ''' <remarks>Raises the ButtonClickEvent which is

    ''' visible to VSTA.</remarks>

    Private Sub RecordClick(ByVal sender As Object, ByVal e As EventArgs)

 

        'raise the event exposed to VSTA for any button click

        EventHelper.Invoke(ButtonClickEventEvent, Me, _

             New ButtonClickEventArgs(sender, CType(e, _

                 System.Windows.Forms.MouseEventArgs)))

 

    End Sub

End Class

 

''' ADD-IN

    Private Sub AppAddIn_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup

 

        AddHandler ButtonClickEvent, AddressOf AddIn_ButtonClick

 

    End Sub

 

    Private Sub AddIn_ButtonClick(ByVal sender As Object, ByVal e As ButtonClickEventArgs)

        'determine which button was pressed

        Dim buttonName As String = e.ButtonName

 

        'determine the mouse button that was used

        Dim mouseButton As String = e.MouseButton

 

        'display a message that shows the add-in found the above info

        addTextToListBox("VSTA add-in caught button click" & vbNewLine & _

                         "Button: " & buttonName & vbNewLine & _

                         "Mouse Button: " & mouseButton)

    End Sub

      

 

 

Copyright Summit Software Company, 2008. All rights reserved.