Calls a command of an add-on from Archicad’s main event loop.

    GSErrCode  ACAPI_Command_CallFromEventLoop (
        const API_ModulID*           mdid,
        GSType                       cmdID,
        Int32                        cmdVersion,
        GSHandle                     paramsHandle,
        bool                         silentMode,
        APICommandCallBackProc*     callbackProc



[in] the identifier of the target add-on. It is defined by the ‘MDID’ resource
[in] the identifier of the command to be executed
[in] the required command version
[in/out] passed parameters (optional). See the Inter-add-on communication section of the ACAPI_Goodies functions
[in] instruct the target add-on to work in silent mode. No option dialogs, error alerts …etc.
[in] optional callback procedure for handling the responses asynchronously


Return Values

the function completed successfully
the mdid parameter is nullptr
the referenced add-on is not installed
the referenced command is not supported by the target add-on
the requested command version is too new; not supported by the target add-on

For other common errors see the list of error codes.



This function is used to call a command implemented in an add-on from Archicad’s main event loop.

Refer to the ACAPI_Command_Test function to test the command availability.

Refer to the Communication Manager for more detailed description on

  • how to pass parameters,
  • how to get return values,
  • how the heaps and API environments are managed by the API.



The following sample starts a new working thread and calls an add-on command to place a column in the given position:

// ---------------------------------------------------------------------------------------------------------------------
// Add double parameter to MDCL parameter list
// ---------------------------------------------------------------------------------------------------------------------
bool    AddFloatMDCLParameter (GSHandle& paramHandle, const char* name, double value)
    API_MDCLParameter   par;
    BNZeroMemory (&par, sizeof (par)); = name;
    par.type = MDCLPar_float;
    par.float_par = value;
    return ACAPI_Goodies (APIAny_AddMDCLParameterID, paramHandle, &par) == NoError;

// ---------------------------------------------------------------------------------------------------------------------
// Get double parameter from MDCL parameter list
// ---------------------------------------------------------------------------------------------------------------------
bool    GetFloatMDCLParameter (GSHandle paramHandle, const char *name, double& value)
    API_MDCLParameter   par;
    BNZeroMemory (&par, sizeof (API_MDCLParameter)); = name;

    if (ACAPI_Goodies (APIAny_GetMDCLParameterID, paramHandle, &par) == NoError && par.type == MDCLPar_float)
        value = par.float_par;
        return true;
    return false;

// ---------------------------------------------------------------------------------------------------------------------
// Create column command handler
// ---------------------------------------------------------------------------------------------------------------------
GSErrCode __ACENV_CALL  Create_Column_CommandHandler (GSHandle paramHandle, GSPtr /*resultData*/, bool /*silentMode*/)
    GSErrCode           err = NoError;
    API_Coord           origoPos;

    if (!GetFloatMDCLParameter (paramHandle, "origoPosX", origoPos.x) ||
        !GetFloatMDCLParameter (paramHandle, "origoPosY", origoPos.y))
        return APIERR_BADPARS;

    API_Element     element;
    API_ElementMemo memo;

    BNZeroMemory (&element, sizeof (API_Element));
    BNZeroMemory (&memo, sizeof (API_ElementMemo));

    element.header.typeID = API_ColumnID;
    err = ACAPI_Element_GetDefaults (&element, nullptr);
    if (err != NoError)
        return err;

    element.column.origoPos    = origoPos;

    ACAPI_CallUndoableCommand ("Test - Create column command",
        [&] () -> GSErrCode {
            return ACAPI_Element_Create (&element, &memo);

    ACAPI_DisposeElemMemoHdls (&memo);

    return err;

// ---------------------------------------------------------------------------------------------------------------------
// CallBack function for command call from event loop
// ---------------------------------------------------------------------------------------------------------------------
void __ACENV_CALL   CommandCallBackProc (GSHandle* paramHandle, GSPtr /*resultData*/, GSErrCode returnCode)
    if (returnCode != NoError)
        WriteReport_Err ("Command finished in event loop with Error", returnCode);
        WriteReport ("Command successfully finished in event loop!");

    if (paramHandle != nullptr)
        ACAPI_Goodies (APIAny_FreeMDCLParameterListID, paramHandle, nullptr);

// --- MonitoredTask -----------------------------------------------------------

class MonitoredTask : public GS::Runnable {
    explicit MonitoredTask ();

    virtual void    Run ();

MonitoredTask::MonitoredTask ()

void    MonitoredTask::Run ()
    try {
        GSErrCode   err = NoError;
        API_Coord   origoPos;
        BNZeroMemory (&origoPos, sizeof (API_Coord));
        origoPos.x = 10.0;
        origoPos.y = 20.0;

        GSHandle    paramHandle = nullptr;
        err = ACAPI_Goodies (APIAny_InitMDCLParameterListID, &paramHandle, nullptr);
        if (err == NoError) {
            if (AddFloatMDCLParameter (paramHandle, "origoPosX", origoPos.x) &&
                AddFloatMDCLParameter (paramHandle, "origoPosY", origoPos.y))
                API_ModulID mdid;
                BNZeroMemory (&mdid, sizeof (mdid));
                mdid.developerID = MDID_GSDEV;
                mdid.localID = MDID_GSDEV_Test;
                err = ACAPI_Command_CallFromEventLoop (&mdid, 'CCOL', 1, paramHandle, false, CommandCallBackProc);
                if (err != NoError) {
                    WriteReport_Err ("ACAPI_Command_CallFromEventLoop failed", err);
                    ACAPI_Goodies (APIAny_FreeMDCLParameterListID, &paramHandle, nullptr);
    catch (GS::InterruptedException&) {
        // Empty handler
    catch (...) {


static void     Do_CommandCallFromEventLoop (void)
    GS::Thread m_worker (new MonitoredTask (), "CommandCallFromEventLoop_MonitoredTaskThread");
    m_worker.Start ();

// Interface definitions
GSErrCode __ACENV_CALL  RegisterInterface (void)
    // register supported command
    GSErrCode err = ACAPI_Register_SupportedService ('CCOL', 1);

    return err;
}       /* RegisterInterface */

// Called when the Add-On has been loaded into memory
// to perform an operation
GSErrCode __ACENV_CALL  Initialize (void)
    // install command handler
    GSErrCode err = ACAPI_Install_ModulCommandHandler ('CCOL', 1, Create_Column_CommandHandler);

    return err;
}       /* Initialize */



Version: API 19 or later
Header: ACAPinc.h


See Also

Communication Manager
API Functions