Add Button to Context-sensitive Menu Example (VB.NET)
This example shows how to add:
- button to a face's context-sensitive menu
in a part.
- shortcut menu for that
button.
'---------------------------------------------------------------------------
' Preconditions:
' 1. Verify that the SOLIDWORKS API SDK add-in templates for your version
' of Microsoft Visual Studio are installed.
' 2. In Microsoft Visual Studio, create a Visual Basic project using the
' SwVBAddin template.
' 3. Name the project AddMenuPopupIconVBNET.
' 4. Copy and paste SwAddin into SwAddin.vb of your project.
' 5. Click Project > AddMenuPopupIconVBNET Properties > Debug.
' 6. Select Start external program and type the pathname to your
' SOLIDWORKS executable.
' 7. Replace the text shown for the imageList array elements
' and smallMainIcon with the pathnames to your image files.
' 8. Press F5 to start debugging this add-in.
'
' Postconditions:
' 1. In SOLIDWORKS, open a part.
' 2. Right-click a face of the part.
' 3. Note the size of the button added by this add-in to the
' context-sensitive menu.
' 4. Click the button added by this add-in to display the shortcut menu.
' 5. Exit SOLIDWORKS.
' 6. Change the size of the text and other items on your computer.
' For example, in Windows 7:
' a. Click Start > Control Panel > Appearance and
' Personalization > Display.
' b. Select a different size.
' c. Click Apply.
' d. Click Log off now.
' e. Log back in.
' 7. Start SOLIDWORKS.
' 8. Repeat steps 1 - 3.
'---------------------------------------------------------------------------
'SwAddin
Imports System
Imports System.Collections
Imports System.Reflection
Imports System.Runtime.InteropServices
Imports SolidWorks.Interop.sldworks
Imports SolidWorks.Interop.swconst
Imports SolidWorks.Interop.swpublished
Imports SolidWorksTools
Imports SolidWorksTools.File
Imports System.Collections.Generic
Imports System.Diagnostics
<Guid("7af58543-3a92-417a-b682-9a3f20465cce")> _
<ComVisible(True)> _
<SwAddin( _
Description:="AddMenuPopupIconVBNET description", _
Title:="AddMenuPopupIconVBNET", _
LoadAtStartup:=True _
)> _
Public Class SwAddin
Implements SolidWorks.Interop.swpublished.SwAddin
#Region "Local Variables"
Dim WithEvents iSwApp As SldWorks
Dim addinID As Integer
Dim openDocs As Hashtable
Dim SwEventPtr As SldWorks
Dim iBmp As BitmapHandler
Dim model As ModelDoc2
Dim frame As IFrame
Dim resultCode As Boolean
Dim registerID As Integer
' Public Properties
ReadOnly Property SwApp() As SldWorks
Get
Return iSwApp
End Get
End Property
ReadOnly Property OpenDocumentsTable() As Hashtable
Get
Return openDocs
End Get
End Property
#End Region
#Region "SolidWorks Registration"
<ComRegisterFunction()> Public Shared Sub RegisterFunction(ByVal t As Type)
' Get Custom Attribute: SwAddinAttribute
Dim attributes() As Object
Dim SWattr As SwAddinAttribute = Nothing
attributes = System.Attribute.GetCustomAttributes(GetType(SwAddin), GetType(SwAddinAttribute))
If attributes.Length > 0 Then
SWattr = DirectCast(attributes(0), SwAddinAttribute)
End If
Try
Dim hklm As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine
Dim hkcu As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.CurrentUser
Dim keyname As String = "SOFTWARE\SolidWorks\Addins\{" + t.GUID.ToString() + "}"
Dim addinkey As Microsoft.Win32.RegistryKey = hklm.CreateSubKey(keyname)
addinkey.SetValue(Nothing, 0)
addinkey.SetValue("Description", SWattr.Description)
addinkey.SetValue("Title", SWattr.Title)
keyname = "Software\SolidWorks\AddInsStartup\{" + t.GUID.ToString() + "}"
addinkey = hkcu.CreateSubKey(keyname)
addinkey.SetValue(Nothing, SWattr.LoadAtStartup, Microsoft.Win32.RegistryValueKind.DWord)
Catch nl As System.NullReferenceException
Console.WriteLine("There was a problem registering this dll: SWattr is null.\n " & nl.Message)
System.Windows.Forms.MessageBox.Show("There was a problem registering this dll: SWattr is null.\n" & nl.Message)
Catch e As System.Exception
Console.WriteLine("There was a problem registering this dll: " & e.Message)
System.Windows.Forms.MessageBox.Show("There was a problem registering this dll: " & e.Message)
End Try
End Sub
<ComUnregisterFunction()> Public Shared Sub UnregisterFunction(ByVal t As Type)
Try
Dim hklm As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine
Dim hkcu As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.CurrentUser
Dim keyname As String = "SOFTWARE\SolidWorks\Addins\{" + t.GUID.ToString() + "}"
hklm.DeleteSubKey(keyname)
keyname = "Software\SolidWorks\AddInsStartup\{" + t.GUID.ToString() + "}"
hkcu.DeleteSubKey(keyname)
Catch nl As System.NullReferenceException
Console.WriteLine("There was a problem unregistering this dll: SWattr is null.\n " & nl.Message)
System.Windows.Forms.MessageBox.Show("There was a problem unregistering this dll: SWattr is null.\n" & nl.Message)
Catch e As System.Exception
Console.WriteLine("There was a problem unregistering this dll: " & e.Message)
System.Windows.Forms.MessageBox.Show("There was a problem unregistering this dll: " & e.Message)
End Try
End Sub
#End Region
#Region "ISwAddin Implementation"
Function ConnectToSW(ByVal ThisSW As Object, ByVal Cookie As Integer) As Boolean Implements SolidWorks.Interop.swpublished.SwAddin.ConnectToSW
iSwApp = ThisSW
addinID = Cookie
' Set up callbacks
iSwApp.SetAddinCallbackInfo2(0, Me, addinID)
' Set up the third-party buttons
AddThirdPartyIcon()
' Set up the Event Handlers
SwEventPtr = iSwApp
openDocs = New Hashtable
AttachEventHandlers()
ConnectToSW = True
End Function
Function DisconnectFromSW() As Boolean Implements SolidWorks.Interop.swpublished.SwAddin.DisconnectFromSW
DetachEventHandlers()
System.Runtime.InteropServices.Marshal.ReleaseComObject(iSwApp)
iSwApp = Nothing
' The add-in must call GC.Collect() here to retrieve all managed code pointers
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()
DisconnectFromSW = True
End Function
#End Region
#Region "UI Methods"
Public Sub AddThirdPartyIcon()
Dim iBmp As New BitmapHandler
Dim thisAssembly As Assembly
' Create a button in the context-sensitive menus of faces in parts
frame = SwApp.Frame()
Dim imageList() As String = New String(2) {}
imageList(0) = "Pathname_to_button_nxn_image"
imageList(1) = "Pathname_to_button_nnxnn_image"
imageList(2) = "Pathname_to_button_nnnxnnn_image"
resultCode = frame.AddMenuPopupIcon3(swDocumentTypes_e.swDocPART, swSelectType_e.swSelFACES, "Third-party context-sensitive", addinID, "CSCallbackFunction", "CSEnable", "", imageList)
' Create and register the shortcut menu
registerID = SwApp.RegisterThirdPartyPopupMenu()
' Add a menu break at the top of the shortcut menu
resultCode = SwApp.AddItemToThirdPartyPopupMenu2(registerID, CInt(swDocumentTypes_e.swDocPART), "Menu Break", addinID, "", "", "", "", "", CInt(swMenuItemType_e.swMenuItemType_Break))
' Add a couple of items to the shortcut menu
Dim smallMainIcon As String
smallMainIcon = "Pathname_to_shortcut_button_image"
resultCode = SwApp.AddItemToThirdPartyPopupMenu2(registerID, CInt(swDocumentTypes_e.swDocPART), "Test1", addinID, "TestCallback", "EnableTest", "", "Test1", smallMainIcon, CInt(swMenuItemType_e.swMenuItemType_Default))
resultCode = SwApp.AddItemToThirdPartyPopupMenu2(registerID, CInt(swDocumentTypes_e.swDocPART), "Test4", addinID, "TestCallback", "EnableTest", "", "Test4", smallMainIcon, CInt(swMenuItemType_e.swMenuItemType_Default))
' Add a separator bar to the shortcut menu
resultCode = SwApp.AddItemToThirdPartyPopupMenu2(registerID, CInt(swDocumentTypes_e.swDocPART), "separator", addinID, "", "", "", "", "", CInt(swMenuItemType_e.swMenuItemType_Separator))
' Add another item to the shortcut menu
resultCode = SwApp.AddItemToThirdPartyPopupMenu2(registerID, CInt(swDocumentTypes_e.swDocPART), "Test5", addinID, "TestCallback", "EnableTest", "", "Test5", smallMainIcon, CInt(swMenuItemType_e.swMenuItemType_Default))
' Add a button to a menu bar of the shortcut menu
resultCode = SwApp.AddItemToThirdPartyPopupMenu2(registerID, CInt(swDocumentTypes_e.swDocPART), "", addinID, "TestCallback", "EnableTest", "", "NoOp", smallMainIcon, CInt(swMenuItemType_e.swMenuItemType_Default))
thisAssembly = Nothing
iBmp.Dispose()
End Sub
Function CompareIDs(ByVal storedIDs() As Integer, ByVal addinIDs() As Integer) As Boolean
Dim storeList As New List(Of Integer)(storedIDs)
Dim addinList As New List(Of Integer)(addinIDs)
addinList.Sort()
storeList.Sort()
If Not addinList.Count = storeList.Count Then
Return False
Else
For i As Integer = 0 To addinList.Count - 1
If Not addinList(i) = storeList(i) Then
Return False
End If
Next
End If
Return True
End Function
#End Region
#Region "Event Methods"
Sub AttachEventHandlers()
AttachSWEvents()
' Listen for events on all currently open documents
AttachEventsToAllDocuments()
End Sub
Sub DetachEventHandlers()
DetachSWEvents()
' Close events on all currently open documents
Dim docHandler As DocumentEventHandler
Dim key As ModelDoc2
Dim numKeys As Integer
numKeys = openDocs.Count
If numKeys > 0 Then
Dim keys() As Object = New Object(numKeys - 1) {}
' Remove all document event handlers
openDocs.Keys.CopyTo(keys, 0)
For Each key In keys
docHandler = openDocs.Item(key)
' Remove the pair from the hash
docHandler.DetachEventHandlers()
docHandler = Nothing
key = Nothing
Next
End If
End Sub
Sub AttachSWEvents()
Try
AddHandler iSwApp.ActiveDocChangeNotify, AddressOf Me.SldWorks_ActiveDocChangeNotify
AddHandler iSwApp.DocumentLoadNotify2, AddressOf Me.SldWorks_DocumentLoadNotify2
AddHandler iSwApp.FileNewNotify2, AddressOf Me.SldWorks_FileNewNotify2
AddHandler iSwApp.ActiveModelDocChangeNotify, AddressOf Me.SldWorks_ActiveModelDocChangeNotify
AddHandler iSwApp.FileOpenPostNotify, AddressOf Me.SldWorks_FileOpenPostNotify
Catch e As Exception
Console.WriteLine(e.Message)
End Try
End Sub
Sub DetachSWEvents()
Try
RemoveHandler iSwApp.ActiveDocChangeNotify, AddressOf Me.SldWorks_ActiveDocChangeNotify
RemoveHandler iSwApp.DocumentLoadNotify2, AddressOf Me.SldWorks_DocumentLoadNotify2
RemoveHandler iSwApp.FileNewNotify2, AddressOf Me.SldWorks_FileNewNotify2
RemoveHandler iSwApp.ActiveModelDocChangeNotify, AddressOf Me.SldWorks_ActiveModelDocChangeNotify
RemoveHandler iSwApp.FileOpenPostNotify, AddressOf Me.SldWorks_FileOpenPostNotify
Catch e As Exception
Console.WriteLine(e.Message)
End Try
End Sub
Sub AttachEventsToAllDocuments()
Dim modDoc As ModelDoc2
modDoc = iSwApp.GetFirstDocument()
While Not modDoc Is Nothing
If Not openDocs.Contains(modDoc) Then
AttachModelDocEventHandler(modDoc)
Else
Dim docHandler As DocumentEventHandler = openDocs(modDoc)
If Not docHandler Is Nothing Then
docHandler.ConnectModelViews()
End If
End If
modDoc = modDoc.GetNext()
End While
End Sub
Function AttachModelDocEventHandler(ByVal modDoc As ModelDoc2) As Boolean
If modDoc Is Nothing Then
Return False
End If
Dim docHandler As DocumentEventHandler = Nothing
If Not openDocs.Contains(modDoc) Then
Select Case modDoc.GetType
Case swDocumentTypes_e.swDocPART
docHandler = New PartEventHandler()
Case swDocumentTypes_e.swDocASSEMBLY
docHandler = New AssemblyEventHandler()
Case swDocumentTypes_e.swDocDRAWING
docHandler = New DrawingEventHandler()
End Select
docHandler.Init(iSwApp, Me, modDoc)
docHandler.AttachEventHandlers()
openDocs.Add(modDoc, docHandler)
End If
End Function
Sub DetachModelEventHandler(ByVal modDoc As ModelDoc2)
Dim docHandler As DocumentEventHandler
docHandler = openDocs.Item(modDoc)
openDocs.Remove(modDoc)
modDoc = Nothing
docHandler = Nothing
End Sub
#End Region
#Region "Event Handlers"
Function SldWorks_ActiveDocChangeNotify() As Integer
' TODO: Add your implementation here
End Function
Function SldWorks_DocumentLoadNotify2(ByVal docTitle As String, ByVal docPath As String) As Integer
' TODO: Add your implementation here
End Function
Function SldWorks_FileNewNotify2(ByVal newDoc As Object, ByVal doctype As Integer, ByVal templateName As String) As Integer
AttachEventsToAllDocuments()
End Function
Function SldWorks_ActiveModelDocChangeNotify() As Integer
' TODO: Add your implementation here
End Function
Function SldWorks_FileOpenPostNotify(ByVal FileName As String) As Integer
AttachEventsToAllDocuments()
End Function
#End Region
#Region " UI Callbacks"
Sub CSCallbackFunction()
resultCode = SwApp.ShowThirdPartyPopupMenu(registerID, 500, 500)
End Sub
Function CSEnable() As Integer
If iSwApp.ActiveDoc Is Nothing Then
CSEnable = 0
Else
CSEnable = 1
End If
End Function
#End Region
End Class