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

Вниз

копирование объектов runtime   Найти похожие ветки 

 
July   (2005-09-06 17:17) [0]

Подскажите, пожалуйста, можно ли программным способам быстро создать копию объекта-контейнера (например, Groupbox или, как в моем случае - rascrollboxband) вместе со всеми размещенными на нем объектами - кнопочками, идитами и т.д.
Знаю только один способ - ручками создавать новый экземпляр класса этого контейнера, потом каждый из объектов, которые нужно на нем разместить, но тогда уж лучше пойти вообще другим путем - слишком много возни.
Может быть есть в какой-нибудь библиотеке метод типа "создать объект класса такого-то точно такой же как объект такой-то со всеми его детишками"?
(Причем нужна именно еще одна копия объекта, а не новый указатель на тот же самый объект)
Подскажите, плиз, срочно нужно решение принимать, заморачиваться с этим или нет?


 
DesWind ©   (2005-09-06 17:25) [1]

TFrame?


 
Digitman ©   (2005-09-06 17:26) [2]

универсального решения нет


 
Бурундук ©   (2005-09-06 17:35) [3]

Нашёл в своих закромах:

procedure TForm1.BCopyClick(Sender: TObject);
var TxtStream: TStream;
   Clone: TComponent;
begin
 TxtStream := TMemoryStream.Create;
 try
   Save(Panel1, Self, TxtStream);
   Clone := CreateComp(Self, Self, Self, TxtStream);
 finally
   TxtStream.Free;
 end;
end;

{------------------------------------------------------------------------------}

function TForm1.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 := {Self.}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 TForm1.ReaderSetName(Reader: TReader; Component: TComponent;
 var Name: string);
begin
 if (Reader.Owner <> nil) and (Reader.Owner.FindComponent(Name) <> nil) then
   Name := "";
 // Это самое простое, что можно придумать, чтобы избежать конфликта имён.
 // Всё равно в рантайме имена не слишком важны
end;

procedure TForm1.Save(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;

{------------------------------------------------------------------------------}


 
July   (2005-09-07 12:27) [4]

to DesWind:
>TFrame?

Не поняла? Это может помочь? Или это вопрос?
Просто с этим классом никогда не работала, не доходит сразу, о чем речь.

to Бурундук:

Спасибо, сохраню подсказку, может пригодится еще когда.
А сейчас я наверное дольше пропыхчу, пока пойму, что там к чему.
Не люблю списывать то, в чем до конца не разбираюсь ;)
В настоящий момент оптимальнее видимо будет вообще каким-нибудь другим спосом мою задачу решить.
Ну очень хотелось прокрасивше сделать.. :)

Всем спасибо!


 
DesWind ©   (2005-09-07 12:33) [5]

Он как раз и есть контейнер для компонентов. Т.е. выглядит приблизительно как форма, шлепаешь на него нужные компоненты. В процесе работы программы создаешь его экземпляр и размещаешь на форме в нужном месте.


 
ShiFT   (2005-09-07 12:39) [6]

Про TFrame
http://delphimaster.ru/articles/frames/index.html


 
Бурундук ©   (2005-09-07 14:31) [7]

2July   (07.09.05 12:27) [4]

Там всё просто.
Основной код заключён в первой функции:  

procedure TForm1.BCopyClick(Sender: TObject);
var TxtStream: TStream;
  Clone: TComponent;
begin
TxtStream := TMemoryStream.Create;
try
  // компонент Panel1 записывается в поток
  Save(Panel1,   // сам компонент
       Self,     // Root-компонент - обычно форма
       TxtStream // поток
  );

  // читается из потока новый компонент,
  // копия старого, и записывется в Clone.
  Clone := CreateComp(
       Self, // Root-компонент нового компонента (форма)
       Self, // Владелец (Owner) нового компонента
       Self, // Parent нового компонента
       TxtStream // поток, в который был записан исходный компонент
  );

finally
  TxtStream.Free;
end;
end;


 
July   (2005-09-07 17:24) [8]

Про фреймы посмотрела бегло, но кажется это хорошо для разных видоизменений формы, а мне надо несколько (возможно много) экземпляров некоего набора контролов на одной форме нашлепать.
Вот с потоками, скорее всего подошло бы, но меня отпугивает то, что нужно не просто нарисовать несколько штук контейнеров на форме, а еще и потом обращаться к ним, обрабатывать их содержимое и т.д. Я тугодум :) Боюсь много времени потрачу на разбирательства, а сроки проект сдавать уже не загорами ;)

Еще раз благодрарствую :)


 
DesWind ©   (2005-09-07 18:08) [9]

А что мешает объеденить их в массив? Что-то вроде:


var
FrameArr [0..n] of TMyFrame;
FrameResult: TFrameRasult;

begin
for c:=0 to n-1 do
 begin
  FrameArr[c]:=TMyFrame.Create(fmMain);
  FrameArr[c].MyButton.Caption:="Btn "+IntToStr(c);
  FrameResult:= FrameArr[c].GetFrameResult;
 end;
end;


Что-то вроде этого. Думаю основная мысль ясна.


 
AlexWlad ©   (2005-09-07 19:57) [10]

А может лучше хранить/загружать данные в/из одного набора контролов в/из массив(а) структур вместо кучи контролов? Мое ИМХО - форма, перегруженная контролами, выглядит не-очень...


 
DesWind ©   (2005-09-08 01:46) [11]

July   (07.09.05 17:24) [8]

Если очень много, то надо обобщить... Иначе вопрос не имеет смысла

Лучше день потерять, зато потом, за пять минут долетеь (с)


 
Defunct ©   (2005-09-08 02:56) [12]

> July   (07.09.05 17:24) [8]
> но кажется это хорошо для разных видоизменений формы, а мне надо несколько (возможно много) экземпляров некоего набора контролов на одной форме нашлепать.


Мне кажется, что ты малость не совсем поняла технологию фреймов. Как раз для твоей задачи они, возможно, подходят лучше всего.



Страницы: 1 вся ветка

Текущий архив: 2005.10.02;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.048 c
4-1123140791
Kot Andrei
2005-08-04 11:33
2005.10.02
Удержание клавиши на мыше - отловить


6-1118043688
Лёха2005_
2005-06-06 11:41
2005.10.02
Определение IP


3-1123148835
alex_1_2_3_4
2005-08-04 13:47
2005.10.02
MySQL, ADO, error :-(


4-1123248812
slaga
2005-08-05 17:33
2005.10.02
Как узнать заблокирован ли компьютер


14-1126530193
Ihor Osov'yak
2005-09-12 17:03
2005.10.02
Немного удивлен...