t_control * ODBG2_Pluginoptions(UINT msg,WPARAM wp,LPARAM lp);

Optional plugin callback function, called when user opens Plugin options dialog, when user changes state of the controls and when dialog is closed.

During the first call
(msg=WM_INITDIALOG) plugin must return pointer to the page description (array of structures t_control). Each new page in the array must begin with the record of type CA_COMMENT. Array must end with the record of type CA_END. Size of the options page is 250x256 units, but left part is occupied withthe list of pages and there are buttons on the bottom. Therefore plugins may use only part of it, 80 .. 240 units horizontally and 0 .. 235 units vertically. If plugin returns NULL, OllyDbg will not bother it again.

When dialog receives WM_COMMAND, it passes this message to ODBG2_Pluginoptions(). Returned value is ignored. Note that if plugin uses control variables (member var in t_control), usually it does not need to process this message. Checkboxes, radio buttons and list boxes change the state of associated control variable automatically. Edit controls modify text. Processing of WM_COMMAND is necessary only if you use pushbuttons or custom controls.

Finally, when user closes dialog, this entry is called for the last time
with msg=WM_CLOSE and wp=1 on OK or 0 on Cancel. Returned value is ignored. This is the best time for plugin to adopt new settings. If user pressed Cancel, OllyDbg automatically restores control variables and edit texts. Plugin should restore custom controls by itself.

To open Plugin options on the page belonging to the plugin, use Pluginshowoptions().


(in) WM_INITDIALOG, WM_COMMAND or WM_CLOSE, see explanation above
(in) If msg=WM_COMMAND, repeats corresponding parameter of WM_COMMAND. If msg=WM_CLOSE, wp is 1 if user pressed OK and 0 if Cancel. In all other cases it is 0
(in) If msg=WM_COMMAND, repeats corresponding parameter of WM_COMMAND. In all other cases it is 0

Return values:

If msg=WM_INITDIALOG, it must return pointer to the page description. In all other cases returned value is ignored

Example of page description:

This is the description of the options in API trace plugin:

static int       protocolapi;          // Protocol API calls
static int       skipgdi32;            // Don't protocol GDI32 APIs
static int       skipuser32;           // Don't protocol USER32 APIs
static int       skipkernel32;         // Don't protocol KERNEL32 APIs
static int       skipmsvc;             // Don't protocol MSVC* APIs
static int       protocolret;          // Protocol returned values
static int       autoupdate;           // Whether window in autoupdate mode

typedef struct t_control {             // Descriptor of dialog control
  ulong          type;                 // Type of control, CA_xxx
  int            id;                   // Control's ID or -1 if unimportant
  int            x;                    // X coordinate, chars/4
  int            y;                    // Y coordinate, chars/8
  int            dx;                   // X size, chars/4
  int            dy;                   // Y size, chars/8
  int            *var;                 // Pointer to control variable or NULL
  wchar_t        *text;                // Name or contents of the control
  wchar_t        *help;                // Tooltip or NULL
  int            oldvar;               // Copy of control variable, internal
} t_control;

static t_control traceapioptions[] = {

  { CA_COMMENT, -1,              0,   0,   0,   0, NULL,
                  NULL },
  { CA_TITLE,   OPT_TITLE,      80,   4, 160,  15, NULL,
                  NULL },
  { CA_CHECK,   OPT_1,          90,  26, 120,  10, &protocolapi,
                  L"Protocol API calls",
                  L"Protocol calls and call arguments to the log" },
  { CA_CHECK,   OPT_2,         105,  38, 160,  10, &skipgdi32,
                  L"Don't protocol GDI32",
                  L"Ignore all APIs that reside in GDI32" },
  { CA_CHECK,   OPT_3,         105,  50, 160,  10, &skipuser32,
                  L"Don't protocol USER32",
                  L"Ignore all APIs that reside in USER32" },
  { CA_CHECK,   OPT_4,         105,  62, 160,  10, &skipkernel32,
                  L"Don't protocol KERNEL32",
                  L"Ignore all APIs that reside in KERNEL32" },
  { CA_CHECK,   OPT_5,         105,  74, 160,  10, &skipmsvc,
                  L"Don't protocol MSVC*",
                  L"Ignore all APIs that reside in Visual C libraries" },
  { CA_CHECK,   OPT_6,         105,  86, 160,  10, &protocolret,
                  L"Protocol returned values",
                  L"Protocol values that called API function returned" },
  { CA_END,     -1,              0,   0,   0,   0, NULL,

First record is CA_COMMENT. It specifies the text that will be displayed in the list of option pages. Record CA_TITLE describes the title of the page. Controls CA_CHECK are checkboxes. Their initial state is defined by the corresponding variables pointed to by var. When user changes state of some checkbox, OllyDbg updates the value of the variable.

Note that checkboxes and some other controls, like static texts or radio buttons, set their width authomatically, effectively ignoring dx. Details are described here.

Standard controls should have identifiers in the range OPT_1 .. OPT_24. Custom controls (and standard controls if you create more than 24 of them) may use identifiers from the range OPT_CUSTMIN .. OPT_CUSTMAX. Other values may conflict with the internal identifiers used by OllyDbg and should be avoided.

If plugin requires several option pages, start each new page with CA_COMMENT. Don't forget to place CA_END at the end, or OllyDbg may crash.

See also:
Dialogs, plugins, t_control, Pluginshowoptions()