Plug-In Modules in SDK 2015

From Vectorworks Developer
Revision as of 20:13, 22 September 2014 by Root (talk | contribs) (Created page with "{{LocationMain|category=LocationSDKSpecial|specific=}} This document explain the changes for Plug-in Modules in the SDK 2015. It uses comparison with existing plug-in to demo...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to 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: http://developer.vectorworks.net/index.php?title=SDK:Module_Plug-in
//
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.

IMenuEventSink

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

IParametricEventSink

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

IToolEventSink

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

IVSFunctionsEventSink

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
{
public:
       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
{
public:
       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

-1 Str31* cmdName ToolInitMessage ToolInitMessage::kAction_Init -2 Str31* cmdName ToolInitMessage ToolInitMessage::kAction_Destroy kToolDoSetup kSetupSetdownPauseRestoreFlag ToolSetupMessage ToolSetupMessage::kAction_SetUp kToolDoSetDown kSetupSetdownPauseRestoreFlag ToolSetupMessage ToolSetupMessage::kAction_DetDown kToolGetCursor TXString* cursorImageSpec kMouseCursorManagerSpecifierRequest ToolGetCursorMessage ToolGetCursorMessage::kAction kToolDoInterface 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 -kToolHandleComplete handle, sometimes? ToolCompleteMessage ToolCompleteMessage::kAction_Create 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.