Issue
How do I arrange to detect selection of component occurrences in an assembly in a non-modal fashion? i.e. I want to detect the selection of parts or sub assemblies when an assembly is active,
without having to issue a command to start the selection process.
When an assembly is not active I don't want to intercept any selection events.
Solution
There are two phases to this solution..
(1) We need to react to component selection events in an Assembly context. We need to be able to enable/disable this behavior programmatically.
(2) We need to detect when an assembly is active. When an assembly is active we need to enable detection of selection events. When no assembly is active we need to disable detection of selection events.
To satisfy these two goals we need to provide two custom event sinks:
(1) DocumentEventsSink
In this event sink we implement OnChangeSelectSet().
This method is called whenever the selection set changes (something is added to selection, or something is removed). We install appropriate logic to trap changes to the selection set that indicate that a component occurrence has been selected/deselected. We can then interrogate the selection set to determine the selected items.
(2) ApplicationEventsSink
In this event sink we implement OnActivateDocument, and OnDeactivateDocument. We install appropriate logic to trap Assembly documents being activated/deactivated.
When an Assembly document is activated we register our DocumentEventsSink (outlined above). When an Assembly document is deactivated we unregister our DocumentEventsSink.
Note: the DocumentsEventSink also has OnActivate(), and OnDeactivate() methods.
These methods are called when a document is activated or deactivated. However they are not currently
called when a new document is created - hence we need to use ApplicationEventsSink to manipulate the context of multi-documents.
Public oAppEvents As ApplicationEvents
Public oDocEvents As DocumentEvents
' start Application events and
' document events for the current document
Private Sub startAppEvents()
_InvApplication = _
Runtime.InteropServices.Marshal. _
GetActiveObject("Inventor.Application")
oAppEvents = _InvApplication.ApplicationEvents
AddHandler oAppEvents.OnActivateDocument,
AddressOf OnActivateDocument
AddHandler oAppEvents.OnDeactivateDocument,
AddressOf OnDeactivateDocument
If Not _InvApplication.ActiveDocument is Nothing then
oDocEvents =
_InvApplication.ActiveDocument.DocumentEvents
AddHandler oDocEvents.OnChangeSelectSet,
AddressOf OnChangeSelectSet
End If
End Sub
' stop the events
Private Sub endAppEvents()
' stop document event
If Not oDocEvents is Nothing then
RemoveHandler oDocEvents.OnChangeSelectSet,
AddressOf OnChangeSelectSet
oDocEvents = Nothing
End If
'stop application event
If Not oAppEvents is Nothing then
RemoveHandler oAppEvents.OnActivateDocument,
AddressOf OnActivateDocument
RemoveHandler oAppEvents.OnDeactivateDocument,
AddressOf OnDeactivateDocument
oAppEvents = Nothing
End If
End Sub
' ApplicationEvents.OnActivateDocument
Public Sub OnActivateDocument(
ByVal DocumentObject As Inventor._Document,
ByVal BeforeOrAfter As Inventor.EventTimingEnum,
ByVal Context As Inventor.NameValueMap,
ByRef HandlingCode As Inventor.HandlingCodeEnum)
If BeforeOrAfter = EventTimingEnum.kAfter then
‘the new document is activated
If Not _InvApplication.ActiveDocument is Nothing then
oDocEvents =
_InvApplication.ActiveDocument.DocumentEvents
AddHandler oDocEvents.OnChangeSelectSet,
AddressOf OnChangeSelectSet
End If
End If
End Sub
'ApplicationEvents.OnactivateDocument
Public Sub OnDeactivateDocument(
ByVal DocumentObject As Inventor._Document,
ByVal BeforeOrAfter As Inventor.EventTimingEnum,
ByVal Context As Inventor.NameValueMap,
ByRef HandlingCode As Inventor.HandlingCodeEnum)
If BeforeOrAfter = EventTimingEnum.kBefore then
' the old document is to deactivated
If Not oDocEvents is Nothing then
RemoveHandler oDocEvents.OnChangeSelectSet,AddressOf OnChangeSelectSet
oDocEvents = Nothing
End If
End If
End Sub
' DocumentEvents.OnChangeSelectSet
Public Sub OnChangeSelectSet(
ByVal BeforeOrAfter As Inventor.EventTimingEnum,
ByVal Context As Inventor.NameValueMap,
ByRef HandlingCode As Inventor.HandlingCodeEnum)
If BeforeOrAfter = EventTimingEnum.kAfter then
If _InvApplication.ActiveDocument.SelectSet.Count >0
then
Dim obj As Object =
_InvApplication.ActiveDocument.SelectSet(1)
'do your work
End If
End If
End Sub