Форум: "Основная";
Текущий архив: 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