home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!mcsun!uknet!glasgow!edrc!a_mahmoo
- From: a_mahmoo@edrc.ac.uk (Arshad Mahmood)
- Newsgroups: comp.lang.c++
- Subject: Re: Callbacks - C++ needs an extension?
- Message-ID: <1992Sep7.173259.7012@edrc.ac.uk>
- Date: 7 Sep 92 17:32:59 GMT
- References: <DAVIDM.92Aug31105639@consilium.com> <la83j0INN839@appserv.Eng.Sun.COM>
- Sender: news@edrc.ac.uk (News System)
- Organization: Engineering Design Research Centre
- Lines: 159
-
- A slightly different approach as covered in D. Young's book is to rely on a
- global callback (and event handler), which supplies the implicit this
- pointer to the method (accellarators are probably still best handled as
- per David's solution). The code below (not taken from Young, I wrote this
- before the book was published) is an example of how this can be
- done (in this case your classes have to be subclasses of XCC to make use of
- this facility, no doubt other's can think of other ways to go about it
- (any ideas on how to implement this in a much nicer way are welcome, the
- class LIST and LIST_Iterator are NOT supplied get in touch if you want to
- make use of it, and I will supply you the rest of code and an example).
-
- /*
- File: XCC.h
- Description:
- My rather daft way of implementing callbacks for C++.
- */
-
- #ifndef _XCC_H
- #define _XCC_H
-
- #include <X11/Intrinsic.h>
- #include "list.h"
-
- class XCC;
-
- typedef void (XCC::*Callback)(Widget, void*, void*);
- typedef void (XCC::*EventHandler)(Widget, void*, XEvent*);
-
- class XCC {
- public:
- XCC();
- ~XCC();
-
- void AddCCCallback(Widget w, char* name, Callback cb, void* client_data);
- void AddCCEventHandler(Widget w, EventMask, Boolean, EventHandler, void*);
-
- private: /* if you're using gnu the next two functions have to be public */
- static void theCallback(Widget, void*, void*);
- static void theHandler(Widget, void*, XEvent*);
-
- LIST client_data_list;
- };
-
- #define AddCallback(w,name,cb,cdata) AddCCCallback(w,name, (Callback)&cb,cdata)
-
- #define AddEventHandler(w,mask,nonmaskable,handler,cdata) \
- AddCCEventHandler(w,mask,nonmaskable,(EventHandler)&handler, cdata)
-
- #endif _XCC_H
- -----------------------------------------
- /*
- File: XCC.C
-
- */
-
- #include "XCC.h"
- #include "list_it.h"
-
- /*
- XCCStruct - This structure is passed as client data to the event handlers
- and callbacks, it passes the implicit this pointer "me" so
- so that member functions may be passed as callbacks and
- event handlers.
- */
-
- typedef struct
- {
- XCC* me;
- EventHandler handler;
- Callback callback;
- void* client_data;
- } XCCStruct;
-
- XCC::XCC()
- {
- }
-
- XCC::~XCC()
- {
- LIST_Iterator it(client_data_list);
- XCCStruct* x;
-
- foreach(it,XCCStruct*,x) delete x;
- }
-
- /*
- AddCCCallback - like the toolkit function XtAddcallback this one
- adds a particular member function as a callback. In order to use
- C++, I have routed all callbacks through one central callback
- (XCC::theCallback), the client data for this tells it what to
- do above and beyond that.
- */
-
- void XCC::AddCCCallback(Widget w, char* name, Callback cb,
- void* client_data)
- {
- XCCStruct* x = new XCCStruct;
-
- x->callback = cb;
- x->client_data = client_data;
- x->me = (XCC *)this;
-
- XtAddCallback(w, name, (XtCallbackProc)XCC::theCallback, (XtPointer)x);
- client_data_list.InsertAtEnd((void *)x);
- }
-
- /*
- AddCCEventHandler - Register a C++ event handler, as with the callbacks
- all events pass through a central handler
- (theHandler)
- */
-
- void XCC::AddCCEventHandler(Widget w, EventMask mask, Boolean nonmaskable,
- EventHandler handler, void* client_data)
- {
- XCCStruct* x = new XCCStruct;
-
- x->handler = handler;
- x->client_data = client_data;
- x->me = (XCC *)this;
-
- XtAddEventHandler(w, mask, nonmaskable, (XtEventHandler)XCC::theHandler,
- (XtPointer)x);
- client_data_list.InsertAtEnd((void *)x);
- }
-
- /*
- theCallback - This is the central callback for all callbacks
- registered as members of classes. It's a static member
- of the class.
- */
-
- void XCC::theCallback(Widget w, void* client_data, void* call_data)
- {
- XCCStruct* cb_struct = (XCCStruct *)client_data;
- XCC* mclass = cb_struct->me;
-
- (mclass->*(cb_struct->callback))(w, cb_struct->client_data, call_data);
- }
-
- /*
- theHandler - This is the central handler through which all C++ based
- Event Handlers work.
- */
-
- void XCC::theHandler(Widget w, void* client_data, XEvent* event)
- {
- XCCStruct* cb_struct = (XCCStruct *)client_data;
- XCC* mclass = cb_struct->me;
-
- (mclass->*(cb_struct->handler))(w, cb_struct->client_data, event);
- }
-
- ------------------------ end of XCC.C --
- Regards,
- A. Mahmood
- Systems Manager
- EDRC
- e-mail: a_mahmoo@uk.ac.edrc
-