Форум: "Основная";
Текущий архив: 2003.05.08;
Скачать: [xml.tar.bz2];
ВнизКак скопировать все компоненты с одной формы на другую? Найти похожие ветки
← →
Unknown user (2003-04-23 19:18) [0]Как скопировать все компоненты с одной формы-насленика TForm на другую- наследник TCustomForm? ПРичем со значениями всех свойств.
← →
sts (2003-04-23 19:46) [1]Что-то типа того (как вариант):
var
mem : TMemoryStream;
c : TComponent;
begin
for i := 0 to Form1.ComponentCount-1 do begin
c := Components[i].ClassType.CreateNew;
mem.ReadComponent(Form1.Components[i]);
mem.Position := 0;
mem.WriteComponent(c);
mem.Clear;
c.Owner := Form2;
end;
mem.Free;
end;
Только с Owner-ом может ерунда выйти (он, вроде, тоже копируется в поток ?).
← →
Unknown user (2003-04-23 20:30) [2]Ошибочка CreateNew -нет такого метода в TComponent. И потом надо ведь и Parent менять.
← →
Юрий Зотов (2003-04-23 22:32) [3]Сохраните первую форму ЦЕЛИКОМ в поток, потом залейте этот поток на вторую форму. Тогда будут правильно назначены и Owner, и все Parent"ы, и все остальное.
← →
Unknown user (2003-04-24 18:18) [4]Оно вроде просто, звучит -"залейте этот поток на вторую форму". Но сделать у меня так не получалось -необходимо чтобы Source b Dest , были одного класса. Если источник TForm2, с кнопкой и, например гроупбоксом, то и в классе получателя должны быть также описаны TButton и TGroupBox.
← →
Skier (2003-04-24 18:20) [5]
> то и в классе получателя должны быть также описаны TButton
> и TGroupBox.
RegisterClass(es) ?
← →
Anatoly Podgorestky (2003-04-24 18:22) [6]Ctrl+С -> Ctrl+V
← →
Unknown user (2003-04-24 18:51) [7]To Skier. Да я использую данную процедуру для того чтобы можно было создавать объекты нужного класса на основании имени класса.
To Anatoly Podgorestky. Юмор понял. А теперь вариант для RunTime, ежели не сложно.
← →
Skier (2003-04-24 18:55) [8]TClipboard.GetComponent
TClipboard.SetComponent ?
← →
Unknown user (2003-04-24 19:31) [9]To Skier, To Anatoly Podgorestky. Да так гораздо проще, я про буфер что-то и не подумал вовсе. И вот подсказали что есть такой незамеченный метод у TComponent -InsertComponent тогда и RegisterClass не нужна.
← →
Юрий Зотов (2003-04-24 20:25) [10]> Unknown user
RegisterClass не нужна в любом случае, поскольку обе формы живут в одной программе. Все уже зарегистрировано первой формой.
Копирование через Clipboard может нарушить Parent"ы, поэтому его надо делать аккуратно - с рекурсией и в цикле по Controls, а не по Components (плюс еще невизуальные компоненты). Но самое главное, что при таком копировании могут быть уничтожены межкомпонентские ссылки, поэтому "порядок имеет значение". В общем, это будет неплохая головная боль.
Заливка в поток, а потом из потока - это самый простой, самый универсальный и самый надежный механизм. А что касается Вашего
"необходимо чтобы Source и Dest были одного класса",
то это необходимо лишь в том случае, если в коде Dest (или в ресурсах Source) есть прямые ссылки на компонентские ПОЛЯ (кстати, в этом случае Source и Dest должны быть одного класса при ЛЮБОМ способе копирования, поскольку помимо самих КОМПОНЕНТОВ Dest должна будет иметь и соответствующие им ПОЛЯ).
Если же в коде Dest и в ресурсах Source прямых ссылок на компонентские ПОЛЯ нет, то класс Dest от класса может отличаться. Просто зальются компоненты, вот и все.
Только зачем такие заморочки? Что мешает использовать ReadComponentXXX, как функцию, создающую экзепляр класса и читающую сам класс из того же потока? Ничто. Общая ссылка будет именно TCustomForm (или TForm), а реально будет создаваться полностью работоспособный экземпляр КОНКРЕТНОГО класса, причем ЛЮБОГО класса.
← →
Anatoly Podgorestky (2003-04-24 21:32) [11]Unknown user © (24.04.03 18:51)
Причем тут юмор, из твоего вопроса больше исходило что в дизайнтайм, а буфер использовать в рантайм последнее дело, пользователи этому не будут рады.
← →
Unknown user (2003-04-25 19:57) [12]To Anatoly Podgorestky. В том и юмор, что про возможность скопировать компонент с одной формы на другую(в DesignTime)я не догадывался, какие еще загадки IDE вы мне раскроете?
То Юрий Зотов. Спасибо за столь подробный ответ. Буду разбираться.
← →
Unknown user (2003-04-25 20:07) [13]To Anatoly Podgorestky. Может ваше компетентное мнение поможет мне в другом вопросе- http://delphimaster.net/view/4-1051088291/.
← →
Anatoly Podgoretsky (2003-04-25 20:11) [14]Компетентными бывают органы, а мнению можно доверять или нет.
← →
Юрий Зотов (2003-04-26 13:43) [15]> Unknown user © (25.04.03 19:57)
А чтобы разбираться было легче, привожу демонстрацию решения Вашей задачи. Это стандартный проект с двумя автосоздаваемыми формами. Как Вы увидите, функция CreateClone создает ПОЛНОСТЬЮ работоспособную и ТОЧНУЮ копию ЛЮБОЙ формы, переданной ей в качестве Source (включая не только все компоненты, но и все обработчики событий). Причем создает именно самостоятельным копированием через поток, а не простым вызовом Create.
unit Unit1;
interface
uses
Classes, Controls, Forms, StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure FormShow(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure OnCloneClose(Sender: TObject; var Action: TCloseAction);
end;
var
Form1: TForm1;
function CreateClone(Source: TCustomForm): TCustomForm;
implementation
{$R *.DFM}
uses
Unit2;
type
TFriendForm = class(TCustomForm);
function CreateClone(Source: TCustomForm): TCustomForm;
begin
Result := TCustomFormClass(Source.ClassType).CreateNew(Application);
with TMemoryStream.Create do
try
WriteComponent(Source);
Position := 0;
ReadComponent(Result)
finally
Free
end;
with TFriendForm(Result) do
begin
OnClose := Form1.OnCloneClose;
SetBounds(Left + 20, Top + 20, Width, Height);
Show;
end
end;
{ TForm1 }
procedure TForm1.FormShow(Sender: TObject);
begin
Form2.Show
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
CreateClone(Self)
end;
procedure TForm1.OnCloneClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree
end;
end.
==========================
unit Unit2;
interface
uses
Classes, Controls, Forms, StdCtrls;
type
TForm2 = class(TForm)
ListBox1: TListBox;
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
var
Form2: TForm2;
implementation
{$R *.DFM}
uses
Unit1;
procedure TForm2.Button1Click(Sender: TObject);
begin
CreateClone(Self)
end;
end.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.05.08;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.007 c