2010-03-06 6 views
2

Я ищу некоторый код BCB, чтобы перебирать элементы управления на форме и получать некоторую информацию о них.BCB: как перебрать элементы управления на форме?

Я пробовал использовать myForm->ControlCount и typeid(myForm->Controls[i]), но это дало мне несколько проблем.

1) typeid(myForm->Controls[i])->Name всегда дает "TControl *", и я надеялся на "TEdit *", "*" TMemo и т.д.

Могу ли я обойти, что с помощью

if (typeid(myForm->Controls[i]) == typeid(TEdit)) 

, а затем литье? (если да, то как лучше всего лить?)

2) как я могу (возможно, путем литья) получить свойства элемента управления? например, имя, ширина, высота и т. д.?

Я действительно ценю действительный код здесь (или URL-адрес какого-либо фактического кода); Благодарю.


Обновление: Так как мне нужно только для тестирования 5 OT 6 различных типов элементов управления для моего конкретного случая, я думал, что я мог бы, возможно, попытаться dynamic_cast<> друг к каждому из них, в свою очередь, но я не могу показаться, получите это, чтобы сработать ...

ответ

8

Вы в некоторой степени верны в своем предположении, что отливка будет хорошей идеей и что использование dynamic_cast - лучший вариант здесь.

Если вы хотите перебрать элементы управления формы (или любого другого контейнера). К сожалению, у меня нет моего C++ Builder на этом компьютере, поэтому я не могу протестировать код, который я вам даю, но создать тривиальную задачу для создания.

// You wanna start my iterating through the controls of the container 
for (int i = 0; i < container->ControlCount; i++) 
{ 
    // Let us extract the control at index i 
    TControl *control = container->Controls[i]; 

    // Now we want to test whether this is any specific type, for instance a 
    // TEdit or any TEdit descendant. 
    TEdit *edit = dynamic_cast<TEdit *>(control); 

    // If this control is a TEdit or any control deriving from it, we will have 
    // a pointer to it, if this is any other type, we will be left with a zero 
    // pointer. 
    if (edit) 
    { 
     // This is a TEdit control... we can now access TEdit only properties. 
     edit->Text = "This is an edit control."; 
    } 

    // We do the same if we want to test for a TButton... 
    TButton *button = dynamic_cast<TButton *>(control); 

    // Again we test whether this was actually a button 
    if (button) 
    { 
     // It is a button, again we can access TButton only properties... 
     button->Caption = "This is a button"; 
     // Yeah ok not a TButton only one, but couldn't think of any. 
    } 

    // And so on... 
} 

Вам не нужно, чтобы сделать функцию рекурсивного для дочерних элементов управления дочерних элементов управления, они включены здесь, а в VCL. Это, на мой взгляд, самое простое решение для тестирования для конкретных типов. Я также стараюсь избегать функций RTTI как можно больше, но это только я.

Как вы можете видеть, мой пример также показывает, как вы можете получить доступ к свойствам и функциям элемента управления, даже тех, которые относятся к определенному типу. Однако те, о которых вы упоминаете: Name, Width и Height являются общими для TControl, и для их доступа нет необходимости бросать их.

Надеюсь, это помогло вам, из моего примера должно быть ясно, что переменная container может быть заменена на myForm, которую вы используете в своем.

+0

Спасибо, Томми. Я отказался и закодировал это Pascal, используя оператор 'is'. Это здорово, что можно сделать это на C++. YOu say '' Вам не нужно делать функцию рекурсивной для дочерних элементов управления дочерних элементов управления, они также включены в VCL «', но что произойдет, если бы у меня было, скажем, TRadioGroup или некоторые элементы управления на TPanel? Они подхвачены вашим кодом? – Mawg

+0

Кстати, мне пришлось рекурсивно отвечать за TPanel и TGroupBox – Mawg

+0

Список Controls [] определен для родителя, к которому вы обращаетесь. Вложенные дочерние элементы управления должны обрабатываться с рекурсией. –

1

Это может помочь вам тоже:

for (int index = 0; index < ControlCount; index ++) 
{ 
    if(Controls[index]->InheritsFrom(__classid(TCustomEdit))) 
    { 
     TCustomEdit *edit = (TEdit*) Controls[index]; 
     edit->Text = "Ok"; 
    } 
}