The Global Archicad Community

Stay informed. Get help. Share your knowledge.

Discussions about using GRAPHISOFT's tools (Archicad API, BIMx API, BIMcloud API) for independent software developers

Moderators: Karl Ottenstein, LaszloNagy, ejrolon, Barry Kelly, Gordana Radonic, nbalogh, mnguyen, gkmethy, rmasaki, Viktor Kovacs, MOREH Tamas, Akos Somorjai, Ed Brown, Mihály Palenik, Tibor Lorántfy

User avatar
By poco2013
#324973
Need some help in changing a STRING parameter in a Library Part. I have looked at several examples and they all only show modifying a float parameter. The problem I'm having is getting the API_​ChangeParamType GS::uchar_t *uStrValue attribute to point to the change string. My code is below. I can not get the correct format for ucscpy below . Please help. I know that I do not fully understand the conversions in Archicad between, ASCII, utf-16 , UTF-8 & UniStings usage, but need some help getting over the hump and started??
Code: Select all
// change params here
						GS::UniString newtxt("XXX");
						API_ChangeParamType chgParam;
						API_ParamOwnerType     paramOwner;
						API_GetParamsType    getParams;
						
						BNZeroMemory(&chgParam, sizeof(API_ChangeParamType));
						BNZeroMemory(&paramOwner, sizeof(API_ParamOwnerType));
						BNZeroMemory(&getParams, sizeof(API_GetParamsType));

						paramOwner.libInd = libIndex;
						paramOwner.typeID = API_ObjectID;      /* object element */
						paramOwner.guid = APINULLGuid;
						
						ACAPI_Goodies(APIAny_OpenParametersID, &paramOwner,nullptr);
						err = ACAPI_Goodies(APIAny_GetActParametersID, &getParams, nullptr);
						if(err == NoError){ 
						     chgParam.index = libIndex;
						     CHCopyC("txt", chgParam.name);

						     GS::ucscpy(chgParam.uStrValue.uStr, newtxt.ToUStr()); //exception here
                                                 /*
						 chgParam is incorrect -- getting message error "left of uStr must have       class/struct/union" - I have changed ucsscpy all different ways and can't get it right.
                                                    */
						      err = ACAPI_Goodies(APIAny_ChangeAParameterID, &chgParam,nullptr);
						}
						ACAPI_Goodies(APIAny_CloseParametersID,nullptr,nullptr);
							if (err)
								ACAPI_WriteReport("busted",true);
EDIT:: found the answer here -- viewtopic.php?f=23&t=68038 Thanks Tibor However, using above with correction - still can't get string parameter to change?? Add-On runs with no errors but no change now.
User avatar
By Tibor Lorántfy
#325203
APIAny_ChangeAParameterID changes the parameters value only in the API_GetParamsType object in the memory. It does not changes any element or libpart in the project directly.
You have to do something with the changed params handle to notify any change after the operation.
Code: Select all
{
	API_GetParamsType theParams = {};
	API_ParamOwnerType paramOwner = {};
	GS::uchar_t uStrBuffer[BUFFER_SIZE];

	paramOwner.typeID = API_ObjectID;
	paramOwner.libInd = libPartIndex;

	GSErrCode err = ACAPI_Goodies (APIAny_OpenParametersID, &paramOwner);
	err |= ACAPI_Goodies (APIAny_GetActParametersID, &theParams);
	if (err == NoError) {
		API_ChangeParamType changeParam = {};

		CHTruncate (paramName, changeParam.name, API_NameLen);
		GS::ucsncpy (uStrBuffer, newStrValue.ToUStr ().Get (), BUFFER_SIZE);
		changeParam.uStrValue = uStrBuffer;

		err = ACAPI_Goodies (APIAny_ChangeAParameterID, &changeParam);
		if (err == NoError) {
			// Do something with theParams.params
		}
	}

	ACAPI_DisposeAddParHdl (&theParams.params);
	ACAPI_Goodies (APIAny_CloseParametersID);
}
I'm here to help, but at first I have to know what's your purpose...
Do you want to change the parameter value in a placed element instance of the library part? If the answer is yes, then use this code instead of the "// Do something with theParams.params" comment:
Code: Select all
API_ElementMemo memo = {};
memo.params = theParams.params;

API_Element	mask;
ACAPI_ELEMENT_MASK_CLEAR (mask);

API_Element	elem = {};
elem.header.guid = elemGuid;
ACAPI_Element_Get (&elem);

err = ACAPI_Element_Change (&elem, &mask, &memo, APIMemoMask_AddPars, true);
Or you would like to change the default value of the parameter in a library part? To achieve that, you have to overwrite the library part in the library.
User avatar
By poco2013
#325206
Thanks Tibor:

I got it to work now. The confusion was basically that i did not understand how Archicad's API called and created elements.

I just wanted to insert a Library part with mostly the same defaults but to change some key parameters. i did not want change the defaults. Basically reusing a base Lib Part over and over to do different things depending on a few user input param changes from another function.

I did not realize that i did not need to use Change_Parameters at all (since the changes were only used for the current object) but just change the Library part params directly in the element create function after I retrieved the params list with GetParameters for the utility Lib Part.

Sorry for the trouble but your above input helps explain things better for me. I copied it for future reference

Thanks again..