Other Tips

From FM Plugin Wikipedia
Jump to: navigation, search

This page is about editing and working with the Calc Engine, Client and Types passed from FileMaker to your plugin.



kMayEvaluateOnServer

The FileMaker api includes a define 'fmx::ExprEnv::kMayEvaluateOnServer' for functions that you want to execute on FileMaker Server.

It is important to understand that this only controls execution of the specified functions within the Server Environment.

ie. in the following situations :

  • Manage -> Database : Updates to schema that require a calculation to be updated, that includes a call to your function
  • Execute Find : A find request that includes a calculated field referring to a plugin call.


Not setting this flag doesn't stop the function being available to Server Side Scripts.

For all purposes, a server side script has access to the same plugin function set as FileMaker Pro / ProAdvanced Client.

Therefore, it is important that any plugin function that shouldn't be performed with the server environment isn't available to server scripts, either by not enabling the function at all, or forcing the function to exit immediately.

My preference is to not enable the functions at all (see below)



Detect Pro, ProAdvanced, Server or Web during FMX_Init

The following steps will allow you to detect the version of FileMaker that is initialising your plugin.


Step One : Modify the 'case kFMXT_Init' to pass 'parm1' to your DoPluginInit function.
/* ::=- FMExternCallProc "Main" =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=:: */
void FMX_ENTRYPT FMExternCallProc(FMX_ExternCallPtr pb)
{
	// Setup global defined in FMxExtern.h
	gFMX_ExternCallPtr = pb;

	// Message dispatcher
	switch (gFMX_ExternCallPtr->whichCall) 
	{
		case kFMXT_Init:
		{
			//	Msg	=	Parm1				Parm2				Parm3
			//	kFMXT_Init	FMX_Application value		App vers unicode c str* 	[unused]

			gFMX_ExternCallPtr->result = Do_PluginInit(gFMX_ExternCallPtr->extnVersion, gFMX_ExternCallPtr->parm1 );
		}
		break;


Step Two : Modify your 'DoPluginInit' function to accept the additional parameter.
	static FMX_Long Do_PluginInit(FMX_Short version, FMX_Application FMAppVersion ) 


Step Three : Check FMAppVersion for FileMaker Application Version

Parm1 is a FMX_Application which is defined in the header file FMXExtern.h

typedef FMX_UChar	FMX_Application;
enum
{
	kFMXT_Developer			= 0,
	kFMXT_Pro			= 1,
	kFMXT_Runtime			= 2,
	kFMXT_Server			= 3,
	kFMXT_Web			= 4,
	kFMXT_Mobile			= 5
};


We can then check if running on Client or server/web.

For this example, I have initialised a 'boolean pluginIsRunningOnClient;'

	pluginIsRunningOnClient = (FMAppVersion <= kFMXT_Runtime);


Finally, use this to decide which functions to initialise :

	if (pluginIsRunningOnClient)	err = fmx::ExprEnv::RegisterExternalFunction(*pluginID, ABCD_Function_ID,	...  , My_Function_Call );
	else				err = fmx::ExprEnv::RegisterExternalFunction(*pluginID, ABCD_Function_ID,	...  , My_Invalid_Function_Call );



Do_StartScript

The default FM 7 API includes the function 'Do_StartScript' works okay, but by default, it doesn't allow you to pass any text to the called script which can then be retrieved using 'Get(ScriptParameter)'


You can modify the script as below, which allows the user to pass an optional (in this example) third parameter, which is then passed to the called script.


FMX_PROC(fmx::errcode) Do_StartScript(short /* funcId */, const fmx::ExprEnv& /* environment */, const fmx::DataVect& dataVect, fmx::Data&  /* results */ )
{
	fmx::errcode errorResult = 0;

	fmx::ulong nParams = dataVect.Size();
	
	if (nParams > 2)
	{
		// This function will trigger the execution of a script in FileMaker Pro, passing the text as parameter to the script.
		errorResult = FMX_StartScript( &(dataVect.AtAsText(0)), &(dataVect.AtAsText(1)), kFMXT_Pause, &(dataVect.At(2)) );
	}
	else if (nParams > 1)
	{
		// This function will trigger the execution of a script in FileMaker Pro with no paramater.
		errorResult = FMX_StartScript( &(dataVect.AtAsText(0)), &(dataVect.AtAsText(1)), kFMXT_Pause, NULL );
	}
	else
	{
		errorResult = -1;	// This is just an example of returning an error
 	}// nParams > 1
	
	return(errorResult);
} // Do_IDMA_StartScript

Make sure in your Function Setup, you have set Min to 2 parameters, and Max to 3 parameters.