Also, as far as I understand it then I'll have to move functionality out of the constructor. Is there a way to change the event handlers inside the constructor?
Unfortunately that does not seem to be the only thing that is a bit awkward in your code.
Please do not take offense but i show some fundamental basics using simple approach. Your head seems a bit clouded by all that you've read
First, you need to instantiate your class and free it after use:
program test1;
{$MODE OBJFPC}{$H+}
Type
TAppData = class
end;
var
AppData: TAppData;
begin
// Create a new instance of your TAppData class and keep it for safe-keeping in variable AppData
AppData := TAppData.Create;
// do stuff, also with AppData
// Free the instantiated TAppdata class
AppData.Free;
end.
Now, let's add a vendorname variable and show it:
program test2;
{$MODE OBJFPC}{$H+}
Type
TAppData = class
public
VendorName : String;
end;
var
AppData: TAppData;
begin
// Create a new instance of your TAppData class and keep it for safe-keeping in variable AppData
AppData := TAppData.Create;
// do stuff, also with AppData
AppData.VendorName := 'Hello world';
WriteLn('The name of the vendor is ', AppData.VendorName);
// Free the instantiated TAppdata class
AppData.Free;
end.
But, we do not like the above. We want to have the vendorname initialized with construction:
program test3;
{$MODE OBJFPC}{$H+}
Type
TAppData = class
public
VendorName : String;
Constructor Create(aVendor: String);
end;
constructor TAppData.Create(aVendor: String);
begin
inherited Create;
VendorName := aVendor;
end;
var
AppData: TAppData;
begin
// Create a new instance of your TAppData class and keep it for safe-keeping in variable AppData
AppData := TAppData.Create('Hello world');
// do stuff, also with AppData
WriteLn('The name of the vendor is ', AppData.VendorName);
// Free the instantiated TAppdata class
AppData.Free;
end.
The public variable allows for change during runtime by user, and we like to prevent that so we make it a private variable and access it by introducing a property:
program test4;
{$MODE OBJFPC}{$H+}
Type
TAppData = class
private
fVendorName: String;
public
Constructor Create(aVendor: String);
property VendorName : String read fVendorName;
end;
constructor TAppData.Create(aVendor: String);
begin
inherited Create;
fVendorName := aVendor;
end;
var
AppData: TAppData;
begin
// Create a new instance of your TAppData class and keep it for safe-keeping in variable AppData
AppData := TAppData.Create('Hello world');
// do stuff, also with AppData
WriteLn('The name of the vendor is ', AppData.VendorName);
// Free the instantiated TAppdata class
AppData.Free;
end.
Now we introduce a property getter for vendorname.
program test5;
{$MODE OBJFPC}{$H+}
Type
TAppData = class
private
fVendorName: String;
protected
function GetVendorName: String;
public
Constructor Create(aVendor: String);
property VendorName : String read GetVendorName;
end;
constructor TAppData.Create(aVendor: String);
begin
inherited Create;
fVendorName := aVendor;
end;
function TAppData.GetVendorName: String;
begin
Result := fVendorName;
end;
var
AppData: TAppData;
begin
// Create a new instance of your TAppData class and keep it for safe-keeping in variable AppData
AppData := TAppData.Create('Hello world');
// do stuff, also with AppData
WriteLn('The name of the vendor is ', AppData.VendorName);
// Free the instantiated TAppdata class
AppData.Free;
end.
That allows us to change behaviour for this property in future, if there ever is a need for it, and without user knowing things changed (on the outside things still work the same).
Last step: introduction of event for getting the vendor name. This allows the user of your class to interfere/override return value
program test6;
{$MODE OBJFPC}{$H+}
Type
TOnGetVendorNameproc = function: String;
TAppData = class
private
fVendorName: String;
fOnGetVendorNameProc : TOnGetVendorNameproc;
protected
function GetVendorName: String;
public
Constructor Create(aVendor: String);
property VendorName : String read GetVendorName;
property OnGetVendorName: TOnGetVendorNameproc read fOnGetVendorNameProc write fOnGetVendorNameProc;
end;
constructor TAppData.Create(aVendor: String);
begin
inherited Create;
fVendorName := aVendor;
end;
function TAppData.GetVendorName: String;
begin
if Assigned(fOnGetVendorNameProc)
then Result := fOnGetVendorNameProc()
else Result := fVendorName;
end;
function MyGetVendorName: String;
begin
Result := 'Another world';
end;
var
AppData: TAppData;
begin
// Create a new instance of your TAppData class and keep it for safe-keeping in variable AppData
AppData := TAppData.Create('Hello world');
// do stuff, also with AppData
WriteLn('The name of the vendor (1) is ', AppData.VendorName);
AppData.OnGetVendorName := @MyGetVendorName;
WriteLn('The name of the vendor (2) is ', AppData.VendorName);
// Free the instantiated TAppdata class
AppData.Free;
end.
That still doesn't answer your direct question, but hopefully shows what goes wrong inside your code so that you're able to fix it.