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

Вниз

Как скопировать все компоненты с одной формы на другую?   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.016 c
1-23198
AbrosimovA
2003-04-24 14:50
2003.05.08
Проблема произвести сортировку <U><B>с учетом регистра</B></U>


3-22989
Andy Verinov
2003-04-17 00:09
2003.05.08
Вешается BDE от большого числа запросов?


1-23149
_MAXi_
2003-04-23 16:15
2003.05.08
TreeView Nodes разными цветами?


3-23025
pavel_rosl
2003-04-17 02:17
2003.05.08
сосчитать сумму


14-23362
msoftware
2003-04-21 10:53
2003.05.08
Где достать INTERBAZE???