C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Нужно программно узнать, есть ли указанное, свойство у компонента или нет.
Wasabi
Отправлено: 20.07.2004, 09:11


Ученик-кочегар

Группа: Участник
Сообщений: 23



Просто я перебираю компоненты на форме и применяю им
CODE

...
TComponent *ChildControl;
(TКласс*)ChildControl)->Font->Size=размер
...

Но у того же Menu свойства font->size нет. И я получу эксепшн при вышеописанном действии.

Как узнать, имеет ли компонент этот Property или нет?
AVC
Отправлено: 20.07.2004, 09:36


Ветеран

Группа: Модератор
Сообщений: 1583



Здесь вы сможете найти ответ. Функция НЕ адаптирована под ваши нужды, если не получится помогу. Идея — искать property по имени Font
CODE

PACKAGE AnsiString __fastcall ObjPropsInfo (TObject *obj)
{
if (!obj) return "NULL";

int cou = GetTypeData(PTypeInfo(obj->ClassInfo()))->PropCount;
if (cou <= 0) return "";

TStringList *slist = new TStringList;
slist->Clear();

bool isok = true;
char *buf = new char[cou*sizeof(PPropInfo)];
try {

AnsiString name;
AnsiString tname;
AnsiString erstr = "Error: ";

PPropList proplist = (PPropList)(buf);
PPropInfo propinfo;
PTypeInfo typeinfo;

Typinfo::TTypeKind kind;
Variant val;

GetPropInfos(PTypeInfo(obj->ClassInfo()), proplist);

for (int i=0; i < cou; i++)
{ propinfo = *(proplist+i);
if (!propinfo) continue;

name = AnsiString(propinfo->Name);

typeinfo = *(propinfo->PropType);
if (!typeinfo)
{ slist->Add(ClpPad(name,20) + erstr + "Bad TypeInfo");
continue;
}

kind = typeinfo->Kind;
if (kind == tkMethod ) continue;

tname = AnsiString(typeinfo->Name).Trim().UpperCase();

try { val = GetPropValue(obj, name, true); }
catch (Exception &xcp) { val = erstr + xcp.Message; isok = false; }

if (kind == tkClass )
{ try { val = loc_SObj ( (TObject*) (int(val)) ); }
catch (Exception &xcp) { val = erstr + xcp.Message; isok = false; }
}

slist->Add(ClpPad(name,30) + VarToString(val));
}

} // try buf
catch (Exception &xcp)
{ isok = false;
slist->Add(AnsiString("Error: ") + xcp.Message);
}

delete[] buf;

if (isok) slist->Sort();

AnsiString rettext = slist->Text;
delete slist;

return rettext;
}
//---------------------------------------------------------------------------

смотрите в районе propinfo->Name

Отредактировано AVC — 20/07/2004, 09:39
Guest
Отправлено: 20.07.2004, 09:51


Не зарегистрирован







Спасибо Вам большое. Разобрался smile.gif

Так как у меня вопросов целая телега, позволю задать еще один smile.gif

Есть такая функция, которая перебирает компоненты на форме и меняет им свойство размера шрифта. Но там приходится описывать все компоненты к которым хочешь поменять шрифт руками.
CODE


TComponent *ChildControl;
AnsiString S;
for (int I = frm->ComponentCount-1; I >= 0; I--)
    {
      ChildControl=frm->Components[I];
      S=ChildControl->ClassName();

      if(S=="TLabel")
        ((TLabel *)ChildControl)->Font->Size=ReadSize(size, ChildControl->ClassName());

      if(S=="TEdit")
        ((TEdit *)ChildControl)->Font->Size=ReadSize(size, ChildControl->ClassName());

      if(S=="TMemo")
        ((TMemo *)ChildControl)->Font->Size=ReadSize(size, ChildControl->ClassName());

      if(S=="TButton")
        ((TButton *)ChildControl)->Font->Size=ReadSize(size, ChildControl->ClassName());

      if(S=="TListView")
        ((TListView *)ChildControl)->Font->Size=ReadSize(size, ChildControl->ClassName());

    }



Как нить изящней низя это сделать ли, одной строкой для всех компонетов?

((TКласс *)ChildControl)->Font->Size=ReadSize(size, ChildControl->ClassName());
AVC
Отправлено: 20.07.2004, 09:59


Ветеран

Группа: Модератор
Сообщений: 1583



Использовать свойство ParentFont и заставить это делать сам компонент.
В коде поменять if на else if и самые вероятные компоненты вынести вперед — станет более оптимально.
Wasabi
Отправлено: 20.07.2004, 13:39


Ученик-кочегар

Группа: Участник
Сообщений: 23



Почему вот так работает?
dynamic_cast(ChildControl)->Left)

А вот так:
dynamic_cast(ChildControl)->Font->Size)
не работает?

Потому что свойство Font в классе TControl — Protected?

Как правильно добраться до этого свойства?

Спасибо
AVC
Отправлено: 20.07.2004, 14:18


Ветеран

Группа: Модератор
Сообщений: 1583



1. Работать через класс, у которого это свойство расшарено. Т.е. приходим к варианту if, else if

2. Через "временный" класс. Например:
CODE

class TTempControl : public TControl
{public: void __fastcall SetFontSize(int pNewSize); };

void __fastcall TTempControl::SetFontSize(int pNewSize)
{ (TControl::Font)->Size = pNewSize; }

// использование
void __fastcall TFMain::BitBtn1Click(TObject *Sender)
{
TTempControl *ctrl = (TTempControl*) Sender;
ctrl->SetFontSize(24);
}
Wasabi
Отправлено: 20.07.2004, 16:04


Ученик-кочегар

Группа: Участник
Сообщений: 23



Оно самое!!!

Слушай, Спасибо Тебе БОЛЬШОЕ!!!
smile.gif
AVC
Отправлено: 20.07.2004, 17:05


Ветеран

Группа: Модератор
Сообщений: 1583



На здоровье.
Аккуратней с вариантом 2 — это потенциальный источник ошибок.

Вернуться в Вопросы программирования в C++Builder