Passing a String value to GeUserArea [SOLVED]

On 05/07/2017 at 01:17, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R18 
Platform:   Windows  ;   
Language(s) :     C++  ;


I have a GeUserArea of type LONG. I want to pass a specific string value to this area every time I click a button.

I know that I can either make it String instead of LONG or I can have my own CustomDataType. But this string doesn't have anything to do with area's value.

How can I get the GeUserArea from within TagData's SetDParameter ? That way I will be able to downcast it and set the string to it right ?

Thank you.

On 05/07/2017 at 06:12, xxxxxxxx wrote:


we are a bit confused by your description. A GeUserArea doesn't have a type.
Can you please explain in a bit more detail, what you want to achieve?

On 05/07/2017 at 11:20, xxxxxxxx wrote:

Hello and sorry for explaining it poorly.

I have a iCustomGui which has a user area attached.

Bool CreateLayout(void){
	Bool res = GeDialog::CreateLayout();
	my_gadget = AddUserArea(10000, BFH_SCALEFIT|BFV_SCALEFIT);
	if (my_gadget )
		AttachUserArea(my_user_area, my_gadget );
	return res;

The variable my_user_area is defined in .res file as:

I have defined MYPARAMCUSTOMGUI as LONG, which is what I want.

LONG custom_gui_type_table[] ={
LONG GetResourceDataType(LONG*& table){
	table = custom_gui_type_table;
	return sizeof(custom_gui_type_table) / sizeof(Int32);

Now, the user area draws an image using DrawBitmap. I want to allow the user to change the image by loading a different one.
To do that, I need to pass the new filename into the user area.
So, inside the SetDParameter of a TagData plugin, I need to update the filename into my GeUserArea.

Thank you very much for your time !

On 07/07/2017 at 07:32, xxxxxxxx wrote:


sorry, this took a bit longer. It was an interesting question, which then in the end turned out to be easier to achieve, than expected.

So, I set up a CustomGUI for a string data type. In CreateLayout() of the iCustomGui implementation I added a BitmapButtonCustomGui to represent your image. The key is in the iCustomGui constructor, there you get a settings BaseContainer, which is actually a Description BaseContainer. Here I store the path to be found in the settings container in a member variable for later use in CreateLayout(), where I set the image of the BitmapButton after adding the actual button.

In order to be able to set the image via resource file I added a property CUSTOMTYPE_STRING to the propertries table returned by CustomGuiData::GetProperties(). The ID of this property is also the ID to be used, when reading the filename from the settings BaseContainer.

For testing purposes I used an ObjectData with a string parameter using the CustomGUI and an additional Filename parameter. In GetDDescription() you basically do the same as when adding or modifying a Description. Roughly like so:

		const DescID* singleid = description->GetSingleDescID();
		if (fn.Content()) // if filename parameter is empty, the default set for IMGFILENAME in resource file will be used
			if (!singleid || cid.IsPartOf(*singleid, nullptr))
				BaseContainer settings = GetCustomDataTypeDefault(DTYPE_STRING);
				settings.SetString(ID_STRINGWITHIMAGE_PROP_IMGFILENAME, fn.GetString()); // Read this in iCustomGui constructor
				description->SetParameter(cid, settings, ID_OBJECTPROPERTIES);

And that's about it. When the Filename parameter gets changed, the image of the String CustomGUI changes accordingly.

On 17/07/2017 at 07:21, xxxxxxxx wrote:

Hello and thank you for your answer.

Right now I have defined this parameter in .res file as LONG:


To set and get its value using data instance I do the following:

BaseContainer* data = baselist2d->GetDataInstance(); //checks are skipped for this example
data->SetInt32(MY_PARAM, 32);//example

How can I do that if MY_PARAM parameter is both LONG and STRING ?
Does the following work ?

//Can I use the same param ID for 2 types ?
data->SetInt32(MY_PARAM, 32);
data->SetString(MY_PARAM, "testing string");

Your code uses GetDDescription to add the param dynamically. Can I do without using GetDDescription ?
Also, I need to be able to modify the image path in SetDParameter.


switch (id[0].id) {
		String new_path = t_data.GetString();
		data->SetInt32(MY_PARAM, 32); 
		data->SetString(MY_PARAM, new_path);

Can I do the above ?

Thank you for your time Andreas !

On 18/07/2017 at 02:58, xxxxxxxx wrote:

Hm, maybe I misunderstood your first posts, but I thought it was a CustomGUI for LONG type. And additionally you had the need to pass a string/filename to the CustomGUI so it shows some image.

What I tried to demonstrate in my post, you can pass additional data via the description container to your CustomGUI. And my example also works with the parameter defined in a resource file. I just use GetDDescription to pass the extra data by "modifying" the description.

As the values are stored in a BaseContainer under a certain ID, you can not store two values of different type under the same ID, but I tried to show with my post, that this is not actually needed.

On 18/07/2017 at 05:41, xxxxxxxx wrote:

Hello and thank you very much for your help.

Here is what I did.


const DescID* single_id = description->GetSingleDescID();
DescID cid = DescID( DescLevel( USER_AREA_PARAM, DTYPE_LONG, 0 ) );
if ( !single_id || cid.IsPartOf(*single_id, NULL) ) {
	BaseContainer settings = GetCustomDataTypeDefault(DTYPE_LONG);
	settings.SetString(IMAGE_PATH_STRING, image_filename);
	if (!description->SetParameter(cid, settings, DescLevel(GROUP_PARAM_ID))) {
		return FALSE;

Property table and type:

static CustomProperty table_properties[] = {
LONG table_type[] = {

In iCustomGui Constructor:
image_path = settings.GetString(IMAGE_PATH_STRING);

In iCustomGui CreateLayout:
//AttachUserArea(user_area, ....);

As it is right now, it works exactly as I want.
The problem is that since I have to load a new image based on the path, it happens constantly every time the layout is changed.

Can I use SetDParameter to set a value in IMAGE_PATH_STRING of USER_AREA_PARAM ?
It feels like I have to use a CustomDataType.

Thank you for your time !

On 18/07/2017 at 05:44, xxxxxxxx wrote:

Can't you just compare against the last path used (maybe also file date)?

But yes, if you want to be able to use SetDParameter() in order to set the string and the integer, you will have to come up with your own datatype consisting of both components.

On 18/07/2017 at 06:22, xxxxxxxx wrote:

Originally posted by xxxxxxxx

Can't you just compare against the last path used (maybe also file date)?

I'll keep the path in a member in the ObjectData that has the user area parameter. Once this parameter is changed, I'll listen to MSG_DESCRIPTION_POSTSETPARAMETER to compare the previous value with the new one. I'll also copy the path member in CopyTo.

I cannot keep the member in the gadget since it is constantly created from scratch everytime the layout is changed.

Thank you.

On 19/07/2017 at 06:04, xxxxxxxx wrote:

I'm not quite sure, if there's still an issue left or if you have found a solution that suits you?

On 20/07/2017 at 00:03, xxxxxxxx wrote:


I mark it as solved.

Thank you again Andreas !