Access Violation

Question.  Suppose a project contains 3 forms and the first form is
auto created, while the other 2 are created in button click  event.
All three forms contain a button. Button1 on form1 creates and then
shows Modally form2.

 Form2 contains table1 which is opened during form2's create
procedure.  Button2 on form2 creates form3 which is shown Modally.
 
Form3 contains button3  which simply Shows a  field from table 1
(which is on form2)
the code on button 3 looks like this:
procedure TForm3.Button1Click(Sender: TObject);
begin
showMessage(form2.Table1Name.Value);
end;

When button3 is pressed An access violation occurs
 Read of address  FFFFFFFF
which the table has not been created yet. but was opened in form2

General Info: Form1 Uses form2 .  Form2 Uses form3... and so on.
Is It Possible to access Any of the fields of table 1 on form2 ?
  I konw I could use a dataModule.  But Would Like to know why this
won't work.
  Thanks Paul Sutton

   

psuttonAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

kretzschmarCommented:
hi psutton,

do u use the global form2-variable, if you create form2?

meikl
0
RBertoraCommented:
Hi I have just tried it and there is no access violation.

Rob ;-)

I use D4 here is my code:

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2},
  Unit3 in 'Unit3.pas' {Form3};

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.


unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    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
  Application.CreateForm(TForm2, Form2);
  Form2.ShowModal;
end;

end.


unit Unit3;

interface

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

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

var
  Form3: TForm3;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm3.Button1Click(Sender: TObject);
begin
  showmessage(Form2.Table1.Fields[0].AsString);
end;

end.
0
RBertoraCommented:
doh! and unit 2:
unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    Button1: TButton;
    Database1: TDatabase;
    Table1: TTable;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

uses Unit3;

{$R *.DFM}

procedure TForm2.Button1Click(Sender: TObject);
begin
  Application.CreateForm(TForm3, Form3);
  form3.showmodal;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  Table1.Open;
end;

end.


Is this what you are doing????
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

karooCommented:
hi psutton,

I tried your small app and was unable to reproduce the error until i followed meikl's advice.
I agree with meikl...

On your button click in Form1 does your code look something like this?:
procedure TForm1.Button1Click(Sender: TObject);
var
  MyForm: TForm2;
begin
  MyForm:= TForm2.Create(Application);
  try
    MyForm.ShowModal;
  finally
    MyForm.Free;
  end;
end;

If it does then it means that when you access the instance of TForm2 in the ShowMessage then you must use the MyForm variable.
i.e.
procedure TForm3.Button1Click(Sender: TObject);
begin
 ShowMessage(MyForm.Table1Name.Value);
end;
0
RBertoraCommented:
Hmm well you should really do things using
 Application.CreateForm(TForm, Form);
to be on the safe side :-)
Rob;-)
0
karooCommented:
Rob,
why is it safer using Application.CreateForm?
Ben.
0
psuttonAuthor Commented:
Here is the code. I hsoul note that I am using D3.02 Pro
program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2},
  Unit3 in 'Unit3.pas' {Form3};

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

unit Unit1;

interface

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

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

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
 Var
  form2:Tform2;
begin
Form2:=Tform2.Create(Nil);
form2.ShowModal;
form2.free;
end;

end.

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Db, DBTables,unit3;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Table1: TTable;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

  Form3:Tform3;
implementation

uses Unit1;

{$R *.DFM}

procedure TForm2.FormCreate(Sender: TObject);
begin
Table1.Open;
end;

procedure TForm2.Button1Click(Sender: TObject);

begin
form3:=Tform3.create(nil);
form3.showModal;
form3.free;

end;

end.

unit Unit3;

interface

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

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

var
  Form3: TForm3;
 
implementation

uses Unit2;



{$R *.DFM}

procedure TForm3.Button1Click(Sender: TObject);
begin
showMessage(form2.Table1.Fields 0].AsString);
end;

end.
0
RBertoraCommented:
This statement is only visible from within your button click:
 Var
  form2:Tform2;

you have to declare the Form variables as global variables.
Rob ;-)
0
karooCommented:
hi psutton,

you can't pass nil as the Owner of the form.

Change: form3:=Tform3.create(nil);
To: Application.CreateForm(TForm3, Form3);
AND
Change: Form2:=Tform2.Create(Nil);
To: Application.CreateForm(TForm2, Form2);

Ben :)
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
RBertoraCommented:
Karoo: to be honest I don't know I just remember another expert whom I respected at the time saying so, so I believed him.. I forget the reason and who it was.. but at least that way you won't get accessviolations like in this example because you don't know your scope/visibility rules.

Rob ;-)
0
psuttonAuthor Commented:
Bingo. Why excellent ? Because It worked. Thanks
0
kretzschmarCommented:
hi friends,

nice discussion ;-)

i would prefer to do it as folloews

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2:= TForm2.Create(Application);
  try
    Form2.ShowModal;
  finally
    Form2.Release;
  end;
end;

if psutton do so,
then there should be no problem with the showmessage

meikl ;-)
0
karooCommented:
thanks Rob, i've only been here at EE for a short time but I respect your oppinions and advice already. I'm also still relativly new in Delphi (4 years:)

i also try to participate in some of the q's (and listen) although as you know some of my comments aren't always spot on. Luckilly there are Experts like you who accept newer members and point us in the right direction:)
This is my first EE expert points and I'm well.. :)) happy.

glad it helped psutton:)

Regards Ben.
0
kretzschmarCommented:
hi karoo,

>I'm also still relativly new in Delphi (4 years:)
ha ha hohoho, sounds like delphi version 1.0

meikl ;-)
0
RBertoraCommented:
Well done Karoo! nice to to start on the points trail :-)
0
karooCommented:
hahaha:))

meikl, hehe, i should have said 4 years in development, but thought 4 yrs in Delphi sounded nicer.

Ben:)
0
kretzschmarCommented:
well, karoo,

also my congratulations to your first expert-points ;-)
now they can grow.
i guess i see you now more as graded expert

>4 yrs in Delphi sounded nicer.
yup, sounds nicer

meikl ;-)
0
kretzschmarCommented:
hi rob,

1189 expert-points left to join the top 15
hurry now

meikl ;-)
0
karooCommented:
thanks meikl,
looong way to go but as they say it is not the destination that counts, but rather the journey:)

an good luck to you Rob,
it will be nice to see your name in the top 15.
0
RBertoraCommented:
Thanks Meikl and Karoo.. :-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.