Well... we are on the final rush, so the project's code follows:
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 poiner 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); procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure FormCreate(Sender: TObject); private { private declarations } EmployeeList : TList; //list of pointers of employees (list of pEmployee) 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 := EmployeeList.Count; end; function TForm1.findNextFreeId(): integer; var imax :integer; pEmpTemp:pEmployee; begin imax:=self.findNumberOfEmployees-1; //TList starts from a[0] etc... if imax <> -1 then begin pEmpTemp := self.EmployeeList[imax]; //Casting : pEmployee = generic pointer of a TList result :=pEmpTemp^.Id +1; end else result := 1; end; procedure TForm1.addEmployee(pEmp:pEmployee); begin self.EmployeeList.Add(pEmp); end; procedure TForm1.modifyEmployee(id:integer; pEmpnew:pEmployee); var i,imax :integer; pEmpTemp:pEmployee; begin imax:=self.findNumberOfEmployees-1;//TList starts from a[0] etc... for i:=0 to imax do begin pEmpTemp := self.EmployeeList[i]; //Casting : pEmployee = generic pointer of a TList if pEmpTemp^.id = id then begin pEmpTemp^:=pEmpnew^; //copy by value !! break; end; end; end; procedure TForm1.deleteEmployee(id:integer); var i,imax :integer; pEmpTemp:pEmployee; begin imax:=self.findNumberOfEmployees-1; for i:=0 to imax do begin pEmpTemp:= self.EmployeeList[i]; //CASTING if pEmpTemp^.id = id then begin //if pEmployee(self.EmployeeList[i])^.id = id then .... dispose(pEmpTemp); //FREE the created pointer which was related to list's item i self.EmployeeList.Delete(i); //delete the list's item i break; end; end; end; function TForm1.getEmployee(id:integer): pEmployee; var i,imax :integer; pEmpTemp:pEmployee; begin result:=nil; imax:=self.findNumberOfEmployees-1; for i:=0 to imax do begin pEmpTemp:=self.EmployeeList[i]; if pEmpTemp^.id = id then begin result:= pEmpTemp; break; end; end; end; function TForm1.printEmployeeWithId(id:integer): string; var i,imax :integer; pEmpTemp:pEmployee; begin imax:=self.findNumberOfEmployees-1; for i:=0 to imax do begin pEmpTemp:=self.EmployeeList[i]; //Casting : pEmployee = generic pointer of a TList if pEmpTemp^.id = id then begin result:= 'Id : ' + inttostr(pEmpTemp^.Id) + '; Name : ' + pEmpTemp^.Name + '; Surname : ' + pEmpTemp^.Surname; break; end; end; end; function TForm1.printEmployeeWithIndex(index:integer): string; var pEmpTemp:pEmployee; begin pEmpTemp:=self.EmployeeList[index]; //Casting : pEmployee = generic pointer of a TList result:= 'Id : ' + inttostr(pEmpTemp^.Id) + '; Name : ' + pEmpTemp^.Name + '; Surname : ' + pEmpTemp^.Surname; end; ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ///////////////////////////EVENTS///////////////////////////////////////////// //add employee event procedure TForm1.ButtonAddClick(Sender: TObject); var pEmpTemp : pEmployee; begin //new : Create a new pointer type variable new(pEmpTemp); //SOS TRY DISABLING THIS STRING AND SEE WHAT HAPPENS ! (pEmpTemp^.Id := .. cannot be assigned i need to create the object) 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 TList.'); //dispose(pEmpTemp); //FREE the created pointer What happens if i enable this string here? when i call ButtonShowClick the TList has no values!!! end; //modify employe event procedure TForm1.ButtonModifyClick(Sender: TObject); var pEmpTemp: pEmployee; begin //i do not create anything the pointer is created at the ADD section and i get it via getEmployee pEmpTemp:=self.getEmployee(strtoint(EditIdModify.Text)); pEmpTemp^.Id := strtoint(EditIdModify.Text); pEmpTemp^.Name := EditNameModify.Text; pEmpTemp^.Surname := EditSurnameModify.Text; self.modifyEmployee(pEmpTemp^.Id,pEmpTemp); showmessage('Employee with this info : ' + self.printEmployeeWithId(pEmpTemp^.id) + ' modifided.'); end; //delete employee event procedure TForm1.ButtonDeleteClick(Sender: TObject); begin self.deleteEmployee(strtoint(EditIdDelete.Text)) ; showmessage('Employee deleted'); 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; //On create form procedure TForm1.FormCreate(Sender: TObject); begin EmployeeList := TList.Create; //Create the list !!! end; //On Exit form procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction); var i,imax:integer; begin imax:=self.findNumberOfEmployees-1; //for i:=imax downto 0 do begin for i:=0 to imax do begin dispose( pEmployee(EmployeeList[i]) ); //delete both TEmployee record and pointer EmployeeList.Delete(i); // delete list's item at index i end; EmployeeList.Free; //Destroy the list !!! end; initialization {$I unit1.lrs} end.
Have fun!
See you on next article!