© 2004 Microsoft Corporation. All rights reserved.

Figure 4 Some Plug-in Types

Plug-in Type
Insertion Point
Description
FileMenu
Follow New in the menu File
Adds a new functionality to the File menu at the same logical level as New or Open. No context information is strictly required.
DocumentFileMenu
Follow Save As in the menu File
A new function is added to the File menu and set to work on the active MDI child. Requires a child document to be enabled. The context information consists of the document window or some of its class members.
DocumentContextMenu
Appended to the context menu
Similar to DocumentMenuFile, but the new function shows up in the document's context menu.
WindowMenu
Appended to the menu Window
Adds a new functionality to the Window menu. No context information is strictly required.
HelpMenu
Appended to the menu Help
Adds to the Help menu. No context information required.
NewPopupMenu
Inserted where specified in the menu bar
Adds a new custom popup menu. No context information required.

Figure 5 Plug-in Repository in XML

  <?xml version="1.0" encoding="Windows-1252" ?>
<!-- XML CHART Registered plug-ins -->
<AppPlugIns>
    <FileMenu>
        <Text>New from Query...</Text>
        <Assembly>ExpowarePlugIns</Assembly>
        <Class>Expoware.NewFromQuery</Class>
    </FileMenu>
    <FileMenu>
        <Text>-</Text>
    </FileMenu>
    <DocumentFileMenu>
        <Text>Send through email</Text>
        <Assembly>ExpowarePlugIns</Assembly>
        <Class>Expoware.SendThroughEmail</Class>
    </DocumentFileMenu>
    <DocumentContextMenu>
        <CheckItem>True</CheckItem>
        <Text>View as a Pie Chart</Text>
        <Assembly>AnotherCompanyPlugIns</Assembly>
        <Class>AnotherCompany.PieChart</Class>
    </DocumentContextMenu>    
    <WindowMenu>
        <Text>-</Text>
    </WindowMenu>
    •••
</AppPlugIns>

Figure 6 Merging Menus

  Private Sub SetupMenu()
   Dim mnuPopup, mnuItem As MenuItem

   ' Access the menu config file 
   Dim ds As DataSet = New DataSet()
   If Not File.Exists(CONFIGFILE) Then
        Return
   End If
   ds.ReadXml(CONFIGFILE)

   ' Add dynamic items to existing popup menus
   AddFileMenuPlugIns(ds)
   AddDocumentFileMenuPlugIns(ds)
   AddWindowMenuPlugIns(ds)
   AddHelpMenuPlugIns(ds)

   ' Add new popup menus
   AddNewPopupMenuPlugIns(ds)
End Sub

' All AddXXXPlugIns routines have a similar structure
'
Private Sub AddFileMenuPlugIns(ByVal ds As DataSet)
   ModifyAppMenu(ds, "MenuFile", mnuFileNew.Index + 1, mnuPopupFile)
End SubPrivate Sub ModifyAppMenu(ByVal pluginType As PlugInType, _
    ByVal tableName As String, _
    ByVal menuIndex As Integer, _
    ByVal mnuInsertPoint As MenuItem)
   Dim mnuPopup, mnuItem As PluggableMenuItem
   Dim config As DataTable
   Dim menuExt As DataRow

   config = ds.Tables(tableName)
   If config Is Nothing Then
        Return
   End If

   Dim index As Integer = menuIndex   
   For Each menuExt In config.Rows
      mnuItem = New PluggableMenuItem(menuExt("Text"), _
        AddressOf StdOnClickHandler)
      mnuItem.AssemblyName = menuExt("Assembly")
      mnuItem.ClassName = menuExt("Class")
      mnuItem.PlugInType = pluginType

      mnuInsertPoint.MenuItems.Add(index, mnuItem)
      index += 1
   Next
 End Sub

Figure 7 Interfaces

  ' Plug-in interface for FileMenu plug-in components
Public Interface IXmlChartFileMenuPlugIn
    Sub PerformAction(ByVal f As BWSLib.XmlChartMainForm)
End Interface

' Plug-in interface for DocumentFileMenu plug-in components
Public Interface IXmlChartDocumentFileMenuPlugIn
    Sub PerformAction(ByVal docWindow As XmlChartDocument)
End Interface

' Plug-in interface for DocumentContextMenu plug-in components
Public Interface IXmlChartDocumentContextMenuPlugIn
    Sub PerformAction(ByVal docWindow As XmlChartDocument)
End Interface

' Plug-in interface for WindowMenu plug-in components
Public Interface IXmlChartWindowMenuPlugIn
    Sub PerformAction(ByVal f As BWSLib.XmlChartMainForm)
End Interface

' Plug-in interface for HelpMenu plug-in components
Public Interface IXmlChartHelpMenuPlugIn
    Sub PerformAction(ByVal f As BWSLib.XmlChartMainForm)
End Interface

' Plug-in interface for NewPopuMenu plug-in components
Public Interface IXmlChartNewPopupMenuPlugIn
    Sub PerformAction(ByVal f As BWSLib.XmlChartMainForm)
End Interface

Figure 9 Invoking the Plug-in Class

  Private Sub StdOnClickHandler(ByVal sender As Object, ByVal e As EventArgs)
   Dim mnuItem As PluggableMenuItem
   mnuItem = CType(sender, PluggableMenuItem)

   Dim a As String = mnuItem.AssemblyName
   Dim c As String = mnuItem.ClassName

   ' Pick up the right plug-in class and invoke the PerformAction method
   Select Case mnuItem.PlugInType

          Case PlugInType.FileMenu
              Dim o As IXmlChartFileMenuPlugIn
              o = CType(Activator.CreateInstance(a, c).Unwrap(), _
                  IXmlChartFileMenuPlugIn)
              o.PerformAction(Me)
              •••
              o.PerformAction(Me.ActiveMdiChild)

              ' If the menu item is checkable, check it!
              If mnuItem.CheckItem Then
                   mnuItem.Checked = Not mnuItem.Checked
              End If

          Case PlugInType.HelpMenu
              Dim o As IXmlChartHelpMenuPlugIn
              o = CType(Activator.CreateInstance(a, c).Unwrap(), _
                  IXmlChartHelpMenuPlugIn)
              o.PerformAction(Me)
              •••
   End Select
End Sub