Dialog boxes and callbacks – Crunch CRiSP File Editor 6 User Manual

Page 66

Advertising
background image

Page 66

every time you click that button, the number is incremented. Where do you store the current value of the
label? (You can use the label itself, but this is a special case, and doing so fails to illustrate the point being
made here).

You can use a global variable, e.g. something like this:

int counter;

void
create_counter_dialog()
{
counter = 0;
create_object(make_list(
DBOX_TITLE, "Counter Example",
DBOX_CALLBACK, "counter_callback",

DBOX_LABEL, "Current value: " + counter,
DBOX_NAME, "counter",
DBOX_BUTTON, " Increment! "
));
}
void
counter_callback(int reason, int obj_id, int sub_obj, string name_id)
{
change_object(obj_id, "counter",
DBOX_VALUE, "Current value: " + ++counter);
}

This is fine but if you now create two dialog boxes at once then this will not work, since the two dialog boxes
do not have their own counter.

As mentioned above, you could get around this problem by having a list of counter values but it is tedious to
maintain the list, especially as the dialog boxes can be created and destroyed in an arbitrary order.

The solution to this problem is the use of a property. Analogues exist in other windowing systems, e.g.
Windows allows the use of atoms, as does X11. A property is simply an arbitrary value associated with a
specific dialog box. This is a symbol table containing arbitrary symbols (of any supported datatype). This
symbol table allows you to stash dialog specific state information away and then later access and/or change
the property values in your callbacks. This gets rid of the need for any global variables in your macro
implementation and allows multiple instances of a dialog box to be created with very few problems.

Properties are created or set, via the set_property() primitive; they are retrieved with the get_property()
primitive:

declare get_property(int obj_id, int rsvd, string name);

int set_property(int obj_id, int rsvd, string name, declare value);

Dialog boxes and Callbacks

The Microsoft Windows API and the Xt/Motif API are similar in a number of very basic areas, but the actually
look and feel of the code is different. In a pure Windows program (without any MFC usage), you tend to see
huge functions which handle the callbacks for specific dialog boxes, and these huge functions are typified by
a large switch statement handling each of the possible actions the program implements. By contrast,
Xt/Motif applications tend to be typified by lots of little callback functions, each callback handling the
semantic actions of a single object in a dialog box.

Each approach has its advantages and disadvantages. (Having a single callback makes it easy to navigate
code since you have a small number of callback functions to consider, and it is usually easy to pin point the
one of interest; on the other hand, huge functions tend to blow compilers and optimisers and other source
code analysers out of the water, and are not necessarily easy to maintain unless you follow some rigorous
coding standards; With the Xt/Motif approach, you tend to have a lot of tiny functions, and it can be very
difficult to find the function of interest, again unless you are very consistent with your naming conventions).

Advertising