Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
3-23017
Katya
2003-04-18 10:59
2003.05.08
BLOB


8-23238
0$a
2003-01-29 23:14
2003.05.08
перерисовка компонента


3-22937
Tomkat
2003-04-18 13:05
2003.05.08
Поик подстроки символов


6-23253
ferrik
2003-03-10 20:19
2003.05.08
WinSock


1-23084
MAX22
2003-04-26 15:24
2003.05.08
Как сделать глобальную процедуру





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский