delphi - Access Violation While Calling Form's Method -


i have form tform1 have kept cxspreadsheet component on it. have created class called ttest. ttest class contains 2 methods 1 loading data , saving data.

when calling method of tform1 class inside ttest class method, though component created giving access violation when call test.loadmydata method, gives access violation atableview1 variable.

what wrong doing ?

type   tform1 = class(tform)     dxspreadsheet1: tdxspreadsheet;     procedure formshow(sender: tobject);   public     atableview1 : tdxspreadsheettableview;     procedure initilize;     procedure loaddata;   end;    ttest = class   public     procedure savemydata(myvalue : string);     procedure loadmydata;   end;  var   form1: tform1;   test: ttest;  implementation  {$r *.dfm}  procedure tform1.formshow(sender: tobject); begin   form1 := tform1.create(self);   initilize;   test := ttest.create;   test.loadmydata; end;  procedure tform1.initilize; begin   atableview1 := dxspreadsheet1.sheets[0] tdxspreadsheettableview; end;  procedure tform1.loaddata; begin   atableview1.cells[10,1].settext('test application'); end;  procedure ttest.loadmydata; begin   form1.loaddata; end; 

in question left out important piece of puzzle. you've mentioned in comments, repeat here because it's direct trigger of problem. in comments said form created follows:

with tform1.create(self) begin   try     showmodal;       free;   end; end; 

your problem within call-chain of showmodal expect form1 assigned specifically instance you've created. haven't yet done set form1.

your "solution" assign form1 within showmodal call-chain. while solves immediate problem, far correct, , i'll explain why later. first i'll show simple solution have avoided problem altogether (note it's not complete solution because there far more problems code realise).

solution, rid of with:

//this first line important. //it explicitly sets variable must assigned new form. form1 := tform1.create(self); try   form1.showmodal;   form1.free; end; 

vishal, try out. if do, you'll see works. , have full attention now. didn't believe @ first, perhaps realise do understand correctly.


so why "solution" wrong? after seems solve problem....

well, said yourself: expected form1 assigned @ start of formshow. you're right, should be. assigning form1 := self; inside formshow you're patching earlier mistake. surely agree it's better fix original mistake patch on later?

but there's deeper problem here... i'm not sure understand difference between "object instances" , "classes". (if do, please still read next few paragraphs revision.)

it seems expected when tform1 created should automatically assigned form1 variable. it's if expected there ever 1 tform1 in memory @ point in time. tform1 class type; meaning defines behaviour any number of object instances of same type. each time create tform1, it's new separate instance of form. , each instance can have own variable assigned it. e.g.

johnsform1 := tform1.create(self); paulsform1 := tform1.create(self); 

consider moment happens incorrect "solution" if needed 2 form variable? write inside formshow method? johnsform1 := self; or paulsform1 := self;?

of course can still choose keep 1 instance of tform1 in memory @ time. delphi has no way automatically know intend. should still desired assignments explicitly above.


i mentioned there still more serious problems code. it's related above discussion object instance , class types.

your ttest class makes bunch of unnecessary assumptions:

  • it assumes there ever 1 instance of tform1.
  • it assumes form available when needed.
  • and assumes form assigned form1 variable.

so again, if need johnsform1 , paulsform1, code won't work.

a tiny change ttest.loadmydata , tform1.formshow solves these problems.

//write loadmydata can told form instance load data procedure ttest.loadmydata(aloadform: tform1); begin   aloadform.loaddata; end;  //change formshow tell test form use in loadmydata procedure tform1.formshow(sender: tobject); begin   initilize;   test := ttest.create;   test.loadmydata(self); end; 

for record, david gave information in his answer. answer demonstrates proper resource protection new ttest instance, whereas i've left out sake of simplicity.

by way, these 2 little changes have solved problem.
basically, had 2 mistakes in code. combination of both mistakes caused problem.
can fix either 1 make problem go away. should fix both make code better.


Comments