Конференция "Компоненты" » Свойство компонента в виде поля класса [D7, WinXP]
 
  • summerfrog © (18.03.10 15:34) [0]
    Суть проблемы в следующем. Нужно опубликовать в компоненте свойство типа класс. При установке компонента на форму выдает ошибку: Access violation at address 40006E9C in module 'rtl70.bpl'. Write of address 00000004 Если кто знает, скажите, пожалуйста, что я делаю не так?
    Вот модуль компонента:

    unit SomeComponent;

    interface

    uses
     Controls, Classes, Graphics;

    type
     TSomeClass = class(TPersistent)
     private
       FSomeString: String;
       FSomeInteger: Integer;
     public
       constructor Create;
       procedure Assign(Source: TPersistent); override;
     published
       property SomeString: String read FSomeString write FSomeString;
       property SomeInteger: Integer read FSomeInteger write FSomeInteger;
     end;

    type
     TSomeComponent = class(TComponent)
     private
       FFont: TFont;
       FSomeClass: TSomeClass;
       procedure SetFont(const AFont: TFont);
       procedure SetSomeClass(const ASomeClass: TSomeClass);
     public
       constructor Create(AOwner: TComponent); override;
       destructor Destroy; override;
     published
       property Font: TFont read FFont write SetFont;
       property SomeClass: TSomeClass read FSomeClass write SetSomeClass;
     end;

    procedure Register;

    implementation

    procedure Register;
    begin
     RegisterComponents('My components', [TSomeComponent]);
    end;

    { TSomeClass }

    procedure TSomeClass.Assign(Source: TPersistent);
    begin
     if Source is TSomeClass then
       begin
         FSomeString:=TSomeClass(Source).FSomeString;
         FSomeInteger:=TSomeClass(Source).FSomeInteger;
       end;
    end;

    constructor TSomeClass.Create;
    begin
     FSomeString:='SomeString';
     FSomeInteger:=0;
    end;

    { TSomeComponent }

    constructor TSomeComponent.Create(AOwner: TComponent);
    begin
     inherited Create(AOwner);
     FSomeClass.Create;
     FFont:=TFont.Create;
    end;

    destructor TSomeComponent.Destroy;
    begin
     FSomeClass.Free;
     FFont.Free;
     inherited;
    end;

    procedure TSomeComponent.SetFont(const AFont: TFont);
    begin
     FFont.Assign(AFont);
    end;

    procedure TSomeComponent.SetSomeClass(const ASomeClass: TSomeClass);
    begin
      FSomeClass.Assign(ASomeClass);
    end;

    end.

  • summerfrog © (18.03.10 18:20) [1]
    Проблему решил. Напартачил с конструктором. Надо было так:
    constructor TSomeComponent.Create(AOwner: TComponent);
    begin
     inherited Create(AOwner);
     FSomeClass:=TSomeClass.Create;
     FFont:=TFont.Create;
    end;

  • dik (18.04.10 21:16) [2]
    Кроме того, советую override делать не для Assign
    а для AssignTo, иначе чужие глюки будут труднее отлавливаться у пользователей компонента.
  • DimaBr © (19.04.10 12:46) [3]

    > dik  
    > Кроме того, советую override делать не для Assignа для AssignTo

    Вы немного путаете предназначение  методов. Метод AssignTo предназначен научить сторонний класс копировать в себя данные из вашего класса.
    Например научим TCustonAction работать с TControl
    procedure TControl.AssignTo(Dest: TPersistent);
    begin
     if Dest is TCustomAction then
       with TCustomAction(Dest) do
       begin
         Enabled := Self.Enabled;
         Hint := Self.Hint;
         Caption := Self.Caption;
         Visible := Self.Visible;
         OnExecute := Self.OnClick;
       end
     else inherited AssignTo(Dest);
    end;

 
Конференция "Компоненты" » Свойство компонента в виде поля класса [D7, WinXP]
Есть новые Нет новых   [120280   +49][b:0][p:0.001]