LiveBindings Inc Method (C++)

From RAD Studio Code Examples
Jump to: navigation, search

Description

This example shows how to create a LiveBindings method, Inc, that increases an integer by 1.

To build and test this example:

  1. Create a package and add a unit to it.
  2. Add the following lines to the beginning of your unit implementation file (.cpp):
    #include <System.Bindings.Methods.hpp>
    #include <System.Bindings.EvalProtocol.hpp>
    #include <System.Bindings.Consts.hpp>
    #include <System.TypInfo.hpp>
Note: Add bindengine.bpi to the package requires.
  1. Define a function that returns an instance of IInvokable. This instance is a function that expects an integer and returns this integer increased by one. For example, if the function receives 5, it returns 6.
  2. In the initialization section, register your invokable function with 'Inc' as both name and ID.
  3. In the finalization section, unregister your invokable function.
Note: After installing the package with custom LiveBindings Methods, re-open the form or project using TBindingsList component.
Note: When application is build with run-time packages, you need to load the package with custom LiveBindings Methods using LoadPackage call. This must be done before the creation of forms which use these methods.

You can now install your package. Your method is registered and you can use it in your custom format and parse expressions. Your method is also listed in the LiveBindings Methods editor.

LiveBindingsIncFormattingMethodBefore.png
LiveBindingsIncFormattingMethodAfter.png

Code

Unit1.h does not need changes.

Unit1.cpp:

//---------------------------------------------------------------------------

#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)

#include <System.Bindings.Methods.hpp>
#include <System.Bindings.EvalProtocol.hpp>
#include <System.Bindings.Consts.hpp>
#include <System.TypInfo.hpp>

class IncMethod : public TCppInterfacedObject<TInvokableBody>
{
public:
    _di_IValue __fastcall Invoke(DynamicArray<_di_IValue> Args)
    {
        // Ensure only one argument is received.
        if (Args.Length != 1) {
            throw EEvaluatorError(System_Bindings_Consts_sFormatArgError);
        }

        // Ensure that the received argument is an integer.
        _di_IValue InputValue = Args[0];
        if (InputValue->GetType()->Kind != tkInteger && InputValue->GetType()->Kind != tkInt64) {
            throw EEvaluatorError(System_Bindings_Consts_sFormatExpectedStr);
        }

        // Calculate the output integer.
        __int64 InputInteger = InputValue->GetValue().AsInt64();
        __int64 OutputInteger = InputInteger + 1;

        // Return the output integer.
        TValue OutputValue = TValue::_op_Implicit(OutputInteger);
        TValueWrapper* WrappedOutputValue = new TValueWrapper(OutputValue);
        return interface_cast<IValue>(WrappedOutputValue);
    }
};

class UnitRegistration
{
public:
    UnitRegistration()
    {
        IncMethodInstance = new IncMethod;
        TMethodDescription IncMethodDescription(interface_cast<IValue>(IncMethodInstance), "Inc", "Inc", "", true, System_Bindings_Consts_sFormatDesc, NULL);
        TBindingMethodsFactory::RegisterMethod(IncMethodDescription);
    }

    ~UnitRegistration()
    {
        TBindingMethodsFactory::UnRegisterMethod("Inc");
        delete IncMethodInstance;
    }

private:
    IncMethod* IncMethodInstance;
};
UnitRegistration UnitRegistrationInstance;

Uses

See Also