I want to fill a form at runtime with a lot of comboboxes with identical lists. They also get the same event handler, which is acting depending on the Sender objects's Name. However, this takes a pretty long time and I was guessing I do something wrong.
I'm using XE2 Rad Studio C++ Builder and the VCL GUI.
Edit: Those boxes contain a different kinds of content and are distributed over a few tabPages within the form. however, it's necessary to display what it selected at at least 80 of them at a glance. Would it maybe be better to replace them with TLabels and create a TCombobox when clicking on the TLabel to select a different element?
The Code looks similar to this:
void __fastcall TForm::TForm(){
int i=0;
TStringList* targetlist = new TStringList();
targetlist->Add("Normal");
targetlist->Add("Inverted");
Vcl::Stdctrls::TComboBox **com = new Vcl::Stdctrls::TComboBox[512];
for(i=0;i<512;++i){
com[i]=new Vcl::Stdctrls::TComboBox(this);
com[i]->Parent=this;
com[i]->Name.printf(L"Combo_%d", i);
com[i]->SetBounds(10, 198 + 20 * i, 130, 200);
com[i]->Items = targetlist;
com[i]->ItemIndex = 0;
com[i]->Style = csDropDownList;
com[i]->OnChange = MyComboTriggerChange;
}
}
One iteration seems to take around 20ms on my machine (testedt with std::clock), which make this part ~10s long. The pointers are deleted at the form's destruction. I just put their declarations here for simplifications.
Is there a better way to create multiple comboboxes? Maybe clone them?
You seriously need to redesign your UI. Using 512
TComboBoxcontrols on one screen with the same list of values makes no logical sense, and is a waste of time and resources. There are better ways to display 512 strings on a screen, such as aTListViewin report mode, or aTListBox(both of them support a virtual mode so they can share common data without wasting memory). Or use aTValueListEditororTStringGridwith anesPickListinline editor. Or, if you are really adventurous, write a custom control from scratch so you use 1 efficient control instead of 512 separate controls. Anything is better than 512TComboBoxcontrols.That being said,
TComboBoxdoes not support a virtual mode, likeTListBoxandTListViewdo, but there are a couple of optimizations you can still make to speed up yourTComboBoxes a little:don't make 512 copies of the same
TStringListcontent. Anything you add to theTComboBox::Itemsis stored inside theTComboBox's memory. You should strive to reuse your singleTStringListand let everything delegate to it as needed. In this case, you can set theTComboBox::Styleproperty tocsOwnerDrawFixedand use theTComboBox::OnDrawItemevent to draw theTStringListstrings on-demand. You still need to add strings to eachTComboBox, but they can be empty strings, at least.subclass
TComboBoxto override its virtualCreateParams()method and it remove theCBS_HASSTRINGSwindow style, then theTComboBoxdoes not actually need to store empty strings in its memory.Try something like this: