Course list http://www.c-jump.com/bcc/
In this lab we explore the mechanism by which FLTK informs our program about user actions, such as mouse clicks or keys pressed on the keyboard. The mechanism is called callback function.
Callbacks are C++ functions invoked by FLTK in response to user actions and other important events, such as timer calls at specific time intervals, button clicks, or text box changes.
To create a callback, our program must
(a) define a callback function
(b) attach the function to a widget or a window.
Besides buttons and other GUI controls, the window itself is a widget. It can be minimized, maximized, and closed by clicking a menu or the "X" button on the title bar of the window.
By default, the "X" button
(a) hides the window
(b) returns from Fl::run() call if this was the last visible window in the application.
The default action is unacceptable when window contains an unsaved information. We may refuse to close the window and warn the user about unsaved data. All of this can be done with the help of a callback function that implements the required behavior.
The prototype for this exercise is Lab 3:
c255labs\labs\c255_lab03_win_class
Make a copy of Lab 3 subfolder and rename it as c255_lab03a_win_close.
Open solution file in Visual Studio and follow the usual steps to rename the project.
Open CDemoWindow.h in Visual Studio source editor and modify the code as follows:
// CDemoWindow.h #ifndef _CDEMOWINDOW_H_INCLUDED_ #define _CDEMOWINDOW_H_INCLUDED_ #include "../fluid_project/CFluidWindow.h" class CDemoWindow : public CFluidWindow { public: void show() { // NEW Specify which C++ function should Update button call: win_app->callback( (Fl_Callback*)callback_window_closing, (void*)(this) ); // Make the window visible: win_app->show(); } // NEW callback functions static void callback_window_closing(Fl_Widget* widg, void* userdata_) { std::cout << "X button clicked -- exiting the program\n"; while( Fl::first_window() ) { Fl::first_window()->hide(); } } };//class CDemoWindow #endif // _CDEMOWINDOW_H_INCLUDED_
The changes are:
It is possible to write callback functions directly in FLUID. However, it's a bit tedious, and I prefer writing callback functions by hand. However, we could try these steps as an exercise:
Start FLUID program:
c255labs\external\fluid\fluid.exe
Open FLUID project:
c255labs\labs\c255_lab03a_win_close\fluid_project\CFluidWindow.fl
Select Window win_app in the tree view, then double-click on the window to open the properties tab.
Switch to C++ tab and type the callback function name: callback_window_closing (no parameters, just the name alone.)
This callback will be invoked when the user clicks the "X" button to close the window.
Close the properties dialog and select the class CFluidWindow in the FLUID browser tree view.
Use FLUID menu
New/Code/Function-Method
and enter the name of the callback function:
Name(arg): callback_window_closing( Fl_Widget* widg, void* userdata ) Return type: static void
Add the callback function body by selecting callback_window_closing in FLUID tree view and then using menu
New/Code/Code...
Add C++ code:
std::cout << "X button clicked -- exiting the program\n"; while( Fl::first_window() ) { Fl::first_window()->hide(); }
For std::cout to compile properly, we must #include <iostream>. Use FLUID menu
Edit/Select None New/Code/Declaration...
and type
#include <iostream>
The new #include should be moved to the top of the tree by hitting the F2 key a few times. Keep in mind that you can rearrange the order of items in the FLUID project tree by F2 (up) and F3 (down).
Note that callback_window_closing() function traps the "X" button. If you do not hide the window or call exit(0), which asks the operating system to terminate the program immediately, the function will do nothing to close the window.
Exiting the app by
win_app->hide();
a cleaner way than calling exit(0). The Fl_Window::hide call removes the window from the screen and quits the application if it's the last visible window. If there are multiple visible windows, the best way to exit the app is:
while( Fl::first_window() ) Fl::first_window()->hide(); }
The loop hides all windows, ensuring that Fl::run() returns and all class destructors are called properly.
The callback function is "attached" to the window by
win_app->callback( ( Fl_Callback* )callback_window_closing, (void*)(this) );
We must not forget to make this call, otherwise callback_window_closing() will never be invoked.
The win_app->callback() takes two parameters:
(Fl_Callback*)callback_window_closing spacifies the address of our callback function
The second parameter, (void*)(this) specifies "user data" (to be discussed in the next Lab.)
This is a self-learning lab. There are no files to submit. Make sure to complete all required steps to build and test the project on your own home computer.