Plug-In Modules in SDK 2015

From Vectorworks Developer
Jump to: navigation, search

.SDK|SDK ..SDK:Types|SDK Types ..SDK:Using the SDK|Using the SDK ..VCOM:VCOM (Vectorworks Component Object Model)|VCOM Basics ..VCOM:Class Reference|VCOM Class Reference

This document explain the changes for Plug-in Modules in the SDK 2015. It uses comparison with existing plug-in to demonstrate the changes required for existing plug-in to be converted to SDK 2015.

This document presumes that the reader is familiar with VCOM and plug-in module extensions.

All these changes are driven by the need for the SDK 2015 to be 64-bit compatible.

Plug-Ins 64-Bit - Transition Guide


The plug-in module main function

Existing plug-ins have the following main function:

extern "C" long GS_EXTERNAL_ENTRY plugin_main(long action, void* pInfo, long& ioData, CallBackPtr cbp)

New plug-ins must have the main function defined like this:

extern "C" Sint32 GS_EXTERNAL_ENTRY plugin_module_main(Sint32 action, void* moduleInfo, const VWIID& iid, IVWUnknown*& inOutInterface, CallBackPtr cbp)

The changes to the main function are:

  • The name has changed. This will ensure old plug-ins, compiled with main function with different parameters, not working in Vectorworks 2015.
  • action parameter have the same meaning and it only changed type to be safe for 64-bit.
  • moduleInfo parameter is the equivalent of the pInfo parameter during the kVCOMRegisterInterfaces action event. Now it always identifiers the current plug-in module being executed.
  • iid parameter was represented as pInfo parameter during kVCOMQueryInterface and kVCOMReleaseInterface action events. Now it always identifiers Interface Identifier when needed.
  • inOutInterface parameter is the equivalent of the ioData parameter. It is used for input and output of interface instances during kVCOMQueryInterface and kVCOMReleaseInterface action events.
  • cbp parameter is a callback pointer for the plug-in to communicate with Vectorworks. There is no changes in the meaning of this parameter.

All the macros used to register and manage VCOM interfaces have been updated to support the changes. Here is an example of a plug-in main function for SDK 2015:

// Entry point of the module plug-in for Vectorworks
// More info at:
extern "C" Sint32 GS_EXTERNAL_ENTRY plugin_module_main(Sint32 action, void* moduleInfo, const VWIID& iid, IVWUnknown*& inOutInterface, CallBackPtr cbp)
       // initialize VCOM mechanizm
       ::GS_InitializeVCOM( cbp );
       // init legacy Global Callback Pointer
       // for support of legacy GS_ functions
       gCBP   = cbp;
       { // Init gSDK
              usingnamespace VectorWorks;
              VCOMPtr<ISDK> localSDK( IID_SDK );
              gSDK   = localSDK;
       Sint32 reply  = 0L;
       usingnamespace VWFC::PluginSupport;
       REGISTER_Extension<TesterModule::CExtTool>( GROUPID_ExtensionTool, action, moduleInfo, iid, inOutInterface, cbp, reply );
       REGISTER_Extension<TesterModule::CExtMenu>( GROUPID_ExtensionMenu, action, moduleInfo, iid, inOutInterface, cbp, reply );
       REGISTER_Extension<TesterModule::CExtObj>( GROUPID_ExtensionParametric, action, moduleInfo, iid, inOutInterface, cbp, reply );
       REGISTER_Extension<TesterModule::CExtVSFuncs>( GROUPID_ExtensionVSFunctions, action, moduleInfo, iid, inOutInterface, cbp, reply );
       return reply; 

Extension eventing

The ILegacyEventSink interface has been removed. This was the interface that contained the main event function, which looked like that:

virtual long VCOM_CALLTYPE LegacyMain(long action, long message1, long message2) = 0;

There are two changes that were made for the extension eventing:

  • The ILegacyEventSink was removed and substituted with four interfaces for each type of extension: IMenuEventSink, IParametricEventSink, IToolEventSink, and IVSFunctionsEventSink
  • There is still one main function for the events inside the new interfaces, but its parameters are strictly typed for each extension type.

These change is implemented inside VWFC, so if your extensions use VWFC classes VWMenu_EventSink, VWParametric_EventSink, VWTool_EventSink, and VWVSFunctions_EventSink, there should not be any changes needed for your plugins as they are reflected internally.


virtual Sint32 VCOM_CALLTYPE Execute(MenuMessage* message) = 0;


virtual Sint32 VCOM_CALLTYPE Execute(ParametricMessage* message) = 0;


virtual Sint32 VCOM_CALLTYPE Execute(ToolMessage* message) = 0;


virtual Sint32 VCOM_CALLTYPE Execute(Sint32 action, PluginLibraryArgTable* argumentTable) = 0;

The new Execute functions accept a base structure type that represents the message and this structure carries the action identifier. Then for each message there is a separate structure type that carries information about the message. For comparison older event handlers must recognize the event by action and they cast generic long numbers into appropriate data for the message.

Migrating you code to the new event sinks

Event though there are new structures representing the messages, there is a direct relation between the old constants and the new data structures, so for the most part translation requires just change of types.

Here is a very simple example of ILegacyEventSink of a menu command that will be translated over to SDK 2015.

The old code:

class CMyMenuCommand_EventSink : public ILegacyEventSink
       virtual long VCOM_CALLTYPE LegacyMain(long action, long message1, long message2)
              long result = 0;
              switch ( action )
                     case kMenuDoInterface:
                           MenuChunkInfo*            chunkInfo = (MenuChunkInfo*) message;
                           RunMyMenuCode( chunkInfo->chunkIndex );
                     } break;
              return result;

And here is the new converted code. Note that it uses action again, but this time the constant for the action is inside the data structure associated with this event. At the end of this document is a table with all events and their corresponding structures.

class CMyMenuCommand_EventSink : public IMenuEventSink
       virtual Sint32 VCOM_CALLTYPE Execute(MenuMessage* message)
              long result = 0;
              switch ( message->fAction )
                     case MenuDoInterfaceMessage::kAction:
                           MenuDoInterfaceMessage*  chunkInfo = dynamic_cast<MenuDoInterfaceMessage*>( message );
                           RunMyMenuCode( chunkInfo->chunkIndex );
                     } break;
              return result;


Note that in this example the type MenuDoInterfaceMessage that corresponds to the constant is actually deriving from MenuChunkInfo so it can be safely cast to that too. This means that if less code change is required, in this case you can also cast like this:

MenuChunkInfo* chunkInfo = dynamic_cast<MenuChunkInfo*>( message );

Table of Message Correspondence

These are three tables displaying the correspondence between the old action constants and the data they carry in the messages, and the new data structures.

Menu Event Sink Messages

Old Constant Old Message 1 Old Message 2 New Message Structure New Message Constant
kMenuDoInterface MenuChunkInfo* MenuDoInterfaceMessage MenuDoInterfaceMessage::kAction
kMenuAddItems MenuChunkInfo* MenuAddItemsMessage MenuAddItemsMessage::kAction
kMenuChunkHilite MenuChunkInfo* MenuCheckHiliteMessage MenuCheckHiliteMessage::kAction
kMenuNotify status id MenuNotifyMessage MenuNotifyMessage::kAction
kMenuHandleToolAction MenuToolActionHandlerParams* MenuToolActionHandlerParams MenuToolActionHandlerParams::kAction
kMenuItemDisplayContextualHelp MenuChunkInfo* MenuItemDisplayContextualHelpMessage MenuItemDisplayContextualHelpMessage::kAction
kMenuItemEnabled chunk index MenuItemEnabledMessage MenuItemEnabledMessage::kAction
kMenuItemCheck MenuItemSpec* MenuItemSpec MenuItemSpec::kAction

Note that MenuChunkInfo is the base structure of the new message structures for the messages that used to have Message 1 as MenuChunkInfo.

Parametric Object Event Sink Messages

Old Constant Old Message 1 Old Message 2 New Message Structure New Message Constant
kParametricRecalculate Parametric Handle ParametricRecalculate ParametricRecalculate::kAction
kParametricPreference Parametric Handle Format Handle ParametricPreferencesMessage ParametricPreferencesMessage::kAction
kObjOnInitXProperties Parametric Handle CodeRefID ParametricInitXPropsMessage ParametricInitXPropsMessage::kAction
kObjOnSpecialEditID Parametric Handle TObjectEditReason* ParametricSpecialEditMessage ParametricSpecialEditMessage::kAction
kObjOnDM_Select Parametric Handle ParametricDMMessage ParametricDMMessage::kAction_Select
kObjOnDM_Cancel Parametric Handle pick index ParametricDMMessage ParametricDMMessage::kAction_Cancel
kObjOnDM_MouseDown Parametric Handle ParametricDMMessage ParametricDMMessage::kAction_MouseDown
kObjOnDM_Draw Parametric Handle pick index ParametricDMMessage ParametricDMMessage::kAction_Draw
kObjOnDM_Complete Parametric Handle pick index ParametricDMMessage ParametricDMMessage::kAction_Complete
kObjOnDM_GetCursor Parametric Handle pick index ParametricOnDM_GetCursorMessage ParametricOnDM_GetCursorMessage::kAction
kObjOnDM_ModeEvent Parametric Handle mode group ParametricOnDM_ModeEvent ParametricOnDM_ModeEvent::kAction
kObjOnDM_GetStatus Parametric Handle ParametricDMMessage ParametricDMMessage::kAction_GetStatus
kObjOnDM_CustomBarEvent Parametric Handle CustomBarEventData* ParametricCustomBarMessage ParametricCustomBarMessage::kAction_OnDM
kObjOnDM_BeginPauseEvent Parametric Handle ParametricDMMessage ParametricDMMessage::kAction_BeginPauseEvent
kObjOnDM_EndPauseEvent Parametric Handle ParametricDMMessage ParametricDMMessage::kAction_EndPauseEvent
kObjOnDM_MouseMove Parametric Handle pick index ParametricDMMessage ParametricDMMessage::kAction_MouseMove
kObjOnObjectUIButtonHit Parametric Handle button id ParametricUIButtonHitMessage ParametricUIButtonHitMessage::kAction
kObjOnCursor_MouseDown Parametric Handle pick index ParametricCurosrMessage ParametricCurosrMessage::kAction_MouseDown
kObjOnCursor_Complete Parametric Handle pick index ParametricCurosrMessage ParametricCurosrMessage::kAction_Complete
kObjOnCursor_MouseMove Parametric Handle pick index ParametricCurosrMessage ParametricCurosrMessage::kAction_MouseMove
kObjOnCursor_Draw Parametric Handle pick index ParametricCurosrMessage ParametricCurosrMessage::kAction_Draw
kObjOnCursor_Cancel Parametric Handle pick index ParametricCurosrMessage ParametricCurosrMessage::kAction_Cancel
kObjOnCursor_CustomBarEvent Parametric Handle CustomBarEventData* ParametricCustomBarMessage ParametricCustomBarMessage::kAction_OnCursor
kObjOnWidgetPrep Parametric Handle OnObjectWidgetPrepCall* OnObjectWidgetPrepCall OnObjectWidgetPrepCall::kAction
kObjOnCommand Parametric Handle ObjectCommand* ObjectCommand ObjectCommand::kAction
kObjOnGetToolName Parametric Handle TXString* toolName ParametricGetToolNameMessage ParametricGetToolNameMessage::kAction
kObjOnAddState Parametric Handle ObjectState* ObjectState ObjectState::kAction
kObjOnContextMenuInit Parametric Handle ObjectContextMenuEvent* ObjectContextMenuEvent ObjectContextMenuEvent::kAction_Init
kObjOnContextMenuEvent Parametric Handle ObjectContextMenuEvent* ObjectContextMenuEvent ObjectContextMenuEvent::kAction_Event
kObjOnWidgetValueUpdate Parametric Handle OnObjectWidgetValueCall* OnObjectWidgetValueCall OnObjectWidgetValueCall::kAction
kObjOnEyedropperPrepareCopy Parametric Handle Record Handle ParametricEyeDropperMessage ParametricEyeDropperMessage::kAction_PrepareCopy
kObjOnEyedropperAfterCopy Parametric Handle Source PIO Handle ParametricEyeDropperMessage ParametricEyeDropperMessage::kAction_AfterCopy
kObjOnGetSpecificGeometry Parametric Handle ObjctGetSpecificGeometryCall* ObjectGetSpecificGeometryCall ObjectGetSpecificGeometryCall::kAction
kToolCustomSubtypeInsert MenuToolActionHandlerParams* ParametricCustomToolMessage ParametricCustomToolMessage::kAction
kObjOnGetObjInCurtainWall Parametric Handle bool (is object in wall) ParametricGetInCurtainWallMessage ParametricGetInCurtainWallMessage::kAction
kObjOnAttributeSelect ParametricAtributeMessage ParametricAtributeMessage::kAction_Select
kObjOnAttributeCancel ParametricAtributeMessage ParametricAtributeMessage::kAction_Cancel
kObjOnAttributeMouseDown ParametricAtributeMessage ParametricAtributeMessage::kAction_MouseDown
kObjOnAttributeDraw ParametricAtributeMessage ParametricAtributeMessage::kAction_Draw
kObjOnAttributeMouseMove ParametricAtributeMessage ParametricAtributeMessage::kAction_MouseMove
kObjOnAttributeComplete ParametricAtributeMessage ParametricAtributeMessage::kAction_Complete
kObjOnAttributeGetCursor ParametricAtributeMessage ParametricAtributeMessage::kAction_GetCursor
kObjOnAttributeMove2D ParametricAtributeMove2DMessage ParametricAtributeMove2DMessage::kAction
kObjOnAttributeGetStatus ParametricAtributeMessage ParametricAtributeMessage::kAction_GetStatus
kObjOnAttributeModeEvent ParametricAtributeModeMessage ParametricAtributeModeMessage::kAction
54 ParametricAtributeModeMessage ParametricAtributeMessage::kAction_ToolSetDown
56 ParametricAtributeModeMessage ParametricAtributeMessage::kAction_ToolSelectionChange
57 ParametricAtributeModeMessage ParametricAtributeMessage::kAction_ToolPlanarSnapFiltering

Tool Event Sink Messages

Old Constant Old Message 1 Old Message 2 New Message Structure New Message Constant
kToolDoSetup kSetupSetdownPauseRestoreFlag ToolSetupMessage ToolSetupMessage::kAction_SetUp
kToolDoSetDown kSetupSetdownPauseRestoreFlag ToolSetupMessage ToolSetupMessage::kAction_DetDown
kToolGetCursor TXString* cursorImageSpec kMouseCursorManagerSpecifierRequest ToolGetCursorMessage ToolGetCursorMessage::kAction
kToolDoModeEvent mode group mode button ToolModeMessage ToolModeMessage::kAction
kToolDoDoubleClick ToolMessage ToolMessage::kAction_DoDoubleClick
kToolPointAdded WorldPt* ViewPt* ToolPointAddedMessage ToolPointAddedMessage::kAction
kToolMouseMove ToolMessage ToolMessage::kAction_MouseMove
kToolDrawingDoubleClick ToolMessage ToolMessage::kAction_DrawingDoubleClick
kToolDraw ToolMessage ToolMessage::kAction_Draw
kToolHandleComplete handle, sometimes? ToolCompleteMessage ToolCompleteMessage::kAction
kToolGetStatus ToolMessage ToolMessage::kAction_GetStatus
kToolPointRemoved kClearingAllToolPoints ToolPointRemovedMessage ToolPointRemovedMessage::kAction
kToolGenericStateChange kTool GenericStateChangeKey or kToolGenericStateChangeView ToolGenericStateChangeMessage ToolGenericStateChangeMessage::kAction
kToolOnInitXProperties tool index ToolInitXPropsMessage ToolInitXPropsMessage::kAction
kToolOnSelectionChange ToolMessage ToolMessage::kAction_OnSelectionChange
kToolOnMoveSelection2D WorldPt* offset Boolean nudging ToolMoveSel2DMessage ToolMoveSel2DMessage::kAction
kToolOnIdleEvent ToolMessage ToolMessage::kAction_OnIdle
kToolOnCustomBarEvent CustomBarEventData* CustomBarEventData CustomBarEventData::kAction
kToolProvideObjectGrips Boolean* isMultiSel ToolProvideObjGripsMessage ToolProvideObjGripsMessage::kAction
kToolInitByObject object Handle ToolInitByObjectMessage ToolInitByObjectMessage::kAction
kToolOnViewChange ToolMessage ToolMessage::kAction_OnViewChange
kOnUpdate2D3DCursor ToolMessage ToolMessage::kAction_OnUpdate2D3DCursor
kOnGetWantsAutoPlane ToolMessage ToolMessage::kAction_OnGetWantsAutoPlane
kOnGetWantsPlanarSnapFiltering ToolMessage ToolMessage::kAction_OnGetWantsPlanarSnapFiltering
kToolGetCursorSpecifier TXString* cursorImageSpec ToolMessage ToolMessage::kAction_GetCursor
kToolPreventsSnapLoupe ToolMessage ToolMessage::kAction_PreventsSnapLoupe
kToolSupportsScreenPlane ToolMessage ToolMessage::kAction_SupportsScreenPlane
kToolOnDeleteKeyWithNoToolPts ToolMessage ToolMessage::kAction_OnDeleteKeyWithNoToolPts
kToolOnEscapeKeyWithNoToolPts ToolMessage ToolMessage::kAction_OnEscapeKeyWithNoToolPts
kDefaultTool_UpdatePreviewObject object Handle ToolDefaultPreviewUpdateMessage ToolDefaultPreviewUpdateMessage::kAction
kToolDoDrawScrMod ToolMessage ToolMessage::kAction_DoDrawScrMod
kToolDoUndrawScrMod ToolMessage ToolMessage::kAction_DoUndrawScrMod

Resource Related Changes

More details can be found here Vectorworks VWR Resources.

Since Vectorworks 2015 no longer supports qtr files, the SDK has been updated to reflect that.

First of all, the numeric system of accessing resources has been declared legacy and new APIs were added to support transition of old plug-ins.

The biggest change is that the TXString(short,short) constructor for reading resources was removed. Instead, a new class was added to allow for reading legacy resources (based on numbers)

TXString title = TXLegacyResource( 11000, 1 )

This legacy class can be used to read String and TEXT resources. This is purely to help transition old plug-ins, and its use should be avoided for future code.

This works because plugins with SDK 2015 must specify a DefaultPluginVWRIdentifier function that returns the resource file for this plug-in. Typically, this function is defined in your main function right above the plugin_module_main function.

Note, that your plug-in will not link if you don't provide this function.

Similarly, there is TXResource class to read resources identified by path.

TXString title = TXResource( "Sample Plugin/Strings/DlgSettings", "title" );

However, it could be very tedious to specify full paths for every string use. The SDK provides a simpler approach:

TXString title = TXResStr( "DlgSettings", "title" );

This will work because of the DefaultPluginVWRIdentifier function.

Personal tools

See Also