Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Копия окна, подскажите пути решения! 
V
    Опции темы
act_naturally
  Дата 4.10.2010, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Доброго дня!

Нахожусь в небольшом тупике. Есть приложение в котором у главного окна (MainForm) в процессе работы создаётся много дочерних форм.  Все они разных типов, наследующих от TForm.

По нажатию кнопки все открытые дочерние окна должны быть закрыты 
(с этим проблем нет MainForm->MDIChildren[i]->Close()) 
Но так же нужно создать окна этих же типов заново!

То есть нужно перебирать открытые окна, закрывать каждое и открывать(создавать) такое же (так как необходимо, чтобы отработали заново конструктор и FormCreate())

Возможно ли решить проблему не влезая в классы дочерних окон и не создавая конструктор копирования?

Приведёт ли к решению CreateWindow? пока что функция возвращает ошибку: незарегистрированное имя класса, которое я беру из MainForm->MDIChildren[i]->ClassName().

Спасибо!)
PM MAIL   Вверх
Platov
Дата 4.10.2010, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(act_naturally @  4.10.2010,  12:43 Найти цитируемый пост)
(так как необходимо, чтобы отработали заново конструктор и FormCreate())
 Может проще выполнить конструктор и FormCreate(), чем закрывать и открывать окна?

PM MAIL   Вверх
xvr
Дата 4.10.2010, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Посмотрите как BCB создает окна при старте.
Код

         Application->CreateForm(__classid(TMainForm), &MainForm);
ClassID вроде можно получить от экземпляра формы, т.ч. можно и форму создать снова

PM MAIL   Вверх
act_naturally
Дата 4.10.2010, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо за скорый ответ!

Цитата(Platov @  4.10.2010,  13:04 Найти цитируемый пост)
Может проще выполнить конструктор и FormCreate(), чем закрывать и открывать окна?

У меня есть только указатель на дочернее окно MainForm->MDIChildren[i] типа TForm*, каким образом выполнить конструктор нужного класса формы, ведь дети могут быть разнообразных классов? А FormCreate() у TForm - закрытый метод.

Цитата(xvr @  4.10.2010,  13:21 Найти цитируемый пост)
         Application->CreateForm(__classid(TMainForm), &MainForm);

Было бы здорово, но __classid(<тип>), увы, опять же принимает на вход тип. А я могу достать только имя типа в процессе выполнения.. Как достать id класса без конструкции __classid(<тип>) - пока не пойму. 

Ещё, конечно, смущает документация: "Do not call CreateForm in an application. C++Builder’s module manager calls CreateForm internally to register the applet objects with the applet application." smile


PM MAIL   Вверх
xvr
Дата 4.10.2010, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(act_naturally @ 4.10.2010,  14:07)
Цитата(xvr @  4.10.2010,  13:21 Найти цитируемый пост)
         Application->CreateForm(__classid(TMainForm), &MainForm);

Было бы здорово, но __classid(<тип>), увы, опять же принимает на вход тип. А я могу достать только имя типа в процессе выполнения.. Как достать id класса без конструкции __classid(<тип>) - пока не пойму. 

Код

MainForm->MDIChildren[i]->ClassType()


Цитата

Ещё, конечно, смущает документация: "Do not call CreateForm in an application. C++Builder’s module manager calls CreateForm internally to register the applet objects with the applet application." smile
У вас нестандартная задача, она требует нестандартных методов решения  smile 

PM MAIL   Вверх
act_naturally
  Дата 5.10.2010, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



xvr
СПАСИБО! Наконец-то дошло, что MainForm->MDIChildren[i]->ClassType() - можно использовать вместо всего выражения __classid(<тип>).


Итак, теперь у меня такой код:
 
Код

TForm *mChild;
Application->CreateForm(frmMain->MDIChildren[i]->ClassType(), &mChild);
mChild->Show();


В итоге, сначала отрабатывает конструктор от TForm, а потом функция FormCreate от MDIChildren[i]->ClassType().

Как же добиться того, чтобы и конструктор отрабатывал от нужного класса!? Ведь в коде я ещё не знаю, какой у дочернего окна будет тип, поэтому и создаю указатель типа TForm и передаю этот указатель в функцию CreateForm.

PM MAIL   Вверх
xvr
Дата 5.10.2010, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(act_naturally @  5.10.2010,  10:49 Найти цитируемый пост)
Как же добиться того, чтобы и конструктор отрабатывал от нужного класса!?
Он и будет от нужного класса, а не от TForm (у TForm конструктор описан виртуальным - это расширение от Borland). Но конструктор у 'нужного класса' должен по сигнатуре совпадать с конструктором TForm, т.е. быть
Код

class YourForm : public TForm {
...
__fastcall virtual YourForm(Classes::TComponent* AOwner) : TForm(AOwner) {...}
__fastcall virtual YourForm(Classes::TComponent* AOwner, int Dummy) : TForm(AOwner,Dummy) {...}
...
};


PM MAIL   Вверх
act_naturally
Дата 5.10.2010, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



xvr

ещё одна попытка (если, допустим, я заранее знаю, что тип будет TfrmMyList):

Код

class TfrmMyList : public TBaseForm
{
public:        // User declarations
    __fastcall  TfrmMyList(TComponent* Owner);
};

__fastcall  TfrmMyList::TfrmMyList(TComponent* Owner)
    : TBaseForm(Owner) 
{ ShowMessage("TfrmMyList"); }

/////////////

class PACKAGE TBaseForm : public TForm
{
public:    
    __fastcall TBaseForm(TComponent* Owner);

protected:
    DYNAMIC void __fastcall DoClose(TCloseAction &Action);
__published:
};

__fastcall TBaseForm::TBaseForm(TComponent* Owner)
    : TForm(Owner)
{
    ShowMessage("TBaseForm"); 
    
    FormStyle = fsMDIChild;
    Position = poDefaultPosOnly;  //fix for Anchors
    ScaleConstraints(this);
}



тогда:

Код

                                TfrmMyList *mChild;
                                ShowMessage(frmMain->MDIChildren[i+i]->ClassType()->ClassName());   //показывает "TfrmMyList"
                                Application->CreateForm(frmMain->MDIChildren[i+i]->ClassType(), &mChild);
                                mChild->Show();



Срабатывает только  ShowMessage("TBaseForm"), то есть конструктор  TfrmMyList не запускается :(

В документации забавно написано:
"void __fastcall CreateForm(System::TMetaClass* InstanceClass, void *Reference);

Description:
CreateForm creates a new form of the type specified by the FormClass parameter and assigns it to the variable given by the Reference parameter. The owner of the new form is the Application object. "

При этом параметра FormClass в документации у функции не указано. Интуитивно, хотелось бы, чтобы создавалась форма типа InstanceClass, но, судя по примеру, хм, не понимаю, что, "судя по примеру"...  Отрабатывает только родительский конструктор :(

Это сообщение отредактировал(а) act_naturally - 5.10.2010, 15:30
PM MAIL   Вверх
xvr
Дата 5.10.2010, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Попробуйте перегрузить и второй конструктор (с 2м целым параметром Dummy), IMHO именно он вызывается в CreateForm

Цитата(act_naturally @  5.10.2010,  12:43 Найти цитируемый пост)
Срабатывает только  ShowMessage("TBaseForm"), то есть конструктор  TfrmMyList не запускается :(
Это совсем непонятно - у вас 2 наследника (в цепочке) от TForm: TBaseForm и TfrmMyList, причем они не отличаются в конструкции себя  smile Тогда почему конструктор одного наследника срабатывает, а второго нет?


PM MAIL   Вверх
act_naturally
Дата 5.10.2010, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Моя ошибка! Надо было здесь в примере сразу указать, что в конструкторе TfrmMyList(TComponent* Owner) есть ещё второй параметр, со значением по умолчанию ( т.е.
Код
 __fastcall TfrmMyList(TComponent* Owner,  Variant pDefaultID=Variant::Empty())
)
Это-таки принципиально, и если убрать параметр по умолчанию, то, действительно, конструктор вызывается.
Жаль.
Получается, что решения пока что найти не могу, и каждый конструктор типа дочернего окна, заявленный как конструктор с несколькими параметрами, отрабатывать не будет.

Спасибо за помощь!
PM MAIL   Вверх
act_naturally
Дата 5.10.2010, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Понятно теперь, что общего решения нет из-за непредсказуемости аргументов в конструкторах дочерних форм. 

Остаётся один путь - создавать новые дочерние формы перебором по всем возможным типам.

 smile 


 smile 
PM MAIL   Вверх
xvr
Дата 5.10.2010, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(act_naturally @  5.10.2010,  16:11 Найти цитируемый пост)
Понятно теперь, что общего решения нет из-за непредсказуемости аргументов в конструкторах дочерних форм. 
А откуда вы собирались брать эти аргументы для реконструирования этих форм? Если из значений по умолчанию, то можно просто сделать 2 конструктора - один без параметров (и задать все оригинальные умолчательные параметрами прямо в теле конструктора), и второй с 2мя обязательными и всеми остальными умолчательными параметрами. Тогда создание через Application->CreateForm будет работать


PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

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

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

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

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


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

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


 




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


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

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