Dialog Layout

The layout of a Cinema 4D dialog is specified in the GeDialog::CreateLayout() function. This function, which should always be overridden in derived dialog classes, is called by Cinema 4D whenever a dialog is opened.
There are two ways to specify the layout:

Layout Files

The recommended way is to use layout files, just as Cinema 4D does internally. Then GeDialog::CreateLayout() becomes as easy as:

Bool MyDialog::CreateLayout()
{
return LoadDialogResource(MYDIALOG, nullptr, 0);
}

MYDIALOG corresponds to a MYDIALOG.res file in the dialogs directory of the res folder.
This file might look like this:

DIALOG MYDIALOG
{
  NAME DIALOG_TITLE;

  GROUP MYGROUP
  {
    COLUMNS 1;
    SPACE 4,4;
    BORDERSIZE 4,4,4,4;

    STATICTEXT { NAME HELLO_WORLD; }
  }

  DLGGROUP { OK; CANCEL; }
}

See Dialog Resource for more information.

Using a separate dialog resource like this has several advantages. Besides that it is easy to edit the dialog layout, it also facilitates international support greatly.
The NAME fields above does not specify their strings directly. Instead they point to the strings in the MYDIALOG.str file in the dialogs directory of the strings_us folder:

DIALOGSTRINGS MYDIALOG
{
  DIALOG_TITLE "My Dialog";
  HELLO_WORLD "Hello World!";
}

To support German as well, just copy the strings_us directory to a new strings_de directory, and change the above file to:

DIALOGSTRINGS MYDIALOG
{
  DIALOG_TITLE "Mein Dialog";
  HELLO_WORLD "Hallo Welt!";
}

Resources are handled by the global ::resource object. GeResource::LoadString() can be used to load other localizable strings (for example member messages), from the file c4d_strings.str:

STRINGTABLE
{
  MYERROR "Oops! Something went wrong.";
}

The string files are stored in Unicode, which means that they handle almost every language there is.

Note
The encoding is 7-bit ASCII with other characters encoded as \uHHHH. For example 'Natürlich' is written 'Nat\u00fcrlich'. Byte-order marks are not used.

The ID MYERROR must be available as an enum in the c4d_symbols.h file. This also applies to the ID of the dialog resource:

enum
{
  MYDIALOG = 10000,
  MYERROR = 10001
};

This file is automatically read by Cinema 4D when it parses the plugin resources, but it must be included in the plugin source code to access the IDs:

#include "c4d_symbols.h"

Manual Layout

If for some reason you do not want to use dialog resources, all the resource commands for adding groups and dialog components are functions in the GeDialog class.
So then the above dialog's CreateLayout() function would look like this:

MyDialog::CreateLayout()
{
SetTitle("My Dialog");
GroupBeginV(100010, 0, 1, 0, "", 0);
{
GroupSpace(4, 4);
GroupBorderSpace(4, 4, 4, 4);
AddStaticText(-1, 0, 0, 0, "Hello World!", 0);
}
GroupEnd();
AddDlgGroup(DLG_OK | DLG_CANCEL);
return true;
}
Note
Now all the localization features are lost, unless all strings are loaded manually with the GeResource class.