Calling PowerScript from an extension

You can call PowerBuilder system functions through IPB_Session. The InitCallInfo method simplifies the process of setting up the call information. You need to provide the arguments to the InitCallInfo method, including an identifier for the PowerBuilder function you want to call.

The identifier can be returned from the GetMethodID or FindMatchingFunction method. 

Using GetMethodID

To get the function's ID using the GetMethodID method, you need the function's signature:

PbmethodID GetMethodID(pbclass cls, LPCTSTR
   methodName, PBRoutineType rt, LPCTSTR signature);

The signature argument in this method call is a string representing the method's return type and arguments. You can obtain this string in the Browser.

For example, to obtain the signature of a system function, select systemfunctions from the left pane of the System page, right-click the function in the right pane, and select Properties from its pop-up menu:

For methods in your application, you can expand the object that contains it in the System Tree, select the function or event, and select Properties from its pop-up menu:

Consider this function:

of_get_trans ( ref transaction atr_trans ) returns (none)

The signature for this function is QRCtransaction. Q indicates that the function does not return a value, R that the argument is passed by reference, and Ctransaction that the argument is a PowerBuilder system object of type transaction.

You can use the pbsig170 command-line tool to obtain a function's signature. However, the pbsig170 tool does not report the signature of functions that are inherited from an ancestor object unless they are extended in the descendant, and it does not report event signatures.

For more information about using pbsig170, and an explanation of all the formats used in the signature, see pbsig170.

Using FindMatchingFunction

Instead of the string that GetMethodID uses, the FindMatchingFunction function provides another way to get the method ID. Some short signatures can be difficult to parse, and signatures that include PowerBuilder system objects or Java classes can be much longer.

FindMatchingFunction uses a "readable signature" instead of the string used by GetMethodID:

FindMatchingFunction(pbclass cls, LPCTSTR methodName, PBRoutineType rt, LPCTSTR readableSignature) 

The readableSignature argument is a comma-separated list of the arguments of the function. Unlike the string used by GetMethodID, it does not include the return type. For example, for a function called uf_test that takes two arguments, an int by value and a double by reference, the call to FindMatchingFunction looks like this:

mid = Session -> FindMatchingFunction(cls, "uf_test",
   PBRT_FUNCTION, "int, double");

Invoking PowerBuilder functions

The following methods are those you use most frequently to invoke PowerBuilder functions. For descriptions of each method, see IPB_Session interface.

PbmethodID GetMethodID(pbclass cls, LPCTSTR methodName,
    PBRoutineType rt, LPCTSTR signature, pbboolean publiconly)
PBXRESULT InitCallInfo(pbclass cls, pbmethodID mid, PBCallInfo *ci)
void FreeCallInfo(PBCallInfo *ci)
PBXRESULT Add<Type>Argument(PBCallInfo *ci, PBType v);
PBXRESULT InvokeClassFunction(pbclass cls, pbmethodID mid, PBCallInfo *ci)
PBXRESULT InvokeObjectFunction(pbobject obj, pbmethodID mid, PBCallInfo *ci)
PBXRESULT TriggerEvent(pbobject obj, pbmethodID mid, PBCallInfo *ci)

Example: Calling PowerBuilder functions

In this code fragment, the class and method ID returned by calls to the IPB_Session GetClass and GetMethodID methods are used to initialize a PBCallInfo structure, called ci, using the IPB_Session InitCallInfo method.

After a new pbstring variable is created, the value of that string is set to the value of the first argument in the PBCallInfo structure.

BOOL CALLBACK CFontEnumerator::EnumFontProc
(
   LPLOGFONT lplf, 
   LPNEWTEXTMETRIC lpntm, 
   DWORD FontType, 
   LPVOID userData
)
{
   UserData* ud = (UserData*)userData;
   pbclass clz = ud->session->GetClass(ud->object);
   pbmethodID mid = ud->session->GetMethodID
      (clz, "onnewfont", PBRT_EVENT, "IS");

   PBCallInfo ci;
   ud->session->InitCallInfo(clz, mid, &ci);

// create a new string variable and set its value
// to the value in the first argument in the 
// PBCallInfo structure
   pbstring str = ud->session->NewString
      (lplf->lfFaceName);
   ci.pArgs->GetAt(0)->SetString(str);

   ud->session->TriggerEvent(ud->object, mid, &ci);
   pbint ret = ci.returnValue->GetInt();

   ud->session->FreeCallInfo(&ci);
   return ret == 1 ? TRUE : FALSE;
}