Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.12.30;
Скачать: CL | DM;

Вниз

Копирование форм   Найти похожие ветки 

 
den303_work ©   (2007-10-08 09:02) [0]

Доброго всем времени!

Как можно наиболее быстро в рантайм создать форму на основе уже существующей, включая все контролы? Короче, создать полный клон формы.

Пока не придумал ничего лучше, чем пробегаться по списку элементов source-формы и создавать эти элементы на дочерней, но важна скорость создания...

Заранее спасибо :o)


 
clickmaker ©   (2007-10-08 09:37) [1]

не понял вопроса... просто создать еще один экземпляр формы - это разве не то же самое?


 
Сергей М. ©   (2007-10-08 09:38) [2]


> важна скорость создания


Без цикла в том или ином виде все равно не обойтись.
Другой вопрос - насколько оптимально и эффективно у тебя тело цикла ..


 
den303_work ©   (2007-10-08 09:48) [3]


> clickmaker ©   (08.10.07 09:37) [1]

Да, именно экземпляр формы. Но со всеми контролами.
Сейчас приходится пробегать по всем контролам на source-форме и создавать такие же с такими же параметрами на новой форме. Очень неэффективно. Есть ли что нибудь типа наследования или assign, чтобы менее затратно решить данную проблему?

Либо КАК создать экземпляр формы?


> Сергей М. ©   (08.10.07 09:38) [2]

Для построения каждого контрола приходится проверять его класс. Ужасно неоптимально.


 
KSergey ©   (2007-10-08 09:53) [4]

> den303_work ©   (08.10.07 09:48) [3]
> Да, именно экземпляр формы. Но со всеми контролами.
> Либо КАК создать экземпляр формы?

А как создаешь первую?

Вообще, любое кол-во экземпляров форм можно создать простым

  TForm1.Create(Application);

например.
Единственное - все создавться со значениями по умолчанию (текст в EdixBox"ах, например, размер и положение формы), но по вопросу не понятно надо ли это копировать. Если надо - то проще всего скопировать нужные свойства в уже созданную форму.


 
KSergey ©   (2007-10-08 09:56) [5]

В дополнение к предыдущему: ну и чтобы отобразилась все же форма (немодально) - тогда так

  with TForm1.Create(Application) do
     Show;


 
den303_work ©   (2007-10-08 10:03) [6]


> KSergey ©   (08.10.07 09:53) [4]

Трабла такая: в приложении при определённом событии нужно очень быстро создать и вывести на экран некую форму (макс. 50 мсек.). Вид формы и её элементов тянется из xml. Это доооолго :o(
Пошёл сл. путём: при запуске приложения я создаю эту форму, а при запросе нужно создать её экземпляр и вывести на экран. Получается много быстрее, но я не знаю, как оптимально создать экземпляр формы со всеми элементами и их параметрами.

Извиняюсь за сумбур :o)

ЗЫ:У меня есть хэндл окна source-формы, я знаю её тип (TForm, к примеру).
Сейчас тестовый пример выглядит так:
 
 FM:=(FindControl(COMHandle) as TMkF_Form);
 FMC:=TMkF_Form.Create(Application);
 with FMC do begin
   Height:=FM.Height;
   Width:=FM.Width;
   {...}
 end;
 for i:=0 to FM.ControlCount-1 do
   if FM.Controls[i].ClassName="TLabel" then begin
     pl:=FM.Controls[i] as TLabel;
     l:=TLabel.Create(FMC);
     l.Parent:=FMC;
     l.Caption:=pl.Caption;
     {...}
   end;
 FMC.Show;

Ужасно :o(


 
KSergey ©   (2007-10-08 10:16) [7]

> den303_work ©   (08.10.07 10:03) [6]
>  Вид формы и её элементов тянется из xml. Это
> доооолго :o(
> Пошёл сл. путём: при запуске приложения я создаю эту форму,
>  а при запросе нужно создать её экземпляр и вывести на экран.

Вот это я не понял: а зачем создавать еще один экземпляр? А если все же надо 2 экземпляра - так может при чтении xml сразу создавать 2 экземпляра? Или 3 (да хоть 10!) А потом просто отобразить нужный, быть может лишь проставив значения необходимым свойствам.
Я все же не понимаю зачем нужно именно копировать на лету имеющийся экземпляр формы.


 
den303_work ©   (2007-10-08 10:25) [8]


> KSergey ©   (08.10.07 10:16) [7]

В том то и дело, что этих экземпляров может быть сколько угодно. Такая вот своеобразная задача :o)
Посему заранее не могу создать нужное количество. Приходится клонировать.
Сейчас код такой:

var
 i:integer;
 l,pl:TLabel;
 img,imgc:TImage;
 bt,btc:TBitBtn;
 obj,objc:TControl;
begin
 FM:=(FindControl(COMHandle) as TMkF_Form);
 FMC:=TMkF_Form.Create(Application);
 with FMC do begin
   Height:=FM.Height;
   Width:=FM.Width;
   {..}
 end;
 for i:=0 to FM.ControlCount-1 do begin
   objc:=FM.Controls[i];
   if FM.Controls[i].ClassName="TLabel" then begin
     pl:=FM.Controls[i] as TLabel;
     l:=TLabel.Create(FMC);
     l.Font:=pl.Font;
     {..}
     obj:=l;
   end
   else
     if FM.Controls[i].ClassName="TImage" then begin
       imgc:=FM.Controls[i] as TImage;
       img:=TImage.Create(FMC);
       img.Transparent:=imgc.Transparent;
       {..}
       obj:=img;
     end
     else
       if FM.Controls[i].ClassName="TBitBtn" then begin
         btc:=FM.Controls[i] as TBitBtn;
         bt:=TBitBtn.Create(FMC);
         {..}
         obj:=bt;
       end;
   obj.Parent:=FMC;
   obj.Top:=objc.Top;
   {..}
 end;
 FMC.Show;
end;

В принципе, по времени укладываюсь, всеь спектр задачи охватываю. Но код ужасен и неоптимален ни разу вообще :o)


 
Slym ©   (2007-10-08 10:29) [9]

http://delphimaster.net/view/1-1189078540/


 
Плохиш ©   (2007-10-08 10:45) [10]


> den303_work ©   (08.10.07 10:25) [8]
>
> > KSergey ©   (08.10.07 10:16) [7]
>
> В том то и дело, что этих экземпляров может быть сколько
> угодно. Такая вот своеобразная задача :o)
> Посему заранее не могу создать нужное количество. Приходится
> клонировать.

Одновременно должны быть показаны идентичные формы в бесконечном количестве? Странная задача и бедные пользователи...


 
den303_work ©   (2007-10-08 10:59) [11]


> Плохиш ©   (08.10.07 10:45) [10]

Форма фотоидентификации. Предприятие огромно, в каждый момент времени может сотня людей одновременно пройти. Все формы надо вывести не столько для пользователей, сколько по ТЗ :o) Тем более, что этими формами управляет сервер, а не пользователь.


> Slym ©   (08.10.07 10:29) [9]

Пытался делать так:
 
 FM:=(FindControl(COMHandle) as TMkF_Form);
 Stream:=TMemoryStream.Create;
 MkF_Form:=TMkF_Form.Create(nil);
 Stream.WriteComponent(FM);
 FMC:=TMkF_Form.Create(Application);
 Stream.Position:=0;
 Stream.ReadComponent(FMC);

В принципе, подходит, но ошибка есть. Что, надо перед ReadComponent объекты создавать?


 
Slym ©   (2007-10-08 11:10) [12]

FMC:=TMkF_Form.CreateNew(Application);
Stream.Position:=0;
Stream.ReadComponent(FMC);


 
Сергей М. ©   (2007-10-08 11:23) [13]


> надо перед ReadComponent объекты создавать?


Не надо. Файлер сам создаст необходимые компоненты на форме-клоне, лишь бы перед записью формы в поток записываемые компоненты имели owner"ом записываемую форму.


 
den303_work ©   (2007-10-08 11:28) [14]


> Slym ©   (08.10.07 11:10) [12]

Великолепно работает, спасибо большое. Помогла предварительная регистрация классов. Весь код создания экземпляра класса (привожу "потомкам в пример", мож кому понадобится):

var
 Stream: TMemoryStream;
begin
 FM:=(FindControl(COMHandle) as TMkF_Form);  {поиск исходной формы по хэндлу}
 RegisterClasses([TLabel]);  {регистрация классов}
 RegisterClasses([TImage]);
 RegisterClasses([TBitBtn]);
 Stream:=TMemoryStream.Create;
 Stream.WriteComponent(FM);
 FMC:=TMkF_Form.CreateNew(Application);  {Создание экземпляра формы}
 Stream.Position:=0;
 Stream.ReadComponent(FMC);
 Stream.Free;
 FMC.Show;


 
korneley ©   (2007-10-08 13:47) [15]

Не знаю, может я неправильно понял условия задачи... У меня были ситуации, когда нужно  иметь несколько экземпляров одной и той же формы. Со всеми контролами. Делал просто: в дизайн-тайме рисовал, убирал переменную из модуля и автосоздание из проекта. Когда надо - создавал обычным TForm1.Create(), (ну или как там класс назывался) с сохранением ссылки, стало не надо - Free. Всё работало, а может просто повезло :)



Страницы: 1 вся ветка

Текущий архив: 2007.12.30;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.02 c
15-1196147650
em240
2007-11-27 10:14
2007.12.30
MsSql2000+транзакции


2-1196692582
..::KraN::..
2007-12-03 17:36
2007.12.30
TImage на рабочий стол


2-1196610039
Dark
2007-12-02 18:40
2007.12.30
Свойства файлов


2-1196604891
DevilDevil
2007-12-02 17:14
2007.12.30
Программно выделить определённую ячейку StringGrid-а


15-1196393774
Lebedev
2007-11-30 06:36
2007.12.30
Если писать программу для Windows 98?