Generic Addin Framework R2

This framework focuses on authoring SolidWorks-aware .NET User Controls that drop seamlessly into the SolidWorks user interface.

Implementation Details

The solution consists of three libraries: SwAddinBase, SwAddinHelpers and SwAddinHelpersComExtender.

ISwAddin Implementation

SwAddinBase:
  • implements ISwAddin interface methods necessary to connect and disconnect to an instance of SolidWorks.
  • implements ISwAddinBase exposing the addin's SolidWorks instance and UI elements. Every addin component holds a reference to SwAddinBase through this interface. See ISwAddinBase and Composable Parts for more information.
  • inherits ComRegistrableAddinImpl which registers the addin with SolidWorks.

UI Elements

SolidWorks GUI

SolidWorks user defined controls:
  • Task Pane
  • Model View Tab
  • Feature Tree Tab
  • Property Page

All UI elements derive from System.Windows.Forms.UserControl. Each type of UI element listed above has its own type of host. The host is responsible for UI element creation and destruction within SolidWorks and subscription to events. Hosts hold a reference to ISwAddinBase while each user control holds a reference to its host. User controls and their hosts communicate with other controls, hosts and the SolidWorks instance through the ISwAddinBase interface as well as through explicitly exposed parameterless methods marked with the [InvokableMethodAttribute(string FriendlyMethodName)]. The addin is capable of hosting multiple UI element hosts of the same type, however only one instance of a specific user control type is allowed at any given time. (This design limitation decision was made since it did not make sense to have the same user control appearing more than once in the SolidWorks UI.)

The Generic Addin Framework R2 supports user controls in a separate library only. This allows for a more modular design (mef.codeplex.com). After the external control library is compiled, the DLL and TLB files must be placed in the same folder as SwAddinBase and SwAddinHelpers DLLs. When SolidWorks loads the Generic Addin Framework, it imports any types tagged with [Export(typeof(IExternalUserControl))] attribute. The IExternalUserControl interface acts as a proxy, passing the external control type as a dynamic type to the Generic Addin Framework.
Hosts
Documentation Inheritance Chain
Task Pane Host TaskPaneHost:UserControlHostBase:AddinProxy
Model View Tab Host ModelViewTabHost:UserControlHostBase:AddinProxy
Feature Tree Tab Host FeatureViewHost:UserControlHostBase:AddinProxy
Property Page Host PropertyManagerHost:UserControlHostBase:AddinProxy
User Controls
Documentation Inheritance Chain Lifetime
External Task Pane Control TaskPaneControlX:TaskPaneControlBase:UserControlBase:UserControl Addin
External Model View Tab Control ModelViewTabControlX:UserControlBase:UserControl Active Document
External Feature View Tab Control FeatureViewControlX:UserControlBase:UserControl Active Document
External Property Page Control PropertyManagerControlX:ActiveXUserControlBase:UserControlBase.UserControl Addin
External Form Control FormControlX:UserControlBase.UserControl Addin


Exposed Properties:
Property Accessor Description
base._OwnerHost get Access this control's host, SolidWorks instance and other addin elements.
base.SetOwner set Sets this controls owning host. Internally used after a UserControlBase is created by the host and extracted from the appropriate SolidWorks object.

Exposed Methods:
Method Modifier Description
base.ThrowOnOwnerHostSetter() virtual Invoked when the control acquires its owner.
base.Tie(), base.Untie() virtual Invoked by the Feature View and Model View hosts when its user control is created and destroyed. Helpful for subscribing to events.


External User control creation requirements:
  • Assembly must be registered with COM Interop
  • Class must follow the appropriate control's inheritance chain
  • Class must implement IExternalUserControl, returning this as a dynamic type
  • Class must be tagged with
    • [ComVisible(true)]
      • [ComVisible(false)] for Form Controls
    • [ProgId(PROGID)]
    • [Export(typeof(IExternalUserControl))]
    • One of [SwAddinHelpers.Attributes.HostedAsAttribute]
      • [SwAddinHelpers.Attributes.HostedAsTaskpane]
      • [SwAddinHelpers.Attributes.HostedAsFeatureView]
      • [SwAddinHelpers.Attributes.HostedAsModelView]
      • [SwAddinHelpers.Attributes.HostedAsPropertyPage]
      • [SwAddinHelpers.Attributes.HostedAsForm]
  • Class must contain a unique public constant PROGID (public const string PROGID = "SwAddinExternalControl.MySpecialControl1";)
  • Property Page only: Class must contain public constants for height and width of the control at runtime (public const short HEIGHT = 420; public const short WIDTH = 150;)
  • Optional class method attributes:
    • [SwAddinHelpers.Attributes.InvokableMethod(string)]
    • [SwAddinHelpers.Attributes.SinkMethod(SwAddinHelpers.Sinks.enumEventSink, bool)]

Use 'Tools > GAF R-2 Manager' to view the available user controls
addinmgr.jpg
Creating a file named 'manager.debug' in the same folder as the Generic Addin Framework will allow you to selectively load control types for debugging purposes.

Menus

Command and menu item callback methods can be distributed all over your code. The SolidWorks SetAddinCallbackInfo() method receives a target object that contains code generated methods, satisfying callback requirements. These code generated methods act as a proxy between SolidWorks and the real callback methods. This allows you to code your callback methods across classes and across assemblies.

Command/menu callback creation requirements:
  • Class must be tagged with [Export(typeof(IExternalCallback))]
  • Class must implement IExternalCallback, returning this as a dynamic type
    • During callbacks, ISwAddinBase is accessible through the below property implementation:
 public ISwAddinBase OwnerAddin
        {
            get { return (ISwAddinBase)this.GetType().GetField("OwnerAddin").GetValue(this); }
        }
  • Callback methods must be public, return void and must not contain any parameters
  • Enable methods must be public,return int and must not contain any parameters

Command item callback creation requirements:
  • Class must be tagged with [SwAddinHelpers.Attributes.CommandGroupDefinition(...)] attribute for every unique command group present in the class. This ensures that the proper CommandGroup is created prior to adding the command item
  • Optional class method attributes:
    • [SwAddinHelpers.Attributes.CommandItemCallback(...)]
  • Optionally, a command item enable method may exist with the name specified in [SwAddinHelpers.Attributes.CommandItemCallback(...)]

Menu item callback creation requirements:
  • Optional class method attributes:
    • [SwAddinHelpers.Attributes.MenuItemCallback(...)]
  • Optionally, a menu item enable method may exist with the name specified in [SwAddinHelpers.Attributes.MenuItemCallback(...)]

Event Handling

The swAppEventSink class is exposed as a public property through the ISwAddinBase interface. The purpose of the swAppEventSink class is to create/destroy/fire event handlers. SolidWorks exposes application, document and UI element event handlers.
Enum enumEventSink is a user defined enumeration of the available event handlers. More handlers and their logic can be added to the swAppEventSink class and exposed via the SinkMethodAttribute.
Subscription
Host and user control methods tagged with the SinkMethodAttribute will be invoked only after the host has subscribed the method to the appropriate event. Event subscription is currently done by calling each host's SubscribeEvent(enumEventSink, enumEventSubscriptionLevel) method. The enumEventSubscriptionLevel determines whether the event should be tied to a method in the host class or the user control class. All events are unsubscribed during the host Teardown() which is done when the addin is unloaded from SolidWorks. The UnsubscribeEvent(enumEventSink) host method can be called to manually untie event handlers.
Automatic Subscription
During the creation of the user control by its host, any user control method tagged with SinkMethodAttribute where the second parameter is true, will be subscribed upon the creation of the control's host.
Late Subscription
User controls are also capable of late subscription while the host's SubscribeEvent method is called as usual. The Property Page user control, for example, is created only after the Property Page is displayed to the user by calling PropertyManagerPage2.Show(). This call invokes PropertyManagerPage2Handler7.OnActiveXControlCreated(int,bool) at which point the user control can be harvested from PropertyManagerPageActiveX.GetControl(). Late subscription is accomplished by setting the host's IsLateSubscriber property to true. Event subscription is done when the host's GuiControl property is set, such as during a call to PropertyManagerPageActiveX.GetControl().
ActiveModelDocChangePreNotify Event
The ActiveModelDocChangeNotify delegate keeps track of the previous active document while a different document is activated. This is helpful with two things: unsubscription of event handlers from the previously active doument and the addition of a custom active document pre-notification event. For example, the ModelViewTabHost holds a reference to a ModelViewManager on top of which it creates a Model View Tab user control. The ActiveModelDocChangeNotify event causes the user control to be created, while the ActiveModelDocChangePreNotify event causes the user control to be destroyed from the previously active document, referenced by the ModelViewManager.Document property. The effect is that the user control exists only on the active document, and any subscribed events are fired only on the active document. The target method receives a SolidWorksEventArgs parameter which contains user definable information. Two of which are the document title and document creation date. In combination they can be used to determine if the action of the method fired by ActiveModelDocChangePreNotify.

Attributes

Several custom attributes exist to extend the programming model at design time. Attribute Reference
Attribute Parameters Purpose
InvokableMethodAttribute Friendly name of a mehod User control parameterless methods are tagged with this attribute. Tagged methods are visible and invokable through their friendly name through their host. Relevant host methods: GetInvokableMethods() and InvokeMethod(string FriendlyName). Invoke Method Example R2
SinkMethodAttribute enumEventSink event and a boolean Host and user control methods are tagged with this attribute. These methods are invoked when the specified event is fired by SolidWorks. The boolean parameter is used to automatically subscribe events when the external control is created. The method signature must match that of the specific event: Method(object sender, EventArgs e) or Method(object sender, SolidWorksEventArgs e)
HostedAsAttribute see derived classes HostedAsTaskpane, HostedAsFeatureView, HostedAsModelView, HostedAsPropertyPage, HostedAsForm are used to tag external control classes. This attribute is used to determine the host to use when creating the external control.
CommandGroupDefinitionAttribute see code Classes containing command item callbacks are tagged with this attribute. The presence of this attribute allows the addin to create a new CommandGroup so that command items can be added.
CommandItemCallbackAttribute see code Command item callback methods are tagged with this attribute. The attribute specifies the CommandGroup as well as other command item properties.
MenuItemCallbackAttribute see code Same as the CommandItemCallbackAttribute except it is used to tag men item callback methods.

COM Types

It is possible to retrieve the .NET managed type from a COM object using SwAddinHelpersComExtender.GetManagedTypeForSWObject(object, bool) and SwAddinHelpersComExtender.GetManagedTypesForSWObject(object) extension methods. The returned type is a fully qualified interface type from the SolidWorks interop library.

For example, selecting a face in a model and querying the returned value from SelectionMgr.GetSelectedObject() would yield the following IEntity,IFace,IFace2,Entity,Face,Face2. Only the types prefixed with 'I' return a MemberInfo collection by calling GetMembers() on the returned type.





Last edited Jul 8, 2010 at 6:35 PM by fixitchris, version 36

Comments

No comments yet.