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

Does not work ACAPI_Element_Change, API_ZoneID, poz.

Anonymous
Not applicable
Hello, I can not change the position of the zone stamp.
The function itself is executed without errors, but the stamp does not move. The documentation indicated will change. For the experiment, changing the name of the zone and everything works with it. Started from the AC17 to the AC21 reached everywhere the same thing.
GSErrCode ModifyZonePoz(const API_Guid &guid)
{
	API_Element     element;
	API_Element		mask;
	GSErrCode err;
	BNZeroMemory(&element, sizeof(API_Element)); // AC17-AC22 element.header.index 
	
	ACAPI_ELEMENT_MASK_CLEAR (mask); 
	ACAPI_ELEMENT_MASK_SET (mask, API_ZoneType, pos);
	//ACAPI_ELEMENT_MASK_SET(mask, API_ZoneType, roomName);

	element.zone.pos.x =  5.0;
	element.zone.pos.y =  10.0;
	//CHCopyC ("test", element.zone.roomName);
	element.header.guid = guid; // в заголовок поместить Guid
	element.header.typeID = API_ZoneID; // обязательно !
	err = ACAPI_Element_Change(&element, &mask, NULL, 0, true);
	WriteReport("ACAPI_Element_Change %ld", err);
	return err;
}
What threatens me if, instead of this function, I copy all the properties of the zone and change the memo, then create a new one? ACAPI_Element_Create?
1 ACCEPTED SOLUTION

Accepted Solutions
Solution
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
Hi,

thank you for pointing out this issue! Unfortunately it's a bug, we will work on it.
As a workaround you can create a new zone with the modified stamp position and delete the original one:
GSErrCode	ModifyZonePos (const API_Guid& guid, const API_Coord& newPos)
{
	API_Element			element;
	API_ElementMemo		memo;
	GSErrCode			err;

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

	// get actual zone
	element.header.guid	= guid;

	err = ACAPI_Element_Get (&element);
	if (err == NoError)
		err = ACAPI_Element_GetMemo (element.header.guid, &memo);
	if (err != NoError)
		return err;

	// modify pos and create a new zone
	element.zone.pos = newPos;

	err = ACAPI_Element_Create (&element, &memo);

	ACAPI_DisposeElemMemoHdls (&memo);

	// delete original zone
	API_Elem_Head** heads = (API_Elem_Head**) BMhAllClear (sizeof (API_Elem_Head));
	(*heads).guid = guid;

	ACAPI_Element_Delete (heads, 1);

	BMhKill ((GSHandle*) &heads);

	return err;
}

Regards,
Tibor

View solution in original post

3 REPLIES 3
Solution
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
Hi,

thank you for pointing out this issue! Unfortunately it's a bug, we will work on it.
As a workaround you can create a new zone with the modified stamp position and delete the original one:
GSErrCode	ModifyZonePos (const API_Guid& guid, const API_Coord& newPos)
{
	API_Element			element;
	API_ElementMemo		memo;
	GSErrCode			err;

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

	// get actual zone
	element.header.guid	= guid;

	err = ACAPI_Element_Get (&element);
	if (err == NoError)
		err = ACAPI_Element_GetMemo (element.header.guid, &memo);
	if (err != NoError)
		return err;

	// modify pos and create a new zone
	element.zone.pos = newPos;

	err = ACAPI_Element_Create (&element, &memo);

	ACAPI_DisposeElemMemoHdls (&memo);

	// delete original zone
	API_Elem_Head** heads = (API_Elem_Head**) BMhAllClear (sizeof (API_Elem_Head));
	(*heads).guid = guid;

	ACAPI_Element_Delete (heads, 1);

	BMhKill ((GSHandle*) &heads);

	return err;
}

Regards,
Tibor
Anonymous
Not applicable
Thank you Tibor Lorántfy, your code helped a lot, and saved a lot of time, considering my level of understanding of x2 pointers. However, I slightly modified it.
GSErrCode	ModifyZonePos(const API_Guid& guid, const API_Coord& newPos)
{
	API_Element			element;
	API_ElementMemo		memo;
	GSErrCode			err;

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

	// get actual zone
	element.header.guid = guid;

	err = ACAPI_Element_Get(&element);
	if (err == NoError)
		err = ACAPI_Element_GetMemo(element.header.guid, &memo);
	if (err != NoError)
		return err;
	// delete original zone, before create a new zone, if not want get alert
	API_Elem_Head** heads = (API_Elem_Head**)BMhAllClear(sizeof(API_Elem_Head));
	(*heads)[0].guid = guid; // 0  -1 zones
	ACAPI_Element_Delete(heads, 1);
	BMhKill((GSHandle*)&heads);

	// modify pos and create a new zone
	element.zone.pos = newPos;
	err = ACAPI_Element_Create(&element, &memo);
	ACAPI_DisposeElemMemoHdls(&memo);
	return err;
}
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
ufo_ru wrote:
considering my level of understanding of x2 pointers
Please note that the parameters of ACAPI_Element_Delete will change in ARCHICAD 23, so you won't have to bother with pointers anymore:
// Before AC23:
GSErrCode	ACAPI_Element_Delete (API_Elem_Head **elemHead, Int32 nItem);

// Since AC23:
GSErrCode	ACAPI_Element_Delete (const GS::Array<API_Guid>& elemGuids);
The sample code in API23 will be much shorter:
GSErrCode	ModifyZonePos(const API_Guid& guid, const API_Coord& newPos)
{
	API_Element	element = {};
	API_ElementMemo	memo = {};
	GSErrCode	err;

	// get actual zone
	element.header.guid = guid;
	err = ACAPI_Element_Get(&element);
	if (err == NoError)
		err = ACAPI_Element_GetMemo(element.header.guid, &memo);
	if (err != NoError)
		return err;

	// delete original zone
	ACAPI_Element_Delete({guid});

	// modify pos and create a new zone
	element.zone.pos = newPos;
	err = ACAPI_Element_Create(&element, &memo);
	ACAPI_DisposeElemMemoHdls(&memo);
	return err;
}