Search the FAQ Archives

3 - A - B - C - D - E - F - G - H - I - J - K - L - M
N - O - P - Q - R - S - T - U - V - W - X - Y - Z
faqs.org - Internet FAQ Archives

Motif FAQ (Part 7 of 9)
Section - 232) How can I have a C++ member function in a callback?

( Part1 - Part2 - Part3 - Part4 - Part5 - Part6 - Part7 - Part8 - Part9 - Single Page )
[ Usenet FAQs | Web FAQs | Documents | RFC Index | Sex offenders ]


Top Document: Motif FAQ (Part 7 of 9)
Previous Document: 231) How can I avoid C++ String class and typedef char *String
Next Document: 233) Is there a Common Lisp binding for Motif?
See reader questions & answers on this topic! - Help others by sharing your knowledge
[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 = XmCreatePushButton(...);
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!
}


User Contributions:

Comment about this article, ask questions, or add new information about this topic:




Top Document: Motif FAQ (Part 7 of 9)
Previous Document: 231) How can I avoid C++ String class and typedef char *String
Next Document: 233) Is there a Common Lisp binding for Motif?

Part1 - Part2 - Part3 - Part4 - Part5 - Part6 - Part7 - Part8 - Part9 - Single Page

[ Usenet FAQs | Web FAQs | Documents | RFC Index ]

Send corrections/additions to the FAQ Maintainer:
kenton@rahul.net (Ken Lee)





Last Update March 27 2014 @ 02:11 PM