pete@TIRS.oz.au (Peter Bartel) (05/24/91)
When writing an XView program with C++, you can specify a function to be called when a button is pressed by: class my_class { virtual void member_func1(void); }; void my_class::member_func1(void) { extern void callback_routine(Panel_item, Event*); xv_set(button, PANEL_NOTIFY_PROC, callback_routine); } In the above case, callback_routine is an ordinary function; not a member of any class. My question is: how do I tell XView to use a member function as the panel notify procedure? What I want is something similar to the following (which doesn't work). class my_class { virtual void member_func1(void); virtual void member_func2(Panel_item, Event*); }; void my_class::member_func1(void) { xv_set(button, PANEL_NOTIFY_PROC, member_func2); } void my_class::member_func2(Panel_item item, Event *event) { fprintf(stderr, "hello"); } _______________________________________________________________________ Peter Bartel Senior Software Engineer International Phone: +61-8-232-1740 Railroad Faxstream: +61-8-232-2274 Systems E-mail: pete@TIRS.oz.au (Electronics) Snail: 209-217 Wakefield St, Adelaide, South Australia, 5000
warsaw@nlm.nih.gov (Barry A. Warsaw) (05/25/91)
>>>>> "Peter" == Peter Bartel <pete@TIRS.oz.au> writes: Peter> In the above case, callback_routine is an ordinary Peter> function; not a member of any class. My question is: how do Peter> I tell XView to use a member function as the panel notify Peter> procedure? What I want is something similar to the Peter> following (which doesn't work). [Example deleted for brevity] The problem with using a (non-static) member function for a callback is that it implicitly requires a `this' pointer, but the XView notifier can't put one on the stack before calling your member function. Fortunately, there's a very simple workaround (and this is what makes using XView with C++ fairly nice). When you're setting up the PANEL_NOTIFY_PROC, you want to use XV_KEY_DATA to attach the `this' pointer to the XView object. Next make the PANEL_NOTIFY_PROC a *static* member function (which does not require an implicit `this') and in this function, extract the key data placed on the object. Then use this object to call the member function that does the guts of your callback. Something similar to the following should do the trick. One caveat: I don't use this code fragment verbatim, but I do things along these lines. Just be aware that I haven't tested this exact example out, but it *should* work. ;-} Hope this helps. -Barry NAME: Barry A. Warsaw INET: warsaw@nlm.nih.gov TELE: (301) 496-1936 UUCP: uunet!nlm.nih.gov!warsaw ==================== example ==================== class my_class { public: void btn_set_callback( void ); private: void do_btn_callback( Panel_item item, Event* event ); static void btn_callback( Panel_item item, Event* event ); Panel_item btn; static Attr_attribute INSTANCE; }; Attr_attribute my_class::INSTANCE = xv_unique_key(); void my_class::btn_set_callback( void ) { xv_set( btn, PANEL_NOTIFY_PROC, &my_class::btn_callback, XV_KEY_DATA, INSTANCE, this, NULL ); }; void my_class::btn_callback( Panel_item item, Event* event ) { my_class* obj = (my_class*)xv_get( item, XV_KEY_DATA, INSTANCE ); obj->do_btn_callback( item, event ); }; void my_class::do_btn_callback( Panel_item, Event* event ) { // implicit `this' is now set correctly, so you can access any // member of my_class you want. };