Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2007.12.30;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.008 c
2-1197019950
Иван1
2007-12-07 12:32
2007.12.30
Динамический массив


2-1196612331
@!!ex
2007-12-02 19:18
2007.12.30
Частый вызов SetLength(Count+10)


4-1181733847
Валькирия
2007-06-13 15:24
2007.12.30
winrar


2-1196767613
LexXL
2007-12-04 14:26
2007.12.30
обрезать картинку


2-1196768252
abhtr
2007-12-04 14:37
2007.12.30
Запрос для набора данных DBGrid-a.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский