Skip to main content
gamedev.net
🔒 Locked

Control Library

Started by kag1 Nov 4, 2004 at 5:55 PM 0 replies 500+ views
Original Post
kag1
kag1
Hello.. I'm making a control library and have so far created a base class (CControl) (which everything is derived from), a Window Class (CWindow) and a Button Class (CButton).. the part i'm having a bit of trouble with is how to handle the mousemove and mousedown events different for each instance of the button class...right now the parent window gets the messages from the WndProc..and sends them to the appropriate control..which is not a problem...but say I want two buttons to do 2 different things.. This is What I would like..

CWindow * ParentWindow;
CButton * button1;
CButton * button2;


MessagePump
{
switch (message)
{
case MOUSEMOVE:
case MOUSEBUTTONDOWN:
case MOUSEBUTTONUP:
    PostMessages(ParentWindow, message); //parent window then relays the messages to the appropriate button
    break;
}

}

button1->MouseDown()
{
do something
}

button2->MouseDown()
{
do something different than button one
}



the problem is since they both come from the same class, i'm not sure how to have them do different functions than each other...without having to like edit the class each time i make a new button
JesseT
JesseT
The use of a programming pattern known as Signals & Slots aka Delegates & Events is the solution to your ails.

Think of a signal or delegate as a functor... a first-class object with object-like semantics, but it acts like a function pointer and can be bound to an actual function or an object & member function.

Think of a slot as a list of such functors.

Your controls should have a slot for each event you wish to expose to the client programmer using the control classes. For example, you might have a slot called 'Clicked'.

Your control's message handling code then triggers the 'Clicked' slot, which calls all of the signals that have been previously registered with it.

Your code might look like this:

class Button{public:    ...    Slot<void()> Clicked;    ...};class Application{public:    Application() : mParent(0), mCloseButton(0), mDone(false)    {        mParent = new Window(...);        // create the 'Close' button, and register the        // 'Quit' member function to be called when the        // button is pressed        mCloseButton = new Button("Close", ...);        mCloseButton->Clicked.Connect(Signal(this, &Quit));        mParent->AddControl(mCloseButton);    }    ~Application()    {        delete mParent; // automatically deletes child controls    }    void Quit()    {        mDone = true;    }    int Run()    {        // loop until the 'Close' button is pressed        while (!mDone)        {            mParent->DoEvents();        }        return 0;    }private:    // non-copyable    Application(Application const&);    Application& operator=(Application const&);private:    Window* mParent;    Button* mCloseButton;    bool mDone;};int main(){    Application app;    return app.Run();}


Or something like that.

Check out here for a sample implementation of slots and signals.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.