Course list http://www.c-jump.com/bcc/
In this lab we explore three widgets: Fl_Input, Fl_Output, and Fl_Button. FLUID design view of our application looks like this:
When user clicks button "Set Text", the data from the input box is replicated in the output box.
We will continue using the window class developed in the previous lab. The prototype for this project is Lab 3a:
c255labs\labs\c255_lab03a_win_close
Make a copy of Lab 3a subfolder and rename it as c255_lab03b_button or download and unzip c255_lab03a_win_close.zip
Open solution file in Visual Studio and follow the usual steps to rename the project.
Start FLUID program and open project
c255labs\labs\c255_lab03b_button\fluid_project\CFluidWindow.fl
Use FLUID menu or Widget Bin to add the widgets to your window.
Select Window win_app object in FLUID tree view. Use menu
New/Text/Input
Name this input box inp_box in the Properties/C++
Note: if you add a callback function to the input box control, it is invoked when the following two conditions are met:
the input box loses its input focus, and
the input box data has changed.
Select Window win_app object in FLUID tree view. Use menu
New/Text/Output
This creates a display-only text box, but user can select the content and copy the data.
Name this output box out_box in the Properties/C++
Select Window win_app object in FLUID tree view.
To create a push button, use menu
New/Buttons/Button
or right-click on the design window and select "Button" from the menu.
Name this button btn_set_text in the Properties/C++, and change its label to "Set Text" in the Properties/GUI.
Save FLUID project and generate C++ code by
File/Write Code...
Open solution
c255labs\labs\c255_lab03b_button\c255_lab03b_button.sln
in Visual Studio.
Open CDemoWindow.h in text editor. Add NEW callback code as shown:
// CDemoWindow.h #ifndef _CDEMOWINDOW_H_INCLUDED_ #define _CDEMOWINDOW_H_INCLUDED_ #include "../fluid_project/CFluidWindow.h" class CDemoWindow : public CFluidWindow { public: void show() { // Window callbacks: win_app->callback( (Fl_Callback*)callback_window_closing, (void*)(this) ); // NEW btn_set_text->callback( (Fl_Callback*)callback_btn_set_text, (void*)(this) ); // Make the window visible: win_app->show(); } // NEW button click event handler void click_btn_set_text() { char const* text = inp_box->value(); out_box->value( text ); } // static callback functions // user wants to close the window 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(); } } // NEW user clicks the button static void callback_btn_set_text(Fl_Widget* widg, void* userdata_) { std::cout << "button set text clicked\n"; CDemoWindow* demo_window = static_cast< CDemoWindow* > ( userdata_ ); demo_window->click_btn_set_text(); } };//class CDemoWindow #endif // _CDEMOWINDOW_H_INCLUDED_
Compile and test the program.
In a non-static member function, the keyword this is a pointer to the object for which the function was invoked. It becomes very helpful when we pass the pointer to CDemoWindow as a function parameter. For example, function call
btn_set_text->callback( (Fl_Callback*)callback_btn_set_text, (void*)(this) );
takes two parameters
The pointer to function callback_btn_set_text():
(Fl_Callback*)callback_btn_set_text
The pointer to CDemoWindow object, cast to a void pointer:
(void*)(this)
A void pointer is a pointer to "any object" in C++.
When user clicks the button, FLTK calls callback_btn_set_text() and passes CDemoWindow pointer in userdata_:
static void callback_btn_set_text( Fl_Widget* widg, void* userdata_ ) {
std::cout << "button set text clicked\n";
CDemoWindow* demo_window = static_cast< CDemoWindow* > ( userdata_ );
demo_window->click_btn_set_text();
}
Here, widg points to FLTK button widget, userdata_ points to the CDemoWindow. We have to cast userdata_ from void* to CDemoWindow* before we can access our object. The static_cast operator converts void* userdata_ to the pointer of the specified type:
CDemoWindow* demo_window = static_cast< CDemoWindow* > ( userdata_ );
As soon as we recover the CDemoWindow object, we can call its member function click_btn_set_text():
demo_window->click_btn_set_text();
Finally, click_btn_set_text() does all the work to handle the "Set Text" click:
void click_btn_set_text() { char const* text = inp_box->value(); // get text from the input box out_box->value( text ); // set text in the output box }
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.