Click here to Skip to main content
Click here to Skip to main content

Working with Delegates in Visual Form Files

, 8 Apr 2009
Rate this:
Please Sign up or sign in to vote.
How to work with delegates in Visual Form Files.

So you've got your interface put together via your Visual Form File resource. Now, you want to hook up some event handlers or callbacks in your application code to the UI. No problem!

The first thing you need to is write the code. Let's start off by using our application class as a place to put the callbacks. Later on, we'll investigate using the main window class as well, but for now, let's look at our app class:

class LOLCatsApp : public Application {
public:

};

OK, let's put in some code to handle a button click. The command button class has a delegate that takes a function with one parameter, a ButtonEvent*, and returns nothing (void). Since ButtonEvent derives from Event, and in this case, we really don't care much about the event per se, we can "cheat" a bit and simply write a function that takes a generic Event*.

class LOLCatsApp : public Application {
public:
 void myCallBack( Event* ) {
   Dialog::showMessage( "Hello there!" );
 }
};

Now, we've defined our callback. Let's add it to the application for later retrieval:

class LOLCatsApp : public Application {
public:
 LOLCatsApp( int argc, char** argv ) :
   Application(argc, argv) {
   addCallback( new ClassProcedure1<Event*,LOLCatsApp>(this, 
     &LOLCatsApp::myCallBack), "LOLCatsApp::myCallBack" );
 }

 void myCallBack( Event* ) {
   Dialog::showMessage( "Hello there!" );
 }
};

An application is a component, and therefore can have 0 or more callbacks. So, we call the app's addCallback() method and create a link to our callback function, making sure to give a correct name.

At this point, we've defined/implemented a callback function, and added it to the list of callbacks the application maintains and that can be retrieved by others via a call to the app's getCallback() function. All we have left is to hook the application's callback to the component in our VFF definition.

Like properties, a component can expose the delegates it has via VCF's RTTI macros. This allows you to access them in the VFF definition. The rule for this is that each object block, i.e.:

object MyObj : MyClass

end

has an optional delegates section, defined like so:

object MyObj : MyClass
 delegates
 end
end

Within this block, you can reference the delegates of the component and then assign an array of callbacks to the delegate. Each callback in the array will be added to the delegate. In other words:

object MyObj : MyClass
 delegates
   MyDelegate = [SomeComponentName@SomeComponentClass::SomeCallBackFunction]
 end
end

Each item in the array of callbacks has the following format: the name of a valid component instance, the "@" character, and the name of the callback. Technically, the name of the callback can be anything you want; however, the convention is to use fully qualified C++ names, so that's usually the name of the component instance's class, the "::" qualifier, and the name of the method.

The component referenced can be any component in the VFF definition, or it can be the name of the app class. By default, the name of the app is its class name *unless* you explicitly change it before you load up your form(s).

Armed with this information, let's add our callback to a button:

object myBtn : VCF::CommandButton  
 caption = 'Click Me'
 delegates
   ButtonClicked = [LOLCatsApp@LOLCatsApp::myCallBack]
 end
end

When the form is loaded, the framework will look at the myBtn instance, get access to its ButtonClicked delegate and the callback named "LOLCatsApp::myCallBack" in the LOLCatsApp instance, and then add the callback to the delegate. At that point, everything is "wired" together - when you click the button, the LOLCatsApp::myCallBack code will be invoked!

One question might be how to know what delegates are available. You can always browse the code, but that may nor may not immediately tell you that the delegate is exposed via the RTTI macros. Another way is use the new ClassRegistry Browser (ClassRegistryBrowser.zip). This is a graphical program that shows all the registered classes in the VCF's ClassRegistry. A class must be registered in the ClassRegistry for it to be available for reference in a VFF definition. When you select a class, the program iterates through all of the properties and delegates of the class. A bit like this:

Using this tool, you can definitively determine what delegates are available and can be safely referenced in your VFF definition.

Now, let's make a change, and instead of using our app class, let's use our window class to hold our callback. Let's add the code to our class first:

class LOLCatsWindow : public Window {
public:
 LOLCatsWindow();

 virtual ~LOLCatsWindow(){};

 void myCallBack( Event* ) {
   Dialog::showMessage( "Hello there!" );
 }

};

Add our callback:

class LOLCatsWindow : public Window {
public:
 LOLCatsWindow() {
   addCallback( new ClassProcedure1<Event*,LOLCatsWindow>(this, 
      &LOLCatsWindow::myCallBack), "LOLCatsWindow::myCallBack" );
  
 }

 virtual ~LOLCatsWindow(){};

 void myCallBack( Event* ) {
   Dialog::showMessage( "Hello there!" );
 }

};

And then, wire it up in the VFF:

object LOLCats  : VCF::Window
 object myBtn : VCF::CommandButton  
   caption = 'Click Me'
   delegates
     ButtonClicked = [LOLCats@LOLCatsWindow::myCallBack]
   end
 end
end

That's it! You've now got your window class handling a button click.

This same technique can be applied to any component that exposes delegates through the VCF's RTTI.

License

This article, along with any associated source code and files, is licensed under The BSD License

Share

About the Author

Jim Crafton
Software Developer (Senior)
United States United States
Currently working on the Visual Component Framework, a really cool C++ framework. Currently the VCF has millions upon millions upon billions of Users. If I make anymore money from it I'll have to buy my own country.

Comments and Discussions

 
QuestionStatus? PinmemberJerry Evans19-Apr-09 13:32 
AnswerRe: Status? PinmemberJim Crafton19-Apr-09 15:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140821.2 | Last Updated 8 Apr 2009
Article Copyright 2009 by Jim Crafton
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid