Create Delphi Object in Form
I have a Delphi form that doesn't have a component. Then I create a block with multiple classes. I tried to instantiate the class and create an object on the form, but it complains that the class is not declared. here is the error message: "E2003 Undeclared Identifier: TUser".
Here's the project:
Testing the program;
uses
Forms,
Home in 'Home.pas' {Form1},
uUser in 'uUser.pas';
{$R *.res}
begin
ReportMemoryLeaksOnShutdown := DebugHook <> 0;
Application.Initialize;
Application.Run;
end.
Here is my empty form:
unit Home;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, uUser;
type
TForm1 = class(TForm)
private
{ Private declarations }
protected
public
{ Public declarations }
u : TUser; //It complaining about TUser. I can right click on
TUser, and it will take me to the class declaration.
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
end.
Here is the class I created:
unit uUser;
interface
uses
classes,SysUtils,Dialogs;
implementation
type
TAddress = class
private
FStreetAddress : string;
FCity : string ;
FState : string;
FZipCode : string;
procedure setStreetAddress(const Value : string);
procedure setCity(const Value : string);
procedure setState(const Value : string);
procedure setZipCode(const Value : string);
protected
public
property StreetAddress : string read FStreetAddress write setStreetAddress;
property City : string read FCity write setCity;
property State : string read FState write setState;
property ZipCode : string read FZipCode write setZipCode;
end;
type
TPermanentAdddress = class (TAddress)
private
FStartDate : string;
FEndDate : string;
procedure setStartDate(const Value : string);
procedure setEndDate(const Value : string);
protected
public
property StartDate : string read FStartDate write setStartDate;
property EndDate : string read FEndDate write setEndDate ;
end;
type
TUser = class(TComponent)
private
FFirstName : string;
FAddress : TPermanentAdddress;
procedure setFirstName(const Value : string);
procedure setAddress(const Value : TPermanentAdddress);
protected
public
constructor Create(); reintroduce; overload;
destructor Destroy(); override;
property FirstName : string read FFirstName write setFirstName;
property Address : TPermanentAdddress read FAddress write setAddress;
end;
procedure TAddress.setStreetAddress(const Value : string);
begin
FStreetAddress := value;
end;
procedure TAddress.setCity(const Value : string);
begin
FCity := Value;
end;
procedure TAddress.setState(const Value : string);
begin
FState := Value;
end;
procedure TAddress.setZipCode(const Value : string);
begin
FZipCode := Value;
end;
//Permanent Address
procedure TPermanentAdddress.setStartDate(const Value : string);
begin
FStartDate := value;
end;
procedure TPermanentAdddress.setEndDate(const Value : string);
begin
FEndDate := Value;
end;
//tvxpatient
procedure TUser.setFirstName(const Value : string);
begin
FFirstName := Value;
end;
procedure TUser.setAddress(const Value : TPermanentAdddress);
begin
FAddress := Value;
end;
constructor TUser.Create();
begin
FAddress := TPermanentAdddress.Create;
end;
destructor TUser.Destroy();
begin
//FAddress.Free;
end;
end.
source to share
All of your classes are in a section implementation
, which means they are not visible outside of the device itself. Move them to the section interface
.
unit uUser;
interface
uses
classes,SysUtils,Dialogs;
interface
type
TAddress = class
private
FStreetAddress : string;
FCity : string ;
FState : string;
FZipCode : string;
procedure setStreetAddress(const Value : string);
procedure setCity(const Value : string);
procedure setState(const Value : string);
procedure setZipCode(const Value : string);
protected
public
property StreetAddress : string read FStreetAddress write setStreetAddress;
property City : string read FCity write setCity;
property State : string read FState write setState;
property ZipCode : string read FZipCode write setZipCode;
end;
type
TPermanentAdddress = class (TAddress)
private
FStartDate : string;
FEndDate : string;
procedure setStartDate(const Value : string);
procedure setEndDate(const Value : string);
protected
public
property StartDate : string read FStartDate write setStartDate;
property EndDate : string read FEndDate write setEndDate ;
end;
type
TUser = class(TComponent)
private
FFirstName : string;
FAddress : TPermanentAdddress;
procedure setFirstName(const Value : string);
procedure setAddress(const Value : TPermanentAdddress);
protected
public
constructor Create(); reintroduce; overload;
destructor Destroy(); override;
property FirstName : string read FFirstName write setFirstName;
property Address : TPermanentAdddress read FAddress write setAddress;
end;
implementation
procedure TAddress.setStreetAddress(const Value : string);
begin
FStreetAddress := value;
end;
procedure TAddress.setCity(const Value : string);
begin
FCity := Value;
end;
procedure TAddress.setState(const Value : string);
begin
FState := Value;
end;
procedure TAddress.setZipCode(const Value : string);
begin
FZipCode := Value;
end;
//Permanent Address
procedure TPermanentAdddress.setStartDate(const Value : string);
begin
FStartDate := value;
end;
procedure TPermanentAdddress.setEndDate(const Value : string);
begin
FEndDate := Value;
end;
//tvxpatient
procedure TUser.setFirstName(const Value : string);
begin
FFirstName := Value;
end;
procedure TUser.setAddress(const Value : TPermanentAdddress);
begin
FAddress := Value;
end;
constructor TUser.Create();
begin
FAddress := TPermanentAdddress.Create;
end;
destructor TUser.Destroy();
begin
//FAddress.Free;
end;
end.
Also, as a side note: the only reason for descending from TComponent
is to create components that will appear on the Component Palette (which means they need a procedure Register
). Unless you are developing components that will be disposed of by form at design time, they don't need the overhead TComponent
as an ancestor - they can just descend from TObject
, which will presumably be for your class TUser
.
source to share