![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Создание копии (одной или нескольких) компонента RTTI [D5, Win2k]
Afonya © (2004-07-30 17:05:00)Добрый день!
Пробую я сделать копию компонента (панель + на ней еще несколько других контролов).
Записую их в поток, а вот создать копии из потока не могу, так как система крычыть, что компонент с таким именем уже существует. Пробовал перехватывать событие Reader.OnSetName - но ошибка почему то происходит раньше.
У меня к Вам большая просьба, если кто наступал на эти грабли - помогите!
Юрий Зотов (2004-07-30 17:41:00) [1]Если Owner копии тот же, что и у оригинала, то, конечно, будет орать - при считывании свойства Name вызывается SetName, а оттуда - ValidateRename.
Отсюда и набор возможных решений:
1. Считывать копию из потока без ее предварительного создания.
2. Создавать копию с другим Owner'ом или вообще без него.
3. Заместить в компоненте SetName.
4. Заместить в компоненте ValidateRename.
и т.д.
Afonya (2004-07-30 17:38:00) [2]
function BSV_ScrollBox.DuplicateBlanks(Blank: BSV_Blank): BSV_Blank;
var
Stream : TMemoryStream;
Reader : TUniqueReader;
NewBlank: TComponent;
begin
Result := nil;
try
Stream := TMemoryStream.Create;
Stream.WriteComponent(Blank);
Stream.Seek(0, soFromBeginning);
NewBlank.Parent := Blank.Parent;
Stream.ReadComponent(NewBlank);
Result := NewBlank;}
while Stream.Position < Stream.Size-1 do
begin
Reader := TUniqueReader.Create(Stream,4096);
with Reader do
try
OnSetName := Reader.SetNameUnique;
NewBlank := BSV_Blank.Create(Self);
// -- ВОТ ТУТ ТО И ОШИБОЧКА ПРОИСХОДИТ --
NewBlank := ReadRootComponent(Blank);
// ---------------------------------------
finally
Reader.Free;
end;
end;
Result := BSV_Blank(NewBlank);
finally
Stream.Free;
end;
end;
procedure TUniqueReader.SetNameUnique( Reader: TReader;
Component: TComponent; // Считываемый компонент
var Name: string // Имя компонента для дальнейшей модификации
);
begin
Name := GetNextName(Component)
end;
function GetNextName (MyComponent : TComponent): string;
var
I : Integer;
TempName : string;
begin
I := 0;
TempName := '';
if assigned(MyComponent) then
repeat
inc(I,1);
TempName := Format('%s%d', [MyComponent.ClassName, I]);
until MyComponent.Owner.FindComponent(TempName) = nil;
Result := TempName;
end;
Digitman (2004-07-30 17:25:00) [3]
> Afonya
код где ?
Afonya (2004-07-30 17:17:00) [4]В том то и дело, что перед тем как заганять компонент в поток - я его регистрирую... И регистрация проходит на ура!
В чем еще может быть дело ума не приложу.
Видать жара влияет... :-)
Digitman (2004-07-30 17:15:00) [5]
> система крычыть, что компонент с таким именем уже существует
не ври
если система и кричит, то жалуется не на "несуществование компонента", а на отсутствие в RTTI сведений о классе