Core Messages Manual

About

Core messages are sent around Cinema 4D to inform various parts of the application about events and changes. This is done so that different parts of the interface can update their status (e.g. Attribute Manager, Viewport, etc.).

Note
Other important message types are messages sent to an C4DAtom based element (see C4DAtom Manual and NodeData::Message() Manual) and GUI and Interaction Messages Manual.

EventAdd

When the active document is changed by some operation one must inform Cinema 4D about it so Cinema 4D can update the GUI.

Valid flags are:

Note
This is only needed when the active document is changed. It is not needed when a virtual or internal document is edited or when objects are handled that are not part of a document.
Events are not sent if no GUI exists (if CINEMAINFO_FORBID_GUI is true).
Warning
Do not use EventAdd() in a threaded context.
// This example shows how to create a new "Cube" object and how to insert it into the document.
if (!document)
return false;
if (!object)
return false;
object->SetName("This is a new object");
document->InsertObject(object, nullptr, nullptr);

Catching Messages

Core messages are sent to update the GUI so it is possible to catch core messages in custom GUI elements:

When EVMSG_CHANGE is received, GeDialog based custom panels typically re-initialize their values by calling GeDialog::InitValues().

It is also possible to catch core messages with a MessageData plugin:

// This example MessageData::CoreMessage() catches EVMSG_CHANGE to detect any change.
Bool CoreMessage(Int32 id, const BaseContainer& bc)
{
if (id == EVMSG_CHANGE)
{
if (false)
GePrint("Something was changed.");
}
return true;
}

A core message can contain a BaseContainer argument. This container may store these values:

Message Types

These are Cinema 4D's core messages:

// This example catches EVMSG_ASYNCEDITORMOVE in a GeDialog.
{
// check if this core message is new
if (CheckCoreMessage(bc))
{
const Int movement = (Int)bc.GetVoid(BFM_CORE_PAR1);
switch (movement)
{
case MOVE_START: { GePrint("Start Movement"); break; }
case MOVE_CONTINUE: { GePrint("Continue Movement"); break; }
case MOVE_END: { GePrint("End Movement"); break; }
}
}
break;
}
// This example catches EVMSG_UPDATESCHEME in a GeDialog
// to be informed when the scheme is changed.
{
// check if this core message is new
if (CheckCoreMessage(bc))
{
const Int scheme = (Int)bc.GetVoid(BFM_CORE_PAR1);
switch (scheme)
{
case SCHEME_LIGHT: { GePrint("Light Scheme"); break; }
case SCHEME_DARK: { GePrint("Dark Scheme"); break; }
case SCHEME_OTHER: { GePrint("Other Scheme"); break; }
}
}
break;
}

Custom Messages

It is possible to send custom, asynchronous core messages. This can be used to send a message from a custom thread into the main thread.

// This example sends a custom core message.
SpecialEventAdd(ID_CUSTOMEVENT, 123, 456);
// This example catches a custom core message.
case ID_CUSTOMEVENT:
{
const Int value1 = (Int)bc.GetVoid(BFM_CORE_PAR1);
const Int value2 = (Int)bc.GetVoid(BFM_CORE_PAR2);
const String value1String = String::IntToString(value1);
const String value2String = String::IntToString(value2);
GePrint("Value 1: " + value1String + ", value 2: " + value2String);
break;
}

Other Functions

Other functions to send core messages are:

// This example forces an update of the attribute manager.

Further Reading