John Barrat
John Barrat

Reputation: 830

Scoping issue with Set types

I have 3 units This is my main unit....

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

Uses Unit2;

{$R *.dfm}


procedure TForm1.FormShow(Sender: TObject);
begin
  Panel1.Visible := oiNone in form2.Settings.OptVars;
  Panel2.Visible := oiHint in form2.Settings.OptVars;
  Panel3.Visible := oiStat in form2.Settings.OptVars;
end;

end.

This is the second unit - used by the first. unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    Settings: TSettings;
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
begin
  Settings := TSettings.Create;
  Checkbox1.Checked := oiNone in Settings.OptVars;
  CheckBox2.Checked := oiHint in Settings.OptVars;
  CheckBox3.Checked := oiStat in Settings.OptVars;
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
  Settings.Free;
end;

end.

and this is the unit which is used by the second unit and contains the Set type which is used by both other units.

unit Unit3;

interface

Uses
  winAPI.windows,system.classes;

Type
  TOptions = Set Of (oiNone, oiHint, oiStat);

  TSettings = class

  private
    fMyOption:    TOptions;
  public
    Constructor Create;
    Destructor Destroy;
    property OptVars: TOptions read fMyOption write fMyOption;
  end;


implementation

constructor TSettings.Create;
begin
  fMyOption := [oiNone, oiHint, oiStat];
end;

destructor TSettings.Destroy;
begin

end;

end.

In the second unit, the items oiNone,oiHint, oiStat are accessible and within scope.

In the first unit, the items oiNone, oiHint and oiStat are not accessible and within scope although the Settings.OpVars which is a TOption data type is accessible.

I cannot think of a better way to describe my problem. If you put these into a project you should see the issue.

Upvotes: 2

Views: 103

Answers (2)

David Heffernan
David Heffernan

Reputation: 613013

Update

After the latest edit it is clear that my first hunch was correct. You weren't using the unit that declares the type. The names have changed, but with the current edit your problem is that the main unit does not use Unit3.


You need to reference the unit that declares the set type, and its enumerated type. Add UnusedItemsReg to your uses clause in the third unit.

If you have done that then the only other explanation I can imagine is that you compile with scoped enums enabled. But I'm clutching at straws now.

I would definitely recommend that you declare the enumerated type as a named type in its own right. Certainly if you use scoped enums then you'll need to do that. But sooner or later you'll want to have that type available.

type
  TOption = (oiNone, oiHint, oiStat); 
  TOptions = set of TOption;

If you do use scoped enums then you'll refer to then like this:

TOption.oiNone

Upvotes: 4

Dsm
Dsm

Reputation: 6013

You need Unit3 in the (a) uses clause of the main unit. Otherwise it cannot see type TOptions. That is a requirement of Delphi for visibility. It does not use the implicit references that you seem to be seeking.

Upvotes: 3

Related Questions