Code: Select all
for i := 0 to ComponentCount - 1 do
begin
if Component[i] is TButton then
// do something with button
if Component[i] is TLabel then
// do something with label
...
end;
If you examine generated code for the definition of Screen object in an application containing multiple object types (Buttons, Labels, CheckBoxes etc.) you will see something like this:
Code: Select all
typedef struct Screen TScreen;
struct Screen {
unsigned int Color;
unsigned int Width;
unsigned int Height;
unsigned int ObjectsCount;
unsigned int ButtonsCount;
TButton * const code *Buttons;
unsigned int LabelsCount;
TLabel * const code *Labels;
unsigned int ImagesCount;
TImage * const code *Images;
unsigned int BoxesCount;
TBox * const code *Boxes;
unsigned int CheckBoxesCount;
TCheckBox * const code *CheckBoxes;
unsigned int RadioButtonsCount;
TRadioButton * const code *RadioButtons;
};
Code: Select all
typedef struct Screen TScreen;
struct Screen {
unsigned int Color;
unsigned int Width;
unsigned int Height;
unsigned int ObjectsCount;
const TComponent *Components; // pointer to const TComponent (first element of Components array)
};
Code: Select all
typedef enum {_objButton, _objLabel, _objImage, _objBox, _objCheckBox, _objRadioButton} TObjectType;
typedef struct {
TObjectType ObjType;
void *ObjPtr;
} TComponent;
Code: Select all
const TComponent Screen1_Components[] = {
{_objBox, &Box1},
{_objLabel, &Label1},
{_objButton, &Button1},
{_objCheckBox, &CheckBox1},
{_objRadioButton, &RadioButton1},
{_objImage, &Image1}
};
Screen1.Components = Screen1_Components;
for (i = 0; i < Screen1.ObjectsCount; i++) {
if (Screen1.Components[i].ObjType == _objButton)
// do something with button
if (Screen1.Components[i].ObjType == _objLabel)
// do something with label
...
}
Code: Select all
typedef struct Button {
TScreen* OwnerScreen;
char Order;
...
Code: Select all
while (order < CurrentScreen->ObjectsCount) {
if (button_idx < CurrentScreen->ButtonsCount) {
local_button = GetButton(button_idx);
if (order == local_button->Order) {
button_idx++;
order++;
DrawButton(local_button);
}
}
if (label_idx < CurrentScreen->LabelsCount) {
local_label = GetLabel(label_idx);
if (order == local_label->Order) {
label_idx++;
order++;
DrawLabel(local_label);
}
}
...
}
Code: Select all
while (order < CurrentScreen->ObjectsCount) {
switch (CurrentScreen->Components[order].ObjType) {
case _objButton:
DrawButton((TButton *)CurrentScreen->Components[order].ObjPtr);
break;
case _objLabel:
DrawLabel((TLabel *)CurrentScreen->Components[order].ObjPtr);
break;
...
}
order++;
}
And finally, here's how you reuse objects on another screen:
Code: Select all
const TComponent myComponents[] = {
{_objBox, &Box1},
{_objLabel, &Label1},
{_objButton, &Button1},
{_objCheckBox, &CheckBox1},
{_objRadioButton, &RadioButton1},
{_objImage, &Image1},
{_objLabel, &Label2}
};
void Button1Click() {
if (CurrentScreen == &Screen1) {
Screen2.Components = myComponents;
Screen2.ObjectsCount = sizeof(myComponents)/sizeof(TComponent);
DrawScreen(&Screen2);
}
}
Regards