Создание компонента с именованными подкомпонентами?

Мне нужно знать основы создания компонентов и управления ими. Первоначально я попробовал это, создав TCollection , и попытался присвоить имя каждому TCollectionItem . Но я понял, что это не так просто, как я надеялся.

Итак, теперь я снова собираюсь начать этот проект с нуля, и на этот раз мне хотелось бы все исправить. Эти субкомпоненты не являются визуальными компонентами и не должны иметь никакого дисплея или окна, просто на основе TComponent . Основной компонент, содержащий эти подкомпоненты, также будет основан на TComponent .Итак, здесь нет ничего визуального, и мне не нужен маленький значок в моей форме (во время разработки) для каждого из этих подкомпонентов.

Я хотел бы иметь возможность поддерживать и управлять этими субкомпонентами в виде коллекции. Важно то, что эти субкомпоненты должны быть созданы, названы и добавлены в источник формы, как, например, пункты меню. Во-первых, в этом весь смысл идеи, если они не могут быть названы, тогда вся эта идея капут.

О, еще одна важная вещь: главный компонент, являющийся родительским для всех подкомпонентов, должен иметь возможность сохранять эти подкомпоненты в файл DFM.

ПРИМЕР:

Вместо доступа к одному из этих подпунктов, например:

MyForm.MyItems[1].DoSomething();

, я бы хотел сделать что-то вроде:

MyForm.MyItem2.DoSomething();

Поэтому мне не нужно полагаться на знание идентификатора каждого подпункта.

РЕДАКТИРОВАТЬ:

Я посчитал необходимым включить мой исходный код, чтобы можно было увидеть, как работает исходная коллекция. Вот только коллекция на стороне сервера и элемент сбора, удаленный из полного блока:

//  Command Collections
//  Goal: Allow entering pre-set commands with unique Name and ID
//  Each command has its own event which is triggered when command is received
//  TODO: Name each collection item as a named component in owner form

  //Determines how commands are displayed in collection editor in design-time
  TJDCmdDisplay = (cdName, cdID, cdCaption, cdIDName, cdIDCaption);

  TJDScktSvrCmdEvent = procedure(Sender: TObject; Socket: TJDServerClientSocket;
    const Data: TStrings) of object;

  TSvrCommands = class(TCollection)
  private
    fOwner: TPersistent;
    fOnUnknownCommand: TJDScktSvrCmdEvent;
    fDisplay: TJDCmdDisplay;
    function GetItem(Index: Integer): TSvrCommand;
    procedure SetItem(Index: Integer; Value: TSvrCommand);
    procedure SetDisplay(const Value: TJDCmdDisplay);
  protected
    function GetOwner: TPersistent; override;
  public
    constructor Create(AOwner: TPersistent);
    destructor Destroy;
    procedure DoCommand(const Socket: TJDServerClientSocket;
      const Cmd: Integer; const Data: TStrings);
    function Add: TSvrCommand;
    property Items[Index: Integer]: TSvrCommand read GetItem write SetItem;
  published
    property Display: TJDCmdDisplay read fDisplay write SetDisplay;
    property OnUnknownCommand: TJDScktSvrCmdEvent
      read fOnUnknownCommand write fOnUnknownCommand;
  end;

  TSvrCommand = class(TCollectionItem)
  private
    fID: Integer;
    fOnCommand: TJDScktSvrCmdEvent;
    fName: String;
    fParamCount: Integer;
    fCollection: TSvrCommands;
    fCaption: String;
    procedure SetID(Value: Integer);
    procedure SetName(Value: String);
    procedure SetCaption(const Value: String);
  protected
    function GetDisplayName: String; override;
  public
    procedure Assign(Source: TPersistent); override;
    constructor Create(Collection: TCollection); override;
    destructor Destroy; override;
  published
    property ID: Integer read fID write SetID;
    property Name: String read fName write SetName;
    property Caption: String read fCaption write SetCaption;
    property ParamCount: Integer read fParamCount write fParamCount;
    property OnCommand: TJDScktSvrCmdEvent read fOnCommand write fOnCommand;
  end;

////////////////////////////////////////////////////////////////////////////////
implementation
////////////////////////////////////////////////////////////////////////////////

{ TSvrCommands }

function TSvrCommands.Add: TSvrCommand;
begin
  Result:= inherited Add as TSvrCommand;
end;

constructor TSvrCommands.Create(AOwner: TPersistent);
begin
  inherited Create(TSvrCommand);
  Self.fOwner:= AOwner;
end;

destructor TSvrCommands.Destroy;
begin
  inherited Destroy;
end;

procedure TSvrCommands.DoCommand(const Socket: TJDServerClientSocket;
  const Cmd: Integer; const Data: TStrings);
var
  X: Integer;
  C: TSvrCommand;
  F: Bool;
begin
  F:= False;
  for X:= 0 to Self.Count - 1 do begin
    C:= GetItem(X);
    if C.ID = Cmd then begin
      F:= True;
      try
        if assigned(C.fOnCommand) then
          C.fOnCommand(Self, Socket, Data);
      except
        on e: exception do begin
          raise Exception.Create(
            'Failed to execute command '+IntToStr(Cmd)+': '+#10+e.Message);
        end;
      end;
      Break;
    end;
  end;
  if not F then begin
    //Command not found

  end;
end;

function TSvrCommands.GetItem(Index: Integer): TSvrCommand;
begin
  Result:= TSvrCommand(inherited GetItem(Index));
end;

function TSvrCommands.GetOwner: TPersistent;
begin
  Result:= fOwner;
end;

procedure TSvrCommands.SetDisplay(const Value: TJDCmdDisplay);
begin
  fDisplay := Value;
end;

procedure TSvrCommands.SetItem(Index: Integer; Value: TSvrCommand);
begin
  inherited SetItem(Index, Value);
end;

{ TSvrCommand }

procedure TSvrCommand.Assign(Source: TPersistent);
begin
  inherited;

end;

constructor TSvrCommand.Create(Collection: TCollection);
begin
  inherited Create(Collection);
  fCollection:= TSvrCommands(Collection);
end;

destructor TSvrCommand.Destroy;
begin
  inherited Destroy;
end;

function TSvrCommand.GetDisplayName: String;
begin        
  case Self.fCollection.fDisplay of
    cdName: begin
      Result:= fName;
    end;
    cdID: begin
      Result:= '['+IntToStr(fID)+']';
    end;
    cdCaption: begin
      Result:= fCaption;
    end;
    cdIDName: begin
      Result:= '['+IntToStr(fID)+'] '+fName;
    end;
    cdIDCaption: begin
      Result:= '['+IntToStr(fID)+'] '+fCaption;
    end;
  end;
end;

procedure TSvrCommand.SetCaption(const Value: String);
begin
  fCaption := Value;
end;

procedure TSvrCommand.SetID(Value: Integer);
begin
  fID:= Value;
end;

procedure TSvrCommand.SetName(Value: String);
begin
  fName:= Value;
end;
5
задан menjaraz 14 January 2012 в 04:16
поделиться