Hello, I am using Microsoft Visual C++ 2010 and FLTK 1.3.
What I have done is to create an Fl_Group derived class that holds a couple Fl_Input widgets in a row in order to instance objects of that class in the main function and efficiently create the rows. This saves me some from hand-typing repetitive lines of
code for each new row and works quite well.
However, I would also like to create a member function for the code that process the information in each instance's widgets, saving me from some extra hand-typed code again. And, this is proving to be more difficult/arcane of a task than I had expected,
and I have yet to find a clear example of how to do this.
The main point of difficulty seems to be using a callback function from an Fl_Button class to the member function of each of the custom Fl_Group class' instances. That causes the program to crash.
Here is the basic code that I have been working with:
#include <cstdlib>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Round_Button.H>
using namespace std;
int studentNum = 0;
char nums[100];
char ftotal[50];
class InputRow: public Fl_Group
{
public:
//Create the widget pointers
Fl_Input *box1;
Fl_Input *box2;
//Contructor
InputRow(int x, int y, int w, int h, const char *l=0) : Fl_Group(x,y,500,500,l)
{
//Load the widget pointers with widget classes
box1 = new Fl_Input(x,y+10,w,h,NULL);
box1->maximum_size(3);
box1->value(0);
box2 = new Fl_Input(x+50,y+10,w,h,NULL);
box2->maximum_size(3);
box2->value(0);
}
//Process the information in the widget by sending their values to an array for further processing.
void process (Fl_Widget *o, void*)
{
Fl_Group *g = (Fl_Group*)o;
Fl_Input *a = (Fl_Input*)g->child(0);
Fl_Input *b = (Fl_Input*)g->child(1);
//Load widget values to integers.
int num1 = 0;
int num2 = 0;
num1 = atoi(a->value());
num2 = atoi(b->value());
//Perform math.
int total = 0;
total = num1 + num2;
//Send the result to an array.
char holder[5];
itoa(total,&holder[0],10);
for(size_t c=0; c<strlen(holder); c++)
{ nums[studentNum] = holder[c];
studentNum++;
}
}
//"Wrapper" necessary for accessing the member function in C++ classes??
static void staticProcess(Fl_Widget *o, void* userdata)
{ InputRow *w = (InputRow*)userdata;
w->process(o,userdata);
}
} *ir1, *ir2; //Forward declaration of object instances.
void initArrays()
{ for(int c=0; c<100; c++) {nums[c]=0;}
for(int c=0; c<50; c++) {ftotal[c]=0;}
}
void calc(Fl_Widget* o, void*)
{
initArrays();
Fl_Group *g1 = (Fl_Group*)o->parent()->child(3);
Fl_Group *g2 = (Fl_Group*)o->parent()->child(4);
studentNum = 0;
g1->callback(InputRow::staticProcess);
g1->do_callback();
studentNum = 5;
g2->callback(InputRow::staticProcess);
g2->do_callback();
//Do math.
int num1;
int num2;
num1 = atoi(&nums[0]);
num2 = atoi(&nums[5]);
int total = num1 + num2;
//Send to display.
itoa(total,&ftotal[0],10);
Fl_Input *display = (Fl_Input*)o->parent()->child(5); //Arrive at Fl_Input on top level and link to an Fl_Input pointer.
display->value(&ftotal[0]); //Send the value of the Fl_Group's Fl_Input widget to the upper level Fl_Input widget's value.
}
int main()
{
Fl_Window *win = new Fl_Window(500,500,"Button Values");{
Fl_Round_Button *b1 = new Fl_Round_Button(50,50,15,15);
b1->set();
Fl_Input *i1 = new Fl_Input(70,50,40,20);
i1->box(FL_BORDER_FRAME);
i1->color(FL_BLACK);
i1->set_output();
Fl_Button *set = new Fl_Button(50,70,40,20,"Set");
//Instances of a group of widgets
InputRow *ir1 = new InputRow(50,90,40,20,NULL);
InputRow *ir2 = new InputRow(50,110,40,20,NULL);
Fl_Input *display = new Fl_Input(50, 160, 40, 20);
Fl_Button *calculate = new Fl_Button(50, 180, 60, 20, "Process");
calculate->callback(calc);
}
win->end();
win->show();
return (Fl::run());
}
The program compiles, but pressing the "Process" button causes it to crash.
The error is:
"Unhandled exception at 0x00a01596 in buttons.exe: 0xC0000005: Access violation reading location 0x00000054."
In Autos, it lists "this".
In the Call Stack, it lists "Buttons.exe Fl_Input::value().
And it opens the Fl_Input.H in the IDE window.
I am not sure which line it is crashing on in the main.cpp.
How can I call the Fl_Group derived class's member function through a callback for each object instance?