Archicad C++ API
About Archicad add-on development using the C++ API.
SOLVED!

I always APIERR_REFUSEDCMD error.

Soonbum Jeong
Newcomer
Hello, good developers.
I have a question.
I'm a newbie.

I'm practising with example source and other person's code.
Even simple codes, it returns APIERR_REFUSEDCMD error.
After ACAPI_Element_Create, any object did not appear on the screen.

My goal is placing Library part object with ACAPI_Element_Create function.

Could you advice me?

This is my first code.

GSErrCode __ACENV_CALL	CommandHandler (const API_MenuParams * /*params*/)
{
	GSErrCode	err;
	char		errMsg [50];

	API_Element			element;
	API_ElementMemo		memo;
	API_LibPart			libPart;
	API_GetPointType	pointInfo;

	double	aParam;
	double	bParam;
	Int32	addParNum;


	// Load a object
	BNZeroMemory (&libPart, sizeof (libPart));
	strcpy (libPart.ownUnID, "{CE0BB097-2FE3-4399-B6DA-80681BD99C60}-{00000000-0000-0000-0000-000000000000}");
	err = ACAPI_LibPart_Search (&libPart, false);
	if (libPart.location != NULL)
		delete libPart.location;

	err = ACAPI_LibPart_Get (&libPart);
	if (err != NoError) {
		sprintf (errMsg, "ACAPI_LibPart_Get: %d", err);
		ACAPI_WriteReport (errMsg, true);
		return err;
	}


	// Click a point
	BNZeroMemory (&pointInfo, sizeof (API_GetPointType));
	CHTruncate ("Click a point", pointInfo.prompt, sizeof (pointInfo.prompt));
	pointInfo.changeFilter = false;
	pointInfo.changePlane  = false;

	err = ACAPI_Interface (APIIo_GetPointID, &pointInfo, NULL);
	if (err != NoError) {
		sprintf (errMsg, "ACAPI_Interface: %d", err);
		ACAPI_WriteReport (errMsg, true);
		return err;
	}


	// Placing a object
	BNZeroMemory (&element, sizeof (API_Element));
	BNZeroMemory (&memo, sizeof (API_ElementMemo));

	element.header.typeID = API_ObjectID;
	element.header.guid = GSGuid2APIGuid (GS::Guid ("{CE0BB097-2FE3-4399-B6DA-80681BD99C60}"));
	
	err = ACAPI_Element_GetDefaults (&element, &memo);
	if (err != NoError) {
		sprintf (errMsg, "ACAPI_Element_GetDefaults: %d", err);
		ACAPI_WriteReport (errMsg, true);
		return err;
	}

	err = ACAPI_LibPart_GetParams (libPart.index, &aParam, &bParam, &addParNum, &memo.params);
	if (err != NoError) {
		sprintf (errMsg, "ACAPI_LibPart_GetParams: %d", err);
		ACAPI_WriteReport (errMsg, true);
		return err;
	}
	//element.object.head.guid = element.header.guid;
	element.object.libInd = libPart.index;
	element.object.pos.x = 0;	// pointInfo.pos.x;
	element.object.pos.y = 0;	// pointInfo.pos.y;
	element.object.level = 0;	// pointInfo.pos.z;
	element.object.xRatio = aParam;
	element.object.yRatio = bParam;

	err = ACAPI_Element_Create (&element, &memo);
	if (err != NoError) {
		sprintf (errMsg, "ACAPI_Element_Create: %d", err);
		ACAPI_WriteReport (errMsg, true);
		return err;
	}

	ACAPI_DisposeElemMemoHdls (&memo);

	return NoError;
}		// CommandHandler ()

This is sample practice code.

GSErrCode __ACENV_CALL	CommandHandler (const API_MenuParams * /*params*/)
{
	const char      hwText[] = { "This multistyle\nword was created\nby the Element Test example project." };

	API_Element     element;
	API_ElementMemo memo;
	GSErrCode       err = NoError;

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

	element.header.typeID = API_TextID;
	ACAPI_Element_GetDefaults (&element, &memo);

	element.text.charCode = CC_UTF8;
	element.text.loc.x = element.text.loc.y = 2;
	element.text.anchor = APIAnc_LB;
	element.text.multiStyle = true;
	element.text.nonBreaking = false;
	element.text.useEolPos = true;
	element.text.width = 150;
	element.text.charCode = CC_Default;
	memo.textContent = BMhAll (Strlen32 (hwText) + 1);
	if (memo.textContent == NULL)
		return APIERR_MEMFULL;
	strcpy (*memo.textContent, hwText);

	// create the text element 
	err = ACAPI_Element_Create (&element, &memo);

	// clean up
	ACAPI_DisposeElemMemoHdls (&memo);

	return err;
}		// CommandHandler ()
1 ACCEPTED SOLUTION

Accepted Solutions
Solution
Ralph Wessel
Mentor
Every database change has to be enclosed in an undoable session. Are you calling this function within that context? If not, take a look at ACAPI_CallUndoableCommand.
Ralph Wessel BArch

View solution in original post

3 REPLIES 3
Solution
Ralph Wessel
Mentor
Every database change has to be enclosed in an undoable session. Are you calling this function within that context? If not, take a look at ACAPI_CallUndoableCommand.
Ralph Wessel BArch
Soonbum Jeong
Newcomer
Ralph wrote:
Every database change has to be enclosed in an undoable session. Are you calling this function within that context? If not, take a look at ACAPI_CallUndoableCommand.
Thank you, Ralph.
I will try it.
Soonbum Jeong
Newcomer
Ralph wrote:
Every database change has to be enclosed in an undoable session. Are you calling this function within that context? If not, take a look at ACAPI_CallUndoableCommand.
Thank you, Ralph.
My code is works well.

GSErrCode __ACENV_CALL	CommandHandler (const API_MenuParams * /*params*/)
{
	GSErrCode	err;
	char		errMsg [50];

	API_Element			element;
	API_ElementMemo		memo;
	API_LibPart			libPart;
	API_GetPointType	pointInfo;

	double	aParam;
	double	bParam;
	Int32	addParNum;


	// Load a object
	BNZeroMemory (&libPart, sizeof (libPart));
	strcpy (libPart.ownUnID, "{CE0BB097-2FE3-4399-B6DA-80681BD99C60}-{00000000-0000-0000-0000-000000000000}");
	err = ACAPI_LibPart_Search (&libPart, false);
	if (libPart.location != NULL)
		delete libPart.location;

	err = ACAPI_LibPart_Get (&libPart);
	if (err != NoError) {
		sprintf (errMsg, "ACAPI_LibPart_Get: %d", err);
		ACAPI_WriteReport (errMsg, true);
		return err;
	}


	// Click a point
	BNZeroMemory (&pointInfo, sizeof (API_GetPointType));
	CHTruncate ("Click a point", pointInfo.prompt, sizeof (pointInfo.prompt));
	pointInfo.changeFilter = false;
	pointInfo.changePlane  = false;

	err = ACAPI_Interface (APIIo_GetPointID, &pointInfo, NULL);
	if (err != NoError) {
		sprintf (errMsg, "ACAPI_Interface: %d", err);
		ACAPI_WriteReport (errMsg, true);
		return err;
	}


	// Placing a object
	BNZeroMemory (&element, sizeof (API_Element));
	BNZeroMemory (&memo, sizeof (API_ElementMemo));

	element.header.typeID = API_ObjectID;
	element.header.guid = GSGuid2APIGuid (GS::Guid ("{CE0BB097-2FE3-4399-B6DA-80681BD99C60}"));
	
	err = ACAPI_Element_GetDefaults (&element, &memo);
	if (err != NoError) {
		sprintf (errMsg, "ACAPI_Element_GetDefaults: %d", err);
		ACAPI_WriteReport (errMsg, true);
		return err;
	}

	err = ACAPI_LibPart_GetParams (libPart.index, &aParam, &bParam, &addParNum, &memo.params);
	if (err != NoError) {
		sprintf (errMsg, "ACAPI_LibPart_GetParams: %d", err);
		ACAPI_WriteReport (errMsg, true);
		return err;
	}
	//element.object.head.guid = element.header.guid;
	element.object.libInd = libPart.index;
	element.object.pos.x = 0;	// pointInfo.pos.x;
	element.object.pos.y = 0;	// pointInfo.pos.y;
	element.object.level = 0;	// pointInfo.pos.z;
	element.object.xRatio = aParam;
	element.object.yRatio = bParam;

	err = ACAPI_CallUndoableCommand ("Create text",
        [&] () -> GSErrCode {
            return ACAPI_Element_Create (&element, &memo);
        });
	if (err != NoError) {
		sprintf (errMsg, "ACAPI_Element_Create: %d", err);
		ACAPI_WriteReport (errMsg, true);
		return err;
	}

	ACAPI_DisposeElemMemoHdls (&memo);

	return NoError;
}