Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

circular references - delphi curse

Status
Not open for further replies.

TeeeTeee

Programmer
Jul 27, 2006
6
0
0
JP
Delphi newby...
I have realised (too late) that Delphi does not support circular references between uses clauses.

I have two forms that communicate with each other, check values and update values between each others' forms.

In C++ I would use a base pointer to pass a reference to the other form and call the peer forms method, quite a simple matter.

In Delphi, I can't seem to do that. The base pointer produces an error and seems to need to explicitly know the type of the object. I can't use a 'class reference' the example 'class reference' code in help doesn't compile either. I can't use a generic form pointer. When I cast it up to the specific form object, it complains it doesn't know about the method I am calling.

I can't move the uses clauses out of the respective 'interface' &/or implementation' sections. They need to know about each other. I have read somewhere that 'circular references limitation' is a 'curse', carried over to Delphi.Net, that Delphi is still unable to fix or unwilling. As it is, a large part of the 'new' functionality of this application CANNOT BE IMPLEMENTED due to this restriction. This seems to seriously limit even the basic object oriented capabilities of Delphi.

Any info or comments this would be welcome.
 
Here is an example of a simple program that consists of Form1 being able to display Form2 or Form3 by clicking on a button. Form2 gets and displays data from Form3 and Form3 gets and displays data from Form2.

Form1 in Unit1:
Code:
...
implementation

{$R *.dfm}

Uses Unit2, Unit3;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.ShowModal;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Form3.ShowModal;
end;

end.

When the button in Form2 is clicked it gets and displays data from Form3:
Code:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    function GetText: string;
  end;

var
  Form2: TForm2;

implementation

uses Unit3;

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  Edit1.Text := IntToStr( Form3.GetNumber );
end;

function TForm2.GetText: string;
begin
  result := 'Data from form 2';
end;

end.

And likewise, when the button in Form3 is clicked it gets and displays data from Form2:
Code:
unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm3 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    function GetNumber: integer;
  end;

var
  Form3: TForm3;

implementation

uses Unit2;

{$R *.dfm}


procedure TForm3.Button1Click(Sender: TObject);
begin
  Edit1.Text := Form2.GetText;
end;

function TForm3.GetNumber: integer;
begin
  result := Random( 100 );
end;

end.
The key to this is where the uses clause is coded.

Or have I completely misunderstood your requirement?

Andrew
Hampshire, UK
 
Thankyou for your detailed reply. Unfortunately my problem relates to ptrs to forms. My explanation was not as clear as it could have been. I now believe I've struck a dead end because of the 'circular uses' issue, but if you are curious about the greater details, here it is below...

take two forms frmDaddy and frmMummy that inherit from a base frmBase. The base contains a pointer to a type TfrmAdapter. Each derived form should be able to create an instance of TfrmAdapter passing a ptr to it's base type in the constructor and the instance of TfrmAdapter should be able to make call backs to it's creators. (they pass information back and forth) The Adapter contains a ptr to a single frmTool, which is the 'peer' of mummy and daddy.

For this implementation:
frmDaddy uses frmBase (is derived from frmBase)
frmMummy uses frmBase (is derived from frmBase)
frmBase uses frmAdapter (has ptr to frmAdapter)
frmDaddy uses frmAdapter (req: for frmBase ptr in ctor)
frmMummy uses frmAdapter (req: for frmBase ptr in ctor)
frmAdapter uses frmTool (req: for the frmTool reference)

but...produces a circular reference. This cannot be solved by shuffling one reference into implementation section and another in interface.


the essentials of this solution is code reuse. I only need to write one adapter form and base and derive all my existing TForms from the frmBase and I get a form that has an adapter in it, oila!!! This is a very fast solution when you have a few forms and you don't want to minimise changes required for each of them.


In C++ this is simple stuff but in Delphi it is a real mess and in the end I found it couldn't be implemented. The alternative of using class references..? I found that the class references code in help, Delphi6, doesn't compile.
 
I am sure that this can be done using Class References. Can you post the code that won't compile?

Andrew
Hampshire, UK
 
Thanks,
You may be right there. Class references sound like they will fit the bill. However, I couldn't get a simple example to compile. From memory the errors seem to indicate that I hadn't defined the class although I assumed that class references must be bound at run time.

For the exercise to be useful to anyone else, I think I should simplify my example and create a new thread name "using class references or ptrs". Unfortunately the 'ptrs' relevant code (abandoned) is tangled up in about 60 pages of other stuff, so might not be easy to cut out the details.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top