From: Stuart Golodetz on
"Aggro" <spammerdream(a)yahoo.com> wrote in message
news:JCJ0j.387$D53.110(a)read3.inet.fi...
>I have a program, which prints out this:
> --------- output -----------
> Button 1:a
> Button 2:a
> --------- output -----------
>
> This is exactly what I want and the program works correctly. The problem
> is that I can only make the callback functions to work in my derived class
> (MyWnd) by declaring virtual functions to my base class ( Window ). This
> is not a very good solutions, since I could end up having several
> different callback functions which I would rather not have in the Window
> class. And I would also like to be able to pick any member function name i
> want to, in the derived classes.
>
> So the question is. Can I keep the functionality I now have, without the
> virtual functions in my base class? I also need to be able to derive other
> classes from Window and implement similar behaviour to those too. And if I
> can, how do I do that?

<snip>

I'm not sure I understand what the problem you're actually trying to solve
here is? I can think of a number of ways to specify button behaviour, e.g.

1) Have a virtual push function in the Button class and specify the desired
functionality by derivation.
2) Have a Button class which takes a pointer to a callback function e.g.
void callback(Window *) - note that this is just any old function, not a
member function.
3) Store a button -> function map in the window. The window's event handler
(say) detects which button has been pressed and calls the appropriate
function. In this design, the button class itself might be redundant - all
the window needs to store is a list of rectangles (say) to specify where the
various buttons are (and maybe a list of captions for them). [I'm not
advocating this design, incidentally, before anyone criticises it.]
etc.

What I don't understand is why you're trying to specify button behaviour on
a per-window basis. Are you envisaging adding the same button to multiple
windows and having different functionality in each? And if so, why?

Best wishes,
Stu


From: Aggro on
Stuart Golodetz wrote:
> "Aggro" <spammerdream(a)yahoo.com> wrote in message

>> So the question is. Can I keep the functionality I now have, without the
>> virtual functions in my base class? I also need to be able to derive other
>> classes from Window and implement similar behaviour to those too. And if I
>> can, how do I do that?

> What I don't understand is why you're trying to specify button behaviour on
> a per-window basis. Are you envisaging adding the same button to multiple
> windows and having different functionality in each? And if so, why?

Short answer: I'm trying to reimplement the functionality of wxWidgets.
A very light version of it.


Let's say that I want to create class SettingsWnd which is derived from
Window. And I want to add there 3 buttons Cancel, Apply and OK, which
all are instances Button. Obviously my example is too simple for this
purpose, but something like this:

Button *cancel = new Button( "Cancel" );
Button *apply = new Button( "Apply" );
Button *ok = new Button( "OK" );

cancel->Connect( *this, &SettingsWnd::CancelPressed );
apply->Connect( *this, &SettingsWnd::ApplyPressed );
ok->Connect( *this, &SettingsWnd::OKPressed );

void SettingsWnd::CancelPressed()
{
// Close window and ignore all changes
}

void SettingsWnd::ApplyPressed()
{
// Save modifications
}

void SettingsWnd::OKPressed()
{
// Save and close window
}

Now, let's say that I also want to create LoginWnd, and there I need
buttons "Login" "Close", "Forgotten password". So I would again create 3
instances of Button class and connect those to call member functions of
the LoginWnd.


But actually I am trying to create a library here. Well actually just
few files of code that can be attached to any project and used there.
But I want to give the user the possibility to create a derivated
Window-class and add as many instances of Button there as the users
wants. And attach those buttons to callback (member) functions which are
called if the button is pressed.

This code can be done with the current implementation. But that would
require me to add a lot of virtual functions to the Window class

void Window::CancelPressed();
void Window::ApplyPressed();
void Window::OKPressed();
void Window::LoginPressed();
etc. So this just very handy.

So... Like I said in my first post. How can I write the code without
virtual functions in the base class. So I want my code to compile and
work even if my Window class wouldn't have any functions at all:

class Window
{
};
From: Stuart Golodetz on
"Aggro" <spammerdream(a)yahoo.com> wrote in message
news:hnZ0j.201$0b3.133(a)read3.inet.fi...
> Stuart Golodetz wrote:
>> "Aggro" <spammerdream(a)yahoo.com> wrote in message
>
>>> So the question is. Can I keep the functionality I now have, without the
>>> virtual functions in my base class? I also need to be able to derive
>>> other classes from Window and implement similar behaviour to those too.
>>> And if I can, how do I do that?
>
>> What I don't understand is why you're trying to specify button behaviour
>> on a per-window basis. Are you envisaging adding the same button to
>> multiple windows and having different functionality in each? And if so,
>> why?
>
> Short answer: I'm trying to reimplement the functionality of wxWidgets. A
> very light version of it.
>
>
> Let's say that I want to create class SettingsWnd which is derived from
> Window. And I want to add there 3 buttons Cancel, Apply and OK, which all
> are instances Button. Obviously my example is too simple for this purpose,
> but something like this:
>
> Button *cancel = new Button( "Cancel" );
> Button *apply = new Button( "Apply" );
> Button *ok = new Button( "OK" );
>
> cancel->Connect( *this, &SettingsWnd::CancelPressed );
> apply->Connect( *this, &SettingsWnd::ApplyPressed );
> ok->Connect( *this, &SettingsWnd::OKPressed );
>
> void SettingsWnd::CancelPressed()
> {
> // Close window and ignore all changes
> }
>
> void SettingsWnd::ApplyPressed()
> {
> // Save modifications
> }
>
> void SettingsWnd::OKPressed()
> {
> // Save and close window
> }
>
> Now, let's say that I also want to create LoginWnd, and there I need
> buttons "Login" "Close", "Forgotten password". So I would again create 3
> instances of Button class and connect those to call member functions of
> the LoginWnd.
>
>
> But actually I am trying to create a library here. Well actually just few
> files of code that can be attached to any project and used there. But I
> want to give the user the possibility to create a derivated Window-class
> and add as many instances of Button there as the users wants. And attach
> those buttons to callback (member) functions which are called if the
> button is pressed.
>
> This code can be done with the current implementation. But that would
> require me to add a lot of virtual functions to the Window class
>
> void Window::CancelPressed();
> void Window::ApplyPressed();
> void Window::OKPressed();
> void Window::LoginPressed();
> etc. So this just very handy.
>
> So... Like I said in my first post. How can I write the code without
> virtual functions in the base class. So I want my code to compile and work
> even if my Window class wouldn't have any functions at all:
>
> class Window
> {
> };

Well the obvious solution would be to make the callbacks non-member
functions and just pass the window pointer to them if you need to access
stuff from the window itself.

Best wishes,
Stu


From: Alf P. Steinbach on
* Aggro:
> Stuart Golodetz wrote:
>> "Aggro" <spammerdream(a)yahoo.com> wrote in message
>
>>> So the question is. Can I keep the functionality I now have, without
>>> the virtual functions in my base class? I also need to be able to
>>> derive other classes from Window and implement similar behaviour to
>>> those too. And if I can, how do I do that?
>
>> What I don't understand is why you're trying to specify button
>> behaviour on a per-window basis. Are you envisaging adding the same
>> button to multiple windows and having different functionality in each?
>> And if so, why?
>
> Short answer: I'm trying to reimplement the functionality of wxWidgets.
> A very light version of it.
>
>
> Let's say that I want to create class SettingsWnd which is derived from
> Window. And I want to add there 3 buttons Cancel, Apply and OK, which
> all are instances Button. Obviously my example is too simple for this
> purpose, but something like this:
>
> Button *cancel = new Button( "Cancel" );
> Button *apply = new Button( "Apply" );
> Button *ok = new Button( "OK" );
>
> cancel->Connect( *this, &SettingsWnd::CancelPressed );
> apply->Connect( *this, &SettingsWnd::ApplyPressed );
> ok->Connect( *this, &SettingsWnd::OKPressed );
>
> void SettingsWnd::CancelPressed()
> {
> // Close window and ignore all changes
> }
>
> void SettingsWnd::ApplyPressed()
> {
> // Save modifications
> }
>
> void SettingsWnd::OKPressed()
> {
> // Save and close window
> }
>
> Now, let's say that I also want to create LoginWnd, and there I need
> buttons "Login" "Close", "Forgotten password". So I would again create 3
> instances of Button class and connect those to call member functions of
> the LoginWnd.
>
>
> But actually I am trying to create a library here. Well actually just
> few files of code that can be attached to any project and used there.
> But I want to give the user the possibility to create a derivated
> Window-class and add as many instances of Button there as the users
> wants. And attach those buttons to callback (member) functions which are
> called if the button is pressed.
>
> This code can be done with the current implementation. But that would
> require me to add a lot of virtual functions to the Window class
>
> void Window::CancelPressed();
> void Window::ApplyPressed();
> void Window::OKPressed();
> void Window::LoginPressed();
> etc. So this just very handy.
>
> So... Like I said in my first post. How can I write the code without
> virtual functions in the base class. So I want my code to compile and
> work even if my Window class wouldn't have any functions at all:
>
> class Window
> {
> };

Take a look at Boost functions (mostly same as in TR1).

Just to give you an idea of how that works on the inside, your code
rewritten without using Boost functions but something like it, custom
made for this particular program:

#include <iostream>
#include <boost/shared_ptr.hpp>

class ClickEventHandler
{
public:
typedef boost::shared_ptr<ClickEventHandler> Ptr;
virtual ~ClickEventHandler() {}
virtual void operator()( char x ) = 0;
};

template< class WindowType >
class ClickEventHandlerFor: public ClickEventHandler
{
private:
typedef void (WindowType::*HandlerFunc)( char x );
WindowType* myW;
HandlerFunc myF;
public:
ClickEventHandlerFor( WindowType& w, HandlerFunc f )
: myW( &w ), myF( f )
{}

void operator()( char x ) { (myW->*myF)( x ); }
};

template< class WindowType, class HandlerFunc >
ClickEventHandler::Ptr clickEventHandlerFor( WindowType& w, HandlerFunc f )
{
return ClickEventHandler::Ptr( new
ClickEventHandlerFor<WindowType>( w, f ) );
}

class Button
{
private:
ClickEventHandler::Ptr myHandler;

public:
template< class WindowType, class HandlerFunc >
void Connect( WindowType& w, HandlerFunc f )
{
myHandler = clickEventHandlerFor( w, f );
}

void Push()
{
(*myHandler)('a');
}
};

class Window
{
public:
virtual ~Window() {}
};

class MyWnd : public Window
{
public:
void Button1( char x )
{
std::cout << "Button 1:" << x << std::endl;
}

void Button2( char x )
{
std::cout << "Button 2:" << x << std::endl;
}

void Connect( Button *b, Button *b2 )
{
b->Connect( *this, &MyWnd::Button1 );
b2->Connect( *this, &MyWnd::Button2 );
}
};

int main()
{
Button *b = new Button();
Button *b2 = new Button();
MyWnd wnd;
wnd.Connect( b, b2 );
b->Push();
b2->Push();
delete b;
delete b2;

return 0;
}


Cheers, & hth.,

- Alf


--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?