Link to home
Start Free TrialLog in
Avatar of psutton
psutton

asked on

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

   

Avatar of kretzschmar
kretzschmar
Flag of Germany image

hi psutton,

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

meikl
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.
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????
Avatar of karoo
karoo

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;
Hmm well you should really do things using
 Application.CreateForm(TForm, Form);
to be on the safe side :-)
Rob;-)
Rob,
why is it safer using Application.CreateForm?
Ben.
Avatar of psutton

ASKER

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.
This statement is only visible from within your button click:
 Var
  form2:Tform2;

you have to declare the Form variables as global variables.
Rob ;-)
ASKER CERTIFIED SOLUTION
Avatar of karoo
karoo

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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 ;-)
Avatar of psutton

ASKER

Bingo. Why excellent ? Because It worked. Thanks
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 ;-)
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.
hi karoo,

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

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

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

Ben:)
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 ;-)
hi rob,

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

meikl ;-)
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.
Thanks Meikl and Karoo.. :-)