Validate data in a ToolPlugin [SOLVED]

On 12/07/2015 at 02:19, xxxxxxxx wrote:

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

I have a ToolPlugin for which I want to validate some data before accepting it.
I already know how to find out what gizmo has changed, inside the Message method, with the code:
          DescriptionCheckUpdate *dc = static_cast<DescriptionCheckUpdate*>(t_data);
          DescID idNum;
          idNum = (*dc->descid)[0].id;
          LONG gizmo = idNum[0].id;

if (gizmo==MDATA_RGBA)

But I need to know the value that the user inserted.
I found this code in this forum:
GeData d;
tag->GetParameter(DescID(idNum), d, DESCFLAGS_GET_0);
Real gizmoValue = d.GetReal();**

But this is for a tag plugin, where the Message method includes a parameter GeListNode *node and we can get the tag with BaseTag *tag = (BaseTag* )node;
But, how can I get that with a Tool plugin?

On 12/07/2015 at 06:47, xxxxxxxx wrote:

ToolData plugins don't have descriptions.  They use a subdialog instead and you will need to store the 'descriptions' either in your own container or as class member variables.

You might want to use a DescriptionToolData plugin since the description data is passed along to Message() and so on.  There are examples in the cinema4dsdk under tool : SnapTool, Scrulpting, and PickObject.

On 12/07/2015 at 07:03, xxxxxxxx wrote:

What I actually need is the value of the gizmo the user just choose.
For example, my Tool plugin has a ComboBox with ID 1000 that containns three items with IDs 0,1 and 2. I can easily get the ID of the gizmo the user just changed. In my case, the ID 1000. But I need to know what value it just choose. Isn't that value somewhere in the dc that I get from DescriptionCheckUpdate *dc = static_cast <DescriptionCheckUpdate*>(t_data); ?

On 12/07/2015 at 07:04, xxxxxxxx wrote:

I don't really need to validate it. I just need to know the value that the user choose so that I can do something, depending on that.

On 12/07/2015 at 07:24, xxxxxxxx wrote:

I tried this:
if (gizmo==MDATA_RGBA)
     LONG tool_id = doc->GetAction();

BasePlugin *tool = NULL;

tool = FindPlugin(tool_id, PLUGINTYPE_TOOL);

if (tool)
          LONG value;
          GeData d;
          tool->GetParameter(DescID(idNum), d, DESCFLAGS_GET_0);


Didn't work 😞

On 12/07/2015 at 07:25, xxxxxxxx wrote:

I mean... it tells me the value that WAS there, not the new value choosen by the user.

On 12/07/2015 at 09:16, xxxxxxxx wrote:

So, we only get what element was changed but we can't have access to the value of that element?

On 12/07/2015 at 11:34, xxxxxxxx wrote:

Could I be checking for the wrong message?
If it is, the structure is only:

struct DescriptionValidate
Int32 flags;

So, I see no data there that could be useful to me 😞

On 13/07/2015 at 01:20, xxxxxxxx wrote:

Well, I solved it by using a good old "previous state" global variable.
But there should be a way to know what value a user inputted, through the description structure.

On 13/07/2015 at 03:07, xxxxxxxx wrote:


ToolData is not based on NodeData so it works a little bit different. As Robert said, you define the GUI of a Tool using a Subdialog. In that subdialog class the Command() function is called when you change a GUI element. You have to catch that event to update the BaseContainer storing the settings of your tool. The tool settings are accessible with GetToolData(). In the GeDialog class you find functions to easily copy the current value from the GUI element into the given BaseContainer ("Container Get").

Best wishes,

On 13/07/2015 at 04:32, xxxxxxxx wrote:

Oh, so I should keep a copy of the container of the dialog?
But only for reading purposes, right? Because there seems to be no SetToolData counterpart.
I just have my Tool dialog set with a res file and I work directly on the provided node (when there is one provided). Is that ok or it is something to avoid?

On 13/07/2015 at 11:18, xxxxxxxx wrote:


GetToolData() returns a pointer to the BaseContainer. So you can read and write the settings using this pointer.

Best wishes,

On 24/07/2015 at 11:32, xxxxxxxx wrote:

Hello Rui,

was your question answered?

Best wishes,

On 24/07/2015 at 11:48, xxxxxxxx wrote:

Well, I got parallel information that was useful 🙂
But the initial question was not answered. I still can't detect what gizmo was changed, when it gets changed.
However, I solved it but using global class variables that store the old values of gizmos and I go through all of them to check if some changed.
Not as efficient or elegant... but it works.

On 27/07/2015 at 01:01, xxxxxxxx wrote:


as said before, you can implement Command() in your subdialog to catch an event when a dialog gadget was changed. You can write the new value in to the tool's BaseContainer that can be accessed with GetToolData().

Best wishes,

On 27/07/2015 at 01:18, xxxxxxxx wrote:

Yes, but I will have to create a duplicate of the dialog container, or at least keep variables to check the old value against the new, right?
Because Cinema 4D doesn't tell me what was the changed parameter.

On 27/07/2015 at 09:57, xxxxxxxx wrote:


GeDialog::Command() receives the ID of the changed gadget with the "id" argument. So you can easily update the BaseContainer.

Best wishes,

On 28/07/2015 at 09:01, xxxxxxxx wrote:

Oh, I get it now 🙂
Thank you.