Using FPInterface::Invoke()

In some cases one might end up with a pointer to an object derived from FPInterface, which has some methods published using the function publishing system, but that are not exported in a .LIB or .DLL file. For example a third party plug-in. In this case one may used FPInterface::Invoke().

Any call to FPInterface::Invoke() should be surrounded in a try/catch block. This is because the MAXScript system throws exceptions to convey error messages. If an FPInterface function throws an exception for any reason and we do not catch it, then Max will crash.

Another consideration when using FPInterface::Invoke() is that function IDs may change without notice, causing your plug-in to crash in the future. To avoid this you should always use FPInterface::FindFn() to find the appropriate function ID for a function name.

When calling FPInterface::Invoke() the user must supply an FPParams object which is a Tab<> collection of FPParam values.

The example code below gives an example of how to open the track view using ITrackViewArray::OpenTrackViewWindow() which takes six arguments.

Note: This is just an example of how to set-up a call to FPInterface::Invoke(). We do not recommend using this technique to access 3ds Max functionality that is exposed to MAXScript but not the SDK. In most cases there is a better way to achieve the desired effect using the SDK, or it is simply not supported by 3ds Max.

ITrackViewArray* myTrackView = ( ITrackViewArray*)GetCOREInterface(ITRACKVIEWS);

FPParams fnParams;
FPValue result, param1, param2, param3, param4, param5, param6;
FPValue param1_FPValue;
TCHAR* param1_TCHAR = _T("Test Track View");
param1_FPValue.type = TYPE_STRING,
param1_FPValue.s = param1_TCHAR;

// getTrackView index must be 1-based
// function map indicates parameter 1 is type TYPE_FPVALUE (accepts int or string)
param1.type = (ParamType2)TYPE_FPVALUE,
param1.fpv = &param1_FPValue;
fnParams.params.Append( 1, &param1 );

// function map indicates parameter 2 is type TYPE_TSTR
TSTR param2_TSTR = TSTR( _T("") );
param2.type = TYPE_TSTR,
param2.tstr = &param2_TSTR;
fnParams.params.Append( 1, &param2 );

// function map indicates parameter 3 is type TYPE_POINT2
Point2 param3_Point2 = Point2(-1.0f,-1.0f);
param3.type = TYPE_POINT2,
param3.p2 = &param3_Point2;
fnParams.params.Append( 1, &param3 );

// function map indicates parameters 4 and 5 are type TYPE_INT
param4.type = (ParamType2)TYPE_INT,
param4.i = -1;
param5.type = (ParamType2)TYPE_INT,
param5.i = -1;
fnParams.params.Append( 1, &param4 );
fnParams.params.Append( 1, &param5 );

// function map indicates parameter 6 is type TYPE_ENUM (integer)
param6.type = TYPE_ENUM,
param6.i = (int)TV_FLOAT;
fnParams.params.Append( 1, &param6 );

try
{
  myTrackView->Invoke( ITrackViewArray::openTrackView, result, &fnParams );
}
catch (...)
{
  // an error occured
}