Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.10.02;
Скачать: [xml.tar.bz2];

Вниз

копирование объектов 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.005 c
1-1125996767
oradb
2005-09-06 12:52
2005.10.02
HotKey для TToolButton


1-1126078099
Alpine
2005-09-07 11:28
2005.10.02
Как лучше округлять денежные значения ?


1-1126532796
Charly22
2005-09-12 17:46
2005.10.02
Вид диалога открытия файлов


3-1124241947
Strech
2005-08-17 05:25
2005.10.02
BLOB поля в dbf через ADO


1-1126246823
whiledo
2005-09-09 10:20
2005.10.02
Работаем с Image





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