0
votes

I'm using 2 Units in Delphi 2010: Unit1 has a Form with a TEdit and a Button, this Button will call a procedure from Unit2 (Unit2 doesn't have a form). That procedure will change the 'caption' property of the TEdit of Unit1, I tried to put Unit2 in Unit1 "Uses" to access the procedure, and put Unit1 in the "Uses" of Unit2 to to access the TEdit in Unit1, but this relation is cyclic.

I'm not sure what can I do to solve this, any suggestion?

1
do not tie GUI elements together and the problem wil solve itself. Work with objects and pass them between forms, the object can be defined in a separate unit that can be used by both forms...whosrdaddy
Well, it can be done by moving the uses Unit1 clause to the implementation section of unit 2, but that is far from good practice. Unit 2 should really be organised so that is does not need to know about unit 1. For example, the procedure in unit 2 could be a function that returns a string which unit 1 will then assign to the caption property of unit1.Dsm
Thank you guys for replying, I'll try your suggestionsBaldwinIV

1 Answers

1
votes

There are many ways to do this, and which one is most appropriate depends crucially on the precise circumstances, so technically this question is too broad for Stack Overflow, I suspect.

Method 1

Still, let me just show you one very simple approach. This might not be a good approach, but it is close to what it seems you are trying to do.

  1. Create a new VCL application.
  2. Drop a TButton and a TEdit control on the main form (TForm1 in Unit1).
  3. Create a new unit, Unit2:

    unit Unit2;
    
    interface
    
    procedure SetCaption;
    
    implementation
    
    uses
      Unit1;
    
    procedure SetCaption;
    begin
      Unit1.Form1.Edit1.Text := 'Hello, World!';
    end;
    
    end.
    
  4. On the main form, use this event handler for the button's OnClick event:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Unit2.SetCaption;
    end;
    

    after you have added Unit2 to the implementation section's uses clause. In full,

    unit Unit1;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
    
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    uses
      Unit2;
    
    {$R *.dfm}
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Unit2.SetCaption;
    end;
    
    end.
    

Notice how the units may use each other if referenced only in the implementation sections. Also notice we use the global Form1 variable in Unit1 to refer to the automatically created instance of TForm1. In many (most) cases, you don't want to use automatically created forms, but that is a different story (I could write a 100-page Delphi textbook here!).

Method 2

Also, let me reiterate the fact that there are many other ways to accomplish this result. For instance, this is arguably a better approach:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

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

var
  Form1: TForm1;

implementation

uses
  Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Unit2.SetCaption(Edit1);
end;

end.



unit Unit2;

interface

uses
  StdCtrls;

procedure SetCaption(AEdit: TCustomEdit);

implementation

procedure SetCaption(AEdit: TCustomEdit);
begin
  AEdit.Text := 'Hello, World!';
end;

end.

Method 3

Arguably even better:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

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

var
  Form1: TForm1;

implementation

uses
  Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit1.Text := Unit2.GetText;
end;

end.



unit Unit2;

interface

function GetText: string;

implementation

function GetText: string;
begin
  Result := 'Hello, World!';
end;

end.