Reputation: 1222
I want to access a main form variable from a class that is called from the main from. Something like this:
Unit1:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,Unit2, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
Chiled:TChiled;
const
Variable = 'dsadas';
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Chiled.ShowMainFormVariable;
end;
end.
Unit2:
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TChiled = class
private
public
procedure ShowMainFormVariable;
end;
var
Form1: TForm1;
implementation
procedure TChiled.ShowMainFormVariable;
begin
ShowMessage(Form1.Variable);
end;
end.
if in Unit2 i add to uses Unit1 an circular errors pops up.
How to make the Unit1 to be GLOBAL?
Upvotes: 4
Views: 5325
Reputation: 54832
As other answers tell, you should use one of the units in implementation section.
Suppose you chose in 'unit2' you'd use 'unit1' in implementation. then you need to devise a mechanism to tell the 'TChiled' how to access 'Form1'. That's because since you haven't used 'unit1' in interface section of 'unit2', you cannot declare the 'Form1:TForm1' variable in interface section. Below is just one possible solution:
unit2
type
TChiled = class
private
FForm1: TForm;
public
procedure ShowMainFormVariable;
property Form1: TForm write FForm1;
end;
implementation
uses
unit1;
procedure TChild.ShowMainFormVariable;
begin
ShowMessage((FForm1 as TForm1).Variable);
end;
then in unit1 you can set the Form1 property of TChiled before calling TChiled's method:
procedure TForm1.Button1Click(Sender: TObject);
begin
Chiled.Form1 := Self;
Chiled.ShowMainFormVariable;
end;
Upvotes: 6
Reputation: 985
I generally create a Data Module (or any type of non-visual container) to share global variables. This way both units can use the variable without a circular reference.
Upvotes: 1
Reputation: 613531
Well, the simple naive answer is that you should add Unit1
to the uses
clause of the implementation section of Unit2
:
unit Unit2;
......
implementation
uses
Unit1;
.....
You can't add it to the uses
clause in the interface section of Unit2
since that would create a circular reference at the interface section. In order words, the interface of Unit1
would uses Unit2
, and the interface of Unit2
would use Unit1
. The language does not allow that. The common solution is to use
one of the units at the implementation level.
Having said that, your code is rather confused and fails in many other ways. Your problems run deeper than the circular reference. For example, what do you mean by Form1.Variable
? The constant Variable
is not a member of TForm1
. You declare two global variables named Form1
of type TForm1
. Why do you do that?
Also, you have spelled child incorrectly.
Upvotes: 3
Reputation: 5115
the simplest solution is to add Unit1 to a uses clause inside Unit2's implementation section as this gets around the circular reference.
However I'd suggest that this design is flawed. It is hard to see what you are trying to achieve with the sample code so it is difficult to offer any real advice.
Upvotes: 3