Indeed the application we here offer has the same graphical interface of previous used in by-value mode: only the engine changes, only management of array's items changes.
To check this is true, download the project code.In next page we show all used code.
[Just an advice: like in by-value code, visual elements don't manage all kind of events; so software can give errors, but only related to events, not to management code]
A good way to learn the different methods is to confront the two codes.
Functions and procedures are called the same in both of ones, so that the job will be easy: you only must get the different behavior.
unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls; //Definition of Employee type (Record) : Here we define TEmployee type of a generic Employee type pEmployee = ^TEmployee; //Define a pointer of TEmployee TEmployee = Record Id : integer; Name : string; Surname : string; end; //End of employee type type { TForm1 } TForm1 = class(TForm) ButtonAdd: TButton; ButtonModify: TButton; ButtonDelete: TButton; ButtonShow: TButton; EditNameNew: TEdit; EditSurnameNew: TEdit; EditIdModify: TEdit; EditNameModify: TEdit; EditSurnameModify: TEdit; EditIdDelete: TEdit; GroupBox1: TGroupBox; GroupBox2: TGroupBox; GroupBox3: TGroupBox; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; LabelNameDelete: TLabel; LabelSurnameDelete: TLabel; Memo: TMemo; procedure ButtonAddClick(Sender: TObject); procedure ButtonDeleteClick(Sender: TObject); procedure ButtonModifyClick(Sender: TObject); procedure ButtonShowClick(Sender: TObject); procedure EditIdDeleteChange(Sender: TObject); procedure EditIdModifyChange(Sender: TObject); private { private declarations } EmployeeArray : Array of pEmployee; //DYNAMIC Array of elements type pEmployees (pEmployee - pointers of employees) Array starts from a[0], a[1] etc ... function findNumberOfEmployees(): integer; function findNextFreeId(): integer; procedure addEmployee(pEmp:pEmployee); procedure modifyEmployee(id:integer; pEmpnew:pEmployee); procedure deleteEmployee(id:integer); function getEmployee(id:integer): pEmployee; //get the pointer of an employee function printEmployeeWithId(id:integer): string; function printEmployeeWithIndex(index:integer): string; public { public declarations } end; var Form1: TForm1; implementation { TForm1 } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ////////////////////////PRIVATE FUNCTIONS//////////////////////////////////// function TForm1.findNumberOfEmployees(): integer; begin result := Length(self.EmployeeArray); end; function TForm1.findNextFreeId(): integer; var imax :integer; begin imax:=self.findNumberOfEmployees-1; //arrays start from a[0] etc... if imax <> -1 then result := self.EmployeeArray[imax]^.Id +1 else result := 1; end; procedure TForm1.addEmployee(pEmp:pEmployee); //I add employees on the end of EmployeeArray ONLY var imax :integer; begin imax:=self.findNumberOfEmployees; SetLength(self.EmployeeArray, imax+1); self.EmployeeArray[imax] := pEmp; //copy by pointer //starts from a[0] end; procedure TForm1.modifyEmployee(id:integer; pEmpnew:pEmployee); var i,imax :integer; begin imax:=self.findNumberOfEmployees-1;//arrays start from a[0] etc... for i:=0 to imax do begin if self.EmployeeArray[i]^.id = id then begin self.EmployeeArray[i]^:=pEmpnew^; //copy by value //starts from a[0] break; end; end; end; procedure TForm1.deleteEmployee(id:integer); var i,k,imax,deletepoint :integer; begin imax:=self.findNumberOfEmployees-1; deletepoint:=0; for i:=0 to imax do begin if self.EmployeeArray[i]^.id = id then begin deletepoint:=i; if deletepoint < imax then begin dispose(self.EmployeeArray[deletepoint]); //FREE the created pointer for k:=deletepoint+1 to imax do begin self.EmployeeArray[k-1]:=self.EmployeeArray[k]; end; self.EmployeeArray[imax]:=nil; SetLength(self.EmployeeArray, imax); end else begin //deletepoint = imax dispose(self.EmployeeArray[imax]); //FREE the created pointer SetLength(self.EmployeeArray, imax); end; break; end; end; end; function TForm1.getEmployee(id:integer): pEmployee; var i,imax :integer; begin result:=nil; imax:=self.findNumberOfEmployees-1; for i:=0 to imax do begin if self.EmployeeArray[i]^.id = id then begin result:= self.EmployeeArray[i]; break; end; end; end; function TForm1.printEmployeeWithId(id:integer): string; var i,imax :integer; begin imax:=self.findNumberOfEmployees-1; for i:=0 to imax do begin if self.EmployeeArray[i]^.id = id then begin result:= 'Id : ' + inttostr((self.EmployeeArray[i]^).Id) + '; Name : ' + self.EmployeeArray[i]^.Name + '; Surname : ' + self.EmployeeArray[i]^.Surname; break; end; end; end; function TForm1.printEmployeeWithIndex(index:integer): string; begin result:= 'Id : ' + inttostr((self.EmployeeArray[index]^).Id) + '; Name : ' + self.EmployeeArray[index]^.Name + '; Surname : ' + self.EmployeeArray[index]^.Surname; end; ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ///////////////////////////EVENTS///////////////////////////////////////////// //add employee event procedure TForm1.ButtonAddClick(Sender: TObject); var pEmpTemp:pEmployee; begin //create a new temp employee new(pEmpTemp); pEmpTemp^.Id := self.findNextFreeId; pEmpTemp^.Name := EditNameNew.Text; pEmpTemp^.Surname := EditSurnameNew.Text; self.addEmployee(pEmpTemp); showmessage('Employee with this info : ' + self.printEmployeeWithId(pEmpTemp^.Id) + ' added into array.'); end; //modify employe event procedure TForm1.ButtonModifyClick(Sender: TObject); var tempEmployee:TEmployee; begin tempEmployee.Id := strtoint(EditIdModify.Text); tempEmployee.Name := EditNameModify.Text; tempEmployee.Surname := EditSurnameModify.Text; self.modifyEmployee(tempEmployee.Id,@tempEmployee); showmessage('Employee with this info : ' + self.printEmployeeWithId(tempEmployee.Id) + ' modifided.'); ButtonModify.Enabled := false; end; //delete employee event procedure TForm1.ButtonDeleteClick(Sender: TObject); begin self.deleteEmployee(strtoint(EditIdDelete.Text)) ; showmessage('Employee deleted'); ButtonDelete.Enabled := false; end; //Show all employees event procedure TForm1.ButtonShowClick(Sender: TObject); var i,imax:integer; begin memo.Clear; imax:=self.findNumberOfEmployees-1; for i:=0 to imax do begin Memo.Lines.Add(self.printEmployeeWithIndex(i)); end; end; //on modify change procedure TForm1.EditIdModifyChange(Sender: TObject); var pTempEmployee : pEmployee; begin pTempEmployee := getEmployee(strtoint(EditIdModify.Text)); if pTempEmployee <> nil then begin EditNameModify.text := pTempEmployee^.Name; EditSurnameModify.text := pTempEmployee^.Surname; ButtonModify.Enabled := true; end else begin EditNameModify.text := 'N/A'; EditSurnameModify.text := 'N/A'; ButtonModify.Enabled := false; end; pTempEmployee:=nil; end; //on delete change procedure TForm1.EditIdDeleteChange(Sender: TObject); var pTempEmployee : pEmployee; begin pTempEmployee := getEmployee(strtoint(EditIdDelete.Text)); if pTempEmployee <> nil then begin LabelNameDelete.Caption := pTempEmployee^.Name; LabelSurnameDelete.Caption := pTempEmployee^.Surname; ButtonDelete.Enabled := true; end else begin LabelNameDelete.Caption := 'N/A'; LabelSurnameDelete.Caption := 'N/A'; ButtonDelete.Enabled := false; end; pTempEmployee:=nil; end; initialization {$I unit1.lrs} end.
That's all for now.
See you on next article!