Hello everyone. I am new (very very new) in programming and have knowledge of the very basic stuff in programming. I am currently working on a project in c++ builder and i have encountered a problem.
I've defined a function which activates at the press of a button. The function creates various objects in TForm1, and 2 of these objects are ListBoxes. Since i wanted the options in the ListBox2 to depend on the options in ListBox1, i tried to create a __fastcall function which activates whenever ListBox1 is clicked. The only problem is that i don't know the syntax for to use in an internal __fastcall function. I will paste here a part of the code:
The actual values in quotes " " don't matter, the idea matters - it doesn't work.Code:void asezare() { TEdit *Edit3,*Edit4; TLabel *Label3,*Label4,*Label5; TListBox *ListBox1,*ListBox2; Edit3=new TEdit(Form1); Form1->InsertControl(Edit3); Edit3->Left=Form1->Edit1->Left-245; Edit3->Top=Form1->Edit1->Top; Edit3->Width=20; Edit4=new TEdit(Form1); Form1->InsertControl(Edit4); Edit4->Left=Form1->Edit2->Left-245; Edit4->Top=Form1->Edit2->Top; Edit4->Width=20; Label3=new TLabel(Form1); Form1->InsertControl(Label3); Label3->Left=Form1->Label1->Left-315; Label3->Top=Form1->Label1->Top; Label3->Caption="Coordonata numerica"; Label3->AutoSize=true; Label4=new TLabel(Form1); Form1->InsertControl(Label4); Label4->Left=Form1->Label2->Left-315; Label4->Top=Form1->Label2->Top; Label4->Caption="Coordonata alfabetica"; Label4->AutoSize=true; ListBox1=new TListBox(Form1); Form1->InsertControl(ListBox1); ListBox1->Left=Edit3->Left+30; ListBox1->Items->Add("Orizontal"); ListBox1->Items->Add("Vertical"); ListBox1->Top=Edit3->Top; ListBox1->Height=30; ListBox1->Width=65; Label5=new TLabel(Form1); Form1->InsertControl(Label5); Label4->Left=ListBox1->Left; Label4->Top=ListBox1->Top-12; Label4->Caption="Pozitia"; Label4->AutoSize=true; ListBox2=new TListBox(Form1); ListBox2->Left=Edit3->Left+60; ListBox2->Top=Edit3->Top; ListBox2->Height=30; ListBox2->Width=65; void __fastcall TForm1::ListBox1Click(TObject *Sender) { if(ListBox1->ItemIndex==0) {ListBox2->Items->Clear(); ListBox2->Items->Add("Sus"); ListBox2->Items->Add("Jos"); } if(ListBox1->ItemIndex==1) {ListBox2->Items->Clear(); ListBox2->Items->Add("Dreapta"); ListBox2->Items->Add("Stanga"); } } }
The errors i get are:
[C++ Error] Unit1.cpp(69): E2089 Identifier 'ListBox1Click' cannot have a type qualifier
[C++ Error] Unit1.cpp(92): E2139 Declaration missing ;
[C++ Error] Unit1.cpp(92): E2190 Unexpected }
Any help is welcome.
Thank you very much.
Last edited by WingedPanther; 12-19-2008 at 11:46 AM. Reason: add code tags (the # button)
Change
In your code to :Code:ListBox2->Width=65; void __fastcall TForm1::ListBox1Click(TObject *Sender) { if(ListBox1->ItemIndex==0) {ListBox2->Items->Clear(); ListBox2->Items->Add("Sus"); ListBox2->Items->Add("Jos"); } if(ListBox1->ItemIndex==1) {ListBox2->Items->Clear(); ListBox2->Items->Add("Dreapta"); ListBox2->Items->Add("Stanga"); } } }
so your problem has nothing to do with __fastcall.Code:ListBox2->Width=65; } // <--- See here void __fastcall TForm1::ListBox1Click(TObject *Sender) { if(ListBox1->ItemIndex==0) { ListBox2->Items->Clear(); ListBox2->Items->Add("Sus"); ListBox2->Items->Add("Jos"); } if(ListBox1->ItemIndex==1) { ListBox2->Items->Clear(); ListBox2->Items->Add("Dreapta"); ListBox2->Items->Add("Stanga"); } } // the } originally here is misplaced.
As for __fastcall, it's just yet another calling convention. calling conventions determine how parameters are passed ( through stack or registers, if stack, the order in which they are pushed on to the stack, etc) and where to find the return value and who's responsibility is to clean the stack of the parameters.
You can pretty much ignore it for now.
BTW, please use code tags to display your code nicely.
At a guess (I don't work with C++ Builder, but I'm familiar with other Borland products):
void __fastcall TForm1::ListBox1Click(TObject *Sender)
should be
void TForm1::ListBox1Click(TObject *Sender)
@Lance:
Your solution would work, but the thing is, the function which calls ListBox1 needs to be within asezare(), because ListBox1 is defined within asezare(). Replacing the "}" only separates void __fastcall from asezare(), but i want the __fascall which uses TListBox1 to be integrated within asezare(). Separating them causes the builder to be unable to detect TListBox1, since it is defined in the function above, TListBox1 is not originally present.
@WingedPanther
Tried, but it didn't work![]()
Go it.
You still need to define the call back function in a class derived from TObject. For example your MainForm or something like that. You can actually name it something else. I mean, unlike visual basic which uses the function name to detect event handler, in c++ builder you can assign any closure to a particular event of an object provided it's of required signature.
OK. You would difine the ListBox OnClick event handler like:
Note I did not test the above code, but the mechanism is sure to work and is exactly the solution to your problem.Code:void __fastcall /* __fastcall keyword is required */ TForm1::LBClicked(TObject * sender) { ShowMessage("You clicked something to cause LBClicked be invoked!"); } void asezare() { TListBox * lb=new TListBox(Form1); lb->Parent = Form1; // you'll actually need this line to make the listbox visible lb->Items->Add("One"); lb->Items->Add("Two"); lb->Top= 30; lb->Left = 50; // assign event Handler lb->OnClick = Form1->LBClicked; // for demonstration, I also assign the same event handler to a button TButton * btn=new TButton(Form1); btn->Parent = Form1; btn->Top = 100; btn->Let = 50; btn->Caption = "&Hello"; btn->OnClick = LBClicked; }
No in C or C++ you cannot define local functions in another function; that's why your code wouldn't even compile.
I didn't read you code or try to write code that will fit into you situation without any change. Just mean to explain the mechanism. It's alright to create controls dynamically (at runtime instead of design time), but any event handler would be pre-exist before they can be assigned as event handler for the dynamically created object.
HTH
C++Builder closure pointer is an extension to standard C++. It's equivalent to C# delegate. So for those who don't use C++Builder, do not try to make sense of the code. you cannot take a member function address using obj->memberfunctionname in standard C++. And closure is more than just a memeber function pointer, it also bind an object in it.
Thank you very very much, i understand how the concept works, just that i got some syntax problems up there. When i compile it, it says:
[C++ Error] Unit1.cpp(78): E2316 'LBclicked' is not a member of 'TForm1'
[C++ Error] Unit1.cpp(197): E2316 '_fastcall TForm1::LBClicked(TObject *)' is not a member of 'TForm1'
I though the problem in LBClicked is that the ListBox is defined as lb, so i changed LBClicked to lbClicked , but, still the same error - it's not a member of TForm1 . The concept obviously works but i need a bit of workaround with syntax.
All i want to do is to make the stuff which appears in ListBox2 depend on the item selected in ListBox1![]()
Last edited by totonex; 12-20-2008 at 06:55 AM.
LBClicked is not a valid method in a form object. How did you create it?
I didn't. It doesn't work. If this method doesn't work, can anyone tell me how to link the information between 2 ListBoxes ? Let's say ListBox1 has the items '1' and '2'. When 1 is pressed, ListBox2 has the items '3' and '4', and when '2' is pressed, ListBox2 has '5' and '6'. This was the entire point of my initial algorithm.
All right. In the header file for TForm1, in private, protected or public section (depends on how you expected to expose it), add a prototype>
You're good to go.Code:class TForm1: public TForm{ ..... private: void __fastcall LBClicked(TObject * sender); };
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks