Parent document is top of "Motif FAQ (Part 7 of 9)"
Previous document is "233) How can I avoid C++ String class and typedef char *String"
Next document is "235) Is there a Common Lisp binding for Motif?"
234) How can I have a C++ member function in a callback?
[Last modified: Oct 94]
Answer: There are three common user problems with C++ callbacks. First, make
sure you use the correct function prototype for the function declarations.
Second, the callback function must be declared as a static member of the
class. Third, when registering it with XtAddCallback(), you must use its full
signature. For example: (from Ken Lee, http://www.rahul.net/kenton/)
class MyClass {
...
void createWidgets();
static void myButtonCB(Widget, XtPointer, XtPointer);
...
};
void MyClass::createWidgets() {
...
w = XtCreatePushButton(...);
XtAddCallback(w, XmNactivateCallback, &MyClass::myButtonCB,
(XtPointer) this);
...
}
void myButtonCB(Widget w, XtPointer clientData, XtPointer callData) {
MyClass *myclass = (MyClass *) clientData;
...
}
Note that the "this" pointer is used as the client data. This technique is
popular, but not required.
Motif++ has a nice tutorial summarizing mechanisms (Ronald van Loon,
rvloon@motif.xs4all.nl). See his articles in the September, 1994 and
Nov/December, 1994 issues of C++ Report.
Doug Young's book deals extensively with one of these. The problem is that you
don't get the object when you just use the function as a callback. You need
to pass the object as a pointer through as the client_data. (use "this" as
the client_data.) Then you can retrieve the object's address, and dereference
from there. For example (Leo O'Donnell, Email: leo@avs.com),
class MyButton {
public:
MyButton (Widget parent, const char *name) {
_button = XtVaCreateManagedWidget (
name, xmPushButtonWidgetClass, parent, NULL, 0);
XtAddCallback (
_button,
XmNactivateCallback,
&MyButton::activateCB,
(XtPointer) this);
}
~MyButton () { XtDestroyWidget (_button); }
private:
Widget _button;
static void activateCB (Widget, XtPointer, XtPointer);
};
void MyButton::activateCB (Widget, XtPointer thisBtn, XtPointer)
{
MyButton *btn = (MyButton *) thisBtn;
// OK you've got the button instance now. Do some stuff with it!
}
Parent document is top of "Motif FAQ (Part 7 of 9)"
Previous document is "233) How can I avoid C++ String class and typedef char *String"
Next document is "235) Is there a Common Lisp binding for Motif?"