Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Динамическое создание компонентов 
:(
    Опции темы
fenix666
Дата 7.7.2010, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 29.3.2008

Репутация: нет
Всего: нет



Есть xml файл с набором компонентов, с определенными для них свойствами. Необходимо создать эти компоненты на форме. Пробовал следующим образом, не получилось:
Код

RegisterClass(__classid(TButton));
TClass cls = GetClass("TButton");/ 
Tobject *obj = cls->InitInstance(SysGetMem(cls->InstanceSize(cls) ));
SetPropValue(obj,"Caption","Test");

Память выделяется, проверяю obj->ClassName() возвращает 'TButton'. Но при вызове функции SetPropValue выходит ошибка EAccessViolation.

Может кто знает как все-таки динамически создать объект нужного типа
PM MAIL   Вверх
UniBomb
Дата 7.7.2010, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
***
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 1754
Регистрация: 24.10.2006
Где: Санкт-Петербург

Репутация: 3
Всего: 97



Код

TButton *btn = new TButton(Form1);
btn->Caption = "test";



--------------------
PM MAIL ICQ Skype   Вверх
fenix666
Дата 7.7.2010, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 29.3.2008

Репутация: нет
Всего: нет



Цитата(UniBomb @ 7.7.2010,  11:44)
Код

TButton *btn = new TButton(Form1);
btn->Caption = "test";

Так я и сам знаю, но этот метод не подходит, т.к. если на форме тока кнопки то да, а если там около 20 разных компонентов, для каждого описывать создание не удобно, хочется универсальную функцию написать
PM MAIL   Вверх
borisbn
Дата 7.7.2010, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



есть плагин к builder'у, который позволяет набросать и настроить визуально компоненты на форме, а потом он генерит код.
Можно ещё собственный парсер *.dfm файлов написать ( в принципе, ничего сложного )


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
fenix666
Дата 8.7.2010, 06:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 29.3.2008

Репутация: нет
Всего: нет



Цитата(borisbn @ 7.7.2010,  17:35)
есть плагин к builder'у, который позволяет набросать и настроить визуально компоненты на форме, а потом он генерит код.
Можно ещё собственный парсер *.dfm файлов написать ( в принципе, ничего сложного )

Спасибо за совет, но парсер отпадает, т.к. в билдере тока основную форму в редакторе далаю, а все остальные генерирую. Генератор кода тоже не вариант, т.к. смысл хранить код для 4-8 форм, если они могу и не вызваться%) Сомневаюсь что все так извращаются и пишут сотни строк ненужного кода. Проще функцию написать, для создания формы по заранее написанному конфигу. 
PM MAIL   Вверх
mrbrooks
Дата 8.7.2010, 07:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



интересно, а как будет анализироваться конфиг, если парсер не годится? За счет белой магии?
PM MAIL   Вверх
borisbn
Дата 8.7.2010, 07:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



Редактор форм в билдере есть не что иное как генератор этих самых
> заранее написанных конфигов
Я ж тебе и предлагаю сделать парсер этих конфигов (dfm), а включать cpp, h  и dfm в проект необязательно

Добавлено через 13 минут и 36 секунд
Не хочу нарываться на hollywar, но в Qt это уже сделано с помощью QUiLoader. Посмотри в эту сторону.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
xvr
Дата 8.7.2010, 10:11 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



А почему бы не воспользоваться системой стриминга самого Builder'а. Создать поток с формой (.dfm или бинарной), а потом через TStream::ReadComponent(TForm*)

PM MAIL   Вверх
Alexeis
Дата 8.7.2010, 10:27 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



fenix666, приведенный способ чистой воды хак, поскольку не вызывается конструктор объекта жди сюрпризов.

Можно воспользоваться недокументированной особенностью  объекта TApplication. Дело в том, что класс TApplication довольно безопасный и при создании формы внимательно проверяет что созданный объект строго является формой. Однако до создания объекта он не может выяснить что за метакласс ему подсунули и в результате он может запросто создать любого наследника TComponent.

Например:

Код

    TControl *cntl;
    RegisterClass(__classid(TButton));
    Application->CreateForm(__classid(TButton), &cntl);
    cntl->Parent = this;
    SetPropValue(cntl, L"Left", 50);
    SetPropValue(cntl, L"Top", 50);
    SetStrProp(cntl, L"Caption", L"Test");


Есть еще правильный вариант. Написать Паскалевский модуль, в котором будет всего одна функция, которая честно реализует функцию CreateComponent по всем правилам. И добавить этот модуль в проект на билдере. 
  Не ясно почему авторы билдера до сих пор не написали такую необходимую в билдере функцию. Видимо, как обычно, все внимание на мэинстрим.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
fenix666
Дата 8.7.2010, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 29.3.2008

Репутация: нет
Всего: нет



Цитата(borisbn @ 8.7.2010,  07:47)
Я ж тебе и предлагаю сделать парсер этих конфигов (dfm), а включать cpp, h  и dfm в проект необязательно

Даже если парсер dfm написать, то возникает опятьже вопрос, как всетаки создать динамически компонент(контрол)? 
Конструкцию типа Tclass *cls = new Tclass() не подходит, нужно чтото универсально, чтобы для любого класса создавалось

Это сообщение отредактировал(а) fenix666 - 8.7.2010, 10:37
PM MAIL   Вверх
borisbn
Дата 8.7.2010, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



fenix666, почему именно 
Цитата(fenix666 @  8.7.2010,  10:36 Найти цитируемый пост)
Tclass *cls = new Tclass()

в dfm содержится указание типа класса
Цитата

object MainForm: TMainForm
...
  object Label1: TLabel
...
  end
end

ну и делай
Код

if ( className == "TMainForm" )
{
    form = new TMainForm;
}
else if ( className == "TLabel" )
{
    label = new TLabel;
}

хотя, предыдущие советы по TStream::ReadComponent, Application->CreateForm и CreateComponent проще реализовать


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
fenix666
Дата 8.7.2010, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 29.3.2008

Репутация: нет
Всего: нет



Цитата(Alexeis @ 8.7.2010,  10:27)
Есть еще правильный вариант. Написать Паскалевский модуль, в котором будет всего одна функция, которая честно реализует функцию CreateComponent по всем правилам. 

Нельзя ли поподробнее?
PM MAIL   Вверх
Alexeis
Дата 8.7.2010, 12:02 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



Цитата(fenix666 @  8.7.2010,  10:22 Найти цитируемый пост)
Нельзя ли поподробнее? 

Код

unit VCLCreate;

interface

uses classes;

function CreateComponent(cl : TComponentClass; AOwner : TComponent) : TComponent;

implementation

function CreateComponent(cl : TComponentClass; AOwner : TComponent) : TComponent;
begin
  Result := cl.Create(AOwner);
end;

end.


Код

#include "VCLCreate.hpp"

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    TControl *cntl;
    RegisterClass(__classid(TButton));
  //    Application->CreateForm(__classid(TButton), &cntl);
    cntl = dynamic_cast<TControl*>(CreateComponent(__classid(TButton), this));
    cntl->Parent = this;
    SetPropValue(cntl, L"Left", 50);
    SetPropValue(cntl, L"Top", 50);
    SetStrProp(cntl, L"Caption", L"Test");
}


Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  _____________2_.zip 6,95 Kb


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Vyacheslav
Дата 9.7.2010, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Код

////////////////////////////////////////////////////////
// Создание компонента по его метаклассу: 
//   (Из форума RSDN) 

TComponent *CreateComponent( TComponentClass CClass, TComponent *AOwner)
{
  typedef TComponent *( __fastcall *TConstructor)( TComponentClass, bool, TComponent *); 
  TConstructor constructor = ((TConstructor *) CClass)[ vmtCreateObject - 1]; 
 return constructor( CClass, true, AOwner);
};  





--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.1053 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.