[SOLVED] Can't access component property lazarus / 21-General ---------------------------------------------------------------------- pcurtis · 2021-05-13 07:00 I am trying to design a component. When I try to set a property at runtime it fails with "unit1.pas(40,26) Error: Argument cannot be assigned to". What's wrong? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit mythreaddisplay; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, LResources, Forms, Controls, Graphics, StdCtrls, ExtCtrls, ComCtrls, Dialogs, Buttons, Windows;type  TThreadInfo = record    Position : Integer;    Caption : String;  end;   TMyThreadDisplay = class(TCustomControl)  private    flblLabel : array[0..4] of TLabel;  fprbProgressbar : array[0..4] of TProgressBar;    fThreadInfo : array[0..4] of TThreadInfo;    function GetThreadInfo(Index: Integer): TThreadInfo;    procedure SetThreadInfo(Index: Integer; AValue: TThreadInfo);  protected   public    constructor Create(AOwner : TComponent); override;    property ThreadInfo[Index: Integer]: TThreadInfo read GetThreadInfo write SetThreadInfo;  published    property Align;  end; procedure Register; implementation function TMyThreadDisplay.GetThreadInfo(Index: Integer): TThreadInfo;begin  Result := fThreadInfo[Index];end; procedure TMyThreadDisplay.SetThreadInfo(Index: Integer; AValue: TThreadInfo);begin  if fThreadInfo[Index].Caption <> AValue.Caption then    begin      fThreadInfo[Index].Caption := AValue.Caption;      flblLabel[Index].Caption := AValue.Caption;    end;   if fThreadInfo[Index].Position <> AValue.Position then    begin      fThreadInfo[Index].Position := AValue.Position;      fprbProgressbar[Index].Position := AValue.Position;    end;end; constructor TMyThreadDisplay.Create(AOwner : TComponent);var  iTEMP : Integer;begin  inherited Create(AOwner);   for iTEMP := 4 downto 0 do    begin      fprbProgressbar[iTEMP] := TProgressBar.Create(Self);       with fprbProgressbar[iTEMP] do      begin          fThreadInfo[iTEMP].Position := 0;          Align := alTop;          Parent := Self;          Position := fThreadInfo[iTEMP].Position;        end;       flblLabel[iTEMP] := TLabel.Create(Self);        with flblLabel[iTEMP] do          begin          fThreadInfo[iTEMP].Caption := 'Thread ' + iTEMP.ToString;          Caption := fThreadInfo[iTEMP].Caption;            Align := alTop;            Parent := Self;            ParentFont := True;        end;      end;   Constraints.MinHeight := 205;  Constraints.MinWidth := 100;  SetBounds(0, 0, 100, 205);end; procedure Register;begin  RegisterComponents('Misc', [TMyThreadDisplay]);end; end.  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, StdCtrls,  mythreaddisplay; type   { TForm1 }   TForm1 = class(TForm)    procedure FormCreate(Sender: TObject);  private   public   end; var  Form1: TForm1;  MyDisplay : TMyThreadDisplay; implementation {$R *.lfm} { TForm1 } procedure TForm1.FormCreate(Sender: TObject);begin  MyDisplay := TMyThreadDisplay.Create(self);  MyDisplay.Left := 8;  MyDisplay.Top := 8;  MyDisplay.Parent := Form1;   MyDisplay.ThreadInfo[1].Caption := 'something';  // fails hereend; end. ---------------------------------------------------------------------- PascalDragon · 2021-05-13 09:07 If you have a property that is of a record type you must change it as a whole. This avoids people wondering why their code does not work, because the getter only provides a copy (*). So you need to use this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  info: TThreadInfo;begin  info := MyDisplay.ThreadInfo[1];  info.Caption := 'something';  MyDisplay.ThreadInfo[1] := info;end; Alternatively you can use a class instead of a record for TThreadInfo (you need to instantiate them correctly of course). Or your property needs to a pointer to the TThreadInfo. (*) That is because the compiler would essentially generate code like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  tmp: TThreadInfo;begin  // MyDisplay.ThreadInfo[1].Caption := 'something';  tmp := MyDisplay.ThreadInfo[1];  tmp.Caption := 'something' The tmp record would be a copy, not a reference. ---------------------------------------------------------------------- pcurtis · 2021-05-13 09:42 Thank you.