SOLVED Discover when a tag has been disabled

Hello guys,
I am trying to detect when a tag is enabled/disabled(here target camera specifically).
For that purpose I am looking at the messages coming from cinema4d.
While I can identify the messages id pattern: I receive 604, 1018484 and then 1685218156.
I cannot retrieve from which message those ID belong to.

  1. How can I know when a tag has been disabled or not? If there a solution with the messages shown or a simpler one ?

I Also noticed, that I receive the same message when I click on the button located on the left of Enable (see image below).


  1. What the purpose of the button located on the left of Enable?

Thank you in advance for your reply.

  1. It depends where you want to know the tag was disabled? It also depends if you want to get triggered by the tag being enabled/disabled, or simply wants to check at given time if tag is enabled/disabled?

If you want to know from within the TagData-derived object the enable state of the tag you can (with a method receiving a GeListNode* node as argument) do:

BaseTag* tag = (BaseTag*)node;

Bool enabled = false;
if (tag)
	GeData d;
	tag->GetParameter(<your tag's ENABLE-id>, d, DESCFLAGS_GET::NONE);
	enabled = d.GetBool();

If you want to get triggered by the change of state then:

Bool YourTagDataDerivedClass::Message(GeListNode* node, Int32 type, void* data)
		DescriptionPostSetValue* postsetval = static_cast<DescriptionPostSetValue*>(data);
		if (postsetval && (*postsetval->descid == DescID(<your tag's ENABLE-id>)))

... and same as above: you get the state of the enable-parameter
  • or -
Bool YourTagDataDerivedClass::SetDParameter(GeListNode* node, const DescID& id, const GeData& t_data, DESCFLAGS_SET& flags)
	if (!node)
		return false;

	const Int32& gadgetID = id[0].id;
	switch (gadgetID)
		case <your tag's ENABLE-id>:
			enabled = t_data.GetBool();

  1. I guess the button in front of the "Enable" label is the keyframe button, so you can animate the tag being enabled/disabled over time.

Thank you for your reply, I guess there is no way to observe a tag if you are not implementing it.


Hello @user168462,

Thank you for reaching out to us. You said,

"I guess there is no way to observe a tag if you are not implementing it."

It depends a bit on how you mean that and how you mean your question in general. @C4DS gave you already a very nice answer (thanks for that). There are basically two scenarios (which effectively will become one):

  1. There is a specific BaseTag instance tag where you did not implement the tag type yourself and you want to track changes for that specific tag instance for a specific parameter.
  2. There is a BaseTag type t where you did not implement the tag type yourself and you want to track changes of a parameter for all tags of that type in a scene.

One might be tempted to solve option 1 by simply storing a pointer to that BaseTag and then periodically look up the tag to track changes. But this will not work due to node reallocation. This problem can be solved by either using the Baselink type or by manually traversing a document tree/graph and identifying nodes by their unique id stored under MAXON_CREATOR_ID. This second approach (traversing the whole document tree) is also what is the solution to option 2.

To carry out the periodical checking, the most straight forward option is to the core message EVMSG_CHANGE. You can do this in a MessageData plugin or GeDialog derived GUIs. An alternative approach is to implement a SceneHookData plugin and do the traversing in its Execute() method.

TLDR: While the Cinema 4D classic API does not have a dependency graph or a very granular event system, scene changes can be tracked with EVMSG_CHANGE. It is only that it is up to the user to find out if the change that occurred is of relevance as Cinema 4D does not give any context for the cause of EVMSG_CHANGE.