Текущий архив: 2005.10.30;
Скачать: CL | DM;
ВнизКлон компонента Найти похожие ветки
← →
stalker780 (2005-10-04 12:56) [0]Подскажите плз.
Как можно создать полный аналог уже существующего компонента в рантайме?
Есть компонент dst_contacts: TpFIBDataset
Нужно создать в рантайме еще несколько таких же независимых компонентов со всеми параметрами, скриптами и полями, но соответсвенно с другим именем.
← →
Digitman © (2005-10-04 12:58) [1]см. TPersistent.Assign()
← →
stalker780 (2005-10-04 13:10) [2]дело в том, что уже пробовал :(
говорит cannot Assign TpFIBDataset to a TpFIBDataset
А есть еще какие-то способы?
← →
Digitman © (2005-10-04 13:19) [3]
> А есть еще какие-то способы?
а думать-то пытался, почему "Сannot Assign .." ?
исходники-то - перед носом ..
← →
Бурундук © (2005-10-04 14:23) [4]Попробуй записать в поток и прочитать из него:
{--------------------------------------------------------------}
function CloneComp(AComp, ARoot,
ANewRoot, ANewOwner: TComponent; ANewParent: TWinControl): TComponent;
var TxtStream: TStream;
//i: Integer;
begin
{RegisterClass(TComponentClass(AComp.ClassType));
if AComp is TWinControl then
for i := 0 to TWinControl(AComp).ControlCount-1 do
RegisterClass(TComponentClass(TWinControl(AComp).Controls[i].ClassType));}
TxtStream := TMemoryStream.Create;
try
SaveComp(AComp, ARoot, TxtStream);
Result := CreateComp(ANewRoot, ANewOwner, ANewParent, TxtStream);
finally
TxtStream.Free;
{UnregisterClass(TComponentClass(AComp.ClassType));
if AComp is TWinControl then
for i := 0 to TWinControl(AComp).ControlCount-1 do
UnregisterClass(TComponentClass(TWinControl(AComp).Controls[i].ClassType));}
end;
end;
{------------------------------------------------------------------------------}
type
TDummy = class
class procedure ReaderSetName(Reader: TReader; Component: TComponent;
var Name: string);
end;
class procedure TDummy.ReaderSetName(Reader: TReader; Component: TComponent;
var Name: string);
begin
if (Reader.Owner <> nil) and
(Reader.Owner.FindComponent(Name) <> nil) then
Name := "";
// Это самое простое, что можно придумать, чтобы избежать конфликта имён.
// Всё равно в рантайме имена не слишком важны
end;
function CreateComp(ARoot, AOwner{, AComp}: TComponent; AParent: TWinControl;
SrcTxtStream: TStream): TComponent;
var
BinStream: TStream;
Reader: TReader;
Comp: TComponent;
begin
BinStream := TMemoryStream.Create;
try
Reader := TReader.Create(BinStream, 4096);
SrcTxtStream.Position := 0;
ObjectTextToBinary(SrcTxtStream, BinStream);
try
Reader.Position := 0;
Reader.Owner := AOwner;
Reader.Parent := AParent;
Reader.Root := ARoot;
// Владелец, родитель для создаваемого из потока
// компонента и корневой компонент (в РТТИ-таблицах
// которого ридер будет искать обработчики событий,
// классы и т.д.)
Reader.OnSetName := TDummy.ReaderSetName;
// Для разрешения конфликтов имён
Reader.BeginReferences;
try
Reader.ReadSignature;
Comp := Reader.ReadComponent(nil {AComp});
Result := Comp;
Reader.FixupReferences;
// инициализирует свойства-ссылки на другие
// компоненты, хранящиеся в ДФМ как имена
finally
Reader.EndReferences;
end;
finally
Reader.Free;
end;
finally
BinStream.Free;
end;
end;
procedure SaveComp(AComp, ARoot: TComponent; DestTxtStream: TStream);
var BinStream: TStream;
Writer: TWriter;
begin
BinStream := TMemoryStream.Create();
try
Writer := TWriter.Create(BinStream, 4096);
try
Writer.Root := ARoot;
Writer.WriteSignature;
Writer.WriteComponent(AComp);
Writer.WriteListEnd;
finally
Writer.Free;
end;
BinStream.Position := 0;
ObjectBinaryToText(BinStream, DestTxtStream);
finally
BinStream.Free;
end;
end;
Страницы: 1 вся ветка
Текущий архив: 2005.10.30;
Скачать: CL | DM;
Память: 0.47 MB
Время: 0.04 c