Недавно добавленные исходники

•  DeLiKaTeS Tetris (Тетрис)  124

•  TDictionary Custom Sort  3 311

•  Fast Watermark Sources  3 060

•  3D Designer  4 815

•  Sik Screen Capture  3 313

•  Patch Maker  3 527

•  Айболит (remote control)  3 628

•  ListBox Drag & Drop  2 990

•  Доска для игры Реверси  81 529

•  Графические эффекты  3 919

•  Рисование по маске  3 226

•  Перетаскивание изображений  2 607

•  Canvas Drawing  2 731

•  Рисование Луны  2 555

•  Поворот изображения  2 162

•  Рисование стержней  2 160

•  Paint on Shape  1 564

•  Генератор кроссвордов  2 223

•  Головоломка Paletto  1 764

•  Теорема Монжа об окружностях  2 209

•  Пазл Numbrix  1 682

•  Заборы и коммивояжеры  2 052

•  Игра HIP  1 278

•  Игра Go (Го)  1 224

•  Симулятор лифта  1 470

•  Программа укладки плитки  1 214

•  Генератор лабиринта  1 542

•  Проверка числового ввода  1 350

•  HEX View  1 488

•  Физический маятник  1 355

 
скрыть


Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Delphi Sources

Дублирование компонентов и их потомков во время выполнения приложения



Учитывая пожелания пользователей, фирма Microsoft объявила, что она внесёт изменение в название Windows 2000, теперь эта операционная система будет называться Windows 2000 beta ДВАДЦАТЬ ПЯТЬ. P.S. (А чё? Ведь существует-же W2000 beta 3 RELEASE CANDIDATE 1)

Приведенный ниже код содержит функцию DuplicateComponents, позволяющую проводить клонирование любых компонентов и их потомков во время выполнения приложения. Действия ее напоминают операцию копирования/вставки (copy/paste) во время разработки приложения. Новые компоненты при создании получают тех же родителей, владельцев (в случае применения контейнеров) и имена (естественно, несколько отличающихся), что и оригиналы. В данной функции есть вероятность багов, но я пока их не обнаружил. Ошибки и недочеты могут возникнуть из-за редко применяемых специфических методов, которые, вместе с тем, могут помочь программистам, столкнувшимися с аналогичными проблемами.

Данная функция может оказаться весьма полезной в случае наличия нескольких одинаковых областей на форме с необходимостью синхронизации изменений в течение некоторого промежутка времени. Процедура создания дубликата проста до безобразия: разместите на TPanel или на другом родительском компоненте необходимые элементы управления и сделайте: "newpanel := DuplicateComponents(designedpanel)".


uses
  SysUtils, Windows, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, ExtCtrls, StdCtrls, IniFiles, TypInfo, Debug;

type
  TUniqueReader = class(TReader)
    LastRead: TComponent;
    procedure ComponentRead(Component: TComponent);
    procedure SetNameUnique(
      Reader: TReader;
      Component: TComponent;
      var Name: string
      );
  end;

implementation

procedure TUniqueReader.ComponentRead(Component: TComponent);
begin
  LastRead := Component;
end;

// Задаем уникальное имя считываемому компоненту, например,
// "Panel2", если "Panel1" уже существует

procedure TUniqueReader.SetNameUnique(
  Reader: TReader;
  Component: TComponent; // Считываемый компонент
  var Name: string // Имя компонента для дальнейшей модификации
  );
var
  i: Integer;
  tempname: string;
begin
  i := 0;
  tempname := Name;
  while Component.Owner.FindComponent(Name) <> nil do
  begin
    Inc(i);
    Name := Format('%s%d', [tempname, i]);
  end;
end;

function DuplicateComponents(
  AComponent: TComponent // исходный компонент
  ): TComponent; // возвращаемся к созданию нового компонента

  procedure RegisterComponentClasses(
    AComponent: TComponent
    );
  var
    i: integer;
  begin
    RegisterClass(TPersistentClass(AComponent.ClassType));
    if AComponent is TWinControl then
      if TWinControl(AComponent).ControlCount > 0 then
        for i := 0 to
          (TWinControl(AComponent).ControlCount - 1) do

          RegisterComponentClasses(TWinControl(AComponent).Controls[i]);
  end;

var
  Stream: TMemoryStream;
  UniqueReader: TUniqueReader;
  Writer: TWriter;
begin
  result := nil;
  UniqueReader := nil;
  Writer := nil;

  try
    Stream := TMemoryStream.Create;
    RegisterComponentClasses(AComponent);

    try
      Writer := TWriter.Create(Stream, 4096);
      Writer.Root := AComponent.Owner;
      Writer.WriteSignature;
      Writer.WriteComponent(AComponent);
      Writer.WriteListEnd;
    finally
      Writer.Free;
    end;

    Stream.Position := 0;
    try
      // создаем поток, перемещающий данные о компоненте в конструктор
      UniqueReader := TUniqueReader.Create(Stream, 4096);
      UniqueReader.OnSetName := UniqueReader.SetNameUnique;
      UniqueReader.LastRead := nil;

      if AComponent is TWinControl then

        UniqueReader.ReadComponents(
          // считываем компоненты и суб-компоненты

          TWinControl(AComponent).Owner,
          TWinControl(AComponent).Parent,
          UniqueReader.ComponentRead
          )
      else

        UniqueReader.ReadComponents(
          // читаем компоненты

          AComponent.Owner,
          nil,
          UniqueReader.ComponentRead
          );
      result := UniqueReader.LastRead;
    finally
      UniqueReader.Free;
    end;
  finally
    Stream.Free;
  end;
end;





Похожие по теме исходники

Очередность выполнения процессов




Copyright © 2004-2024 "Delphi Sources" by BrokenByte Software. Delphi World FAQ

Группа ВКонтакте