Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Call stack 1

Status
Not open for further replies.

Koen Piller

Programmer
Jun 30, 2005
841
NL
Sequence of instructions / Call stack

I know we have LISA in VFP.

I have myForm which is subclassed from myBaseForm

Now I have in myForm.Load
Code:
If !Used('naw')
    Use naw In 0
Endif
Select naw
Dodefault
Locate

And in myBaseform.Load
Code:
Create Cursor curDistance (distance c(10,0))
Also in myForm an object on MyPageFrame.Page2.Grid1
Here you have code in Init:
Code:
Set Classlib To 'ZORGENZEK.VCX' Additive
 
This.RecordSource = This.RecordSource

DoDefault()
The Grid is based on class myGrid, here you have code in the init:
Code:
THIS.setgrid()
RETURN
When I follow in the debugger the callstack, I notice that the sequence is:
1) myForm.Load
2) myForm.MyPageFrame2.Grid1.init (not from Grid1 but from myGrid.init - inside to outside)

which is unwanted as the cursor (myBaseform.load) ia not yet created and thus the grid errors.
How can I rearrange so that the callstack will be:
myForm.Load
myBaseForm.Load
a.s.o.
or ventualy inside out

Koen
 
Koen,

First, the term "call stack" is not appropriate here. The call stack usually refers to the calling of functions and procedures rather than the execution of methods. But never mind. It's not important.

Next, I am worried about this:

Code:
Select naw
Dodefault
Locate

It is not clear from this code which table you want the LOCATE to operate on. In fact, it is curDistance, but you can't tell that my looking at the code on its own, and more importantly, if you subsequently change myBaseForm.Load, then myForm.Load would no longer work. In other words, you are introducing an unnecessary dependency.

But to answer your main question. You want to execute the code in myForm.Load before myBaseForm.Load. So you need to put all the myForm.Load code as the first code in myForm.Load, and follow it with your DODEFAULT. The point is that the parent code is executed at the point that DODEFAULT is encountered, so in this case the code in myBaseForm.Load would be executed after the code in myForm.Load, which you say is what you want.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
But none of that explains the error you are seeing. In general, if you want a cursor to be available when you initiate an object (in this case, a grid), then creating the cursor in the form's Load (including the Load of the form's parent classes) should work. As you have observed, the Load is executed before the control's Init.

In this case, there must be some other reason for the cursor not being available, most likely because it has been closed at some point.

I suggest you go back to the debugger, and set a Watch on USED("curDistance"). That will confirm that it has been created, and will show you if and when it is being closed. That might give you a clue to what is going wrong.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike,

Yes call stack may not be the correct expression, what I am referring to, hope you understood that, is the sequence of instructions.
Next, my coding here was indeed a little bit to little, in real it looks like in myFrom.init
Code:
If !Used('naw')
    Use naw In 0
Endif
Select naw
Locate
 
DoDefault()

and in the parent myEditform.init
Code:
Create Cursor curDistance (distance c(10,0))
Append Blank
Create Cursor curDistanceMtrs  ( afstand c(10,0) )
Append Blank
Create Cursor curDuration ( duration c(10,0) )
Create Cursor curFinal ( finalcontent M )
Create Cursor curWebPage ( content M )
Create Cursor curRoute ( instructions M )
Create Cursor curLatLan ( ;
    Start_addressLatLan c(35), End_addressLatLan c(35), Start_address c(100), ;
    End_address c(100), Start_addressCalculated c(100),  End_addressCalculated c(100))

If !Used('Zorgverzekeraar')
    Use Zorgverzekeraar In 0
Endif
these cursors are never created, VFP 'jumps' to the MyForm.MyPageframe1.Grid1.Init (The Parent) and does not executes the parent init from myForm.

Yes I would like to the parent code to be executed at the point that DODEFAULT is encountered, so in this case the code in myBaseForm.Load would be executed after the code in myForm.Load, which you say is what you want.

Have now recoded and moved the DoDefault to line 1 in the init, see how it goes than.
Regards,
Koen
 
OK when dodefault is moved to the first line, the parent.load is executed. After that
mypageframe.Page2.Grid.init (the parent)
myPageframe.Page2.Grid.init
..
..
and myForm.init is NOT executed grr.

I always believed the form would do first LISA and than, after that instantiate all the objects from inside out, however it seems it is
1)L
2) all the objects inside out
3)Init
4)Set
4)Activate

Is that correctly understood??

Regards,

Koen


 
Your understanding of LISA is correct. But the point is that the form's Init is executed after the Inits of all its contained objects. If you create a cursor in the form's Init (and it makes no difference whether that is in the form object or any of its parent clases), it will be too late to use it in the Init of a gid, or any other contained object.

But that's not what you had in your original post. You said you were creating the cursor in Load, not the Init. The Load is executed before any of the controls' Inits, so that is the correct place to create your cursors.

That said, I would take a completely different approach. I would put all the relevant code in the form's Init. I would first create the cursors (or call a custom method which creates the cursors), and then call a method which sets up the grids, in particular which sets their record sources.

I hope this makes sense.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Just want to point out that DODEFAULT() should have parens. It appears it's not giving you an error without, but calling it without the parens is like making a function call without parens.

Tamar
 
Tamar,

Thanks, that seems to be the trouble!

Regards,

Koen
 
I don't see how that resolves the issue, it's normal that the form init runs after all controls inits.

If you do a bunch of CREATE CURSOR in form.init, that's too late for control init code to bind them. Such cursor creating code has to be in a load event, not form init.

LISA is just roughly describing the event order of the form and the form init runs after the form load, that's totally valid, but it also runs after all controls init. The controls are instantiated and initialized, so the form init can reference them. That's what you're missing, most probably.

And as I just explained lately, you can solve binding problems and make it very relaxed even for grids, when you make use of form.BindControls. At designtime set it .F. and then only set it .T. when all controls are set up and ready.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Yes, Tamar was right, when I changed from dodefault to dodefault() everything worked as default. Sorry MS did not make an error catch on dodefault - without the parents.

Regards,

Koen
 
I actually get an error "unrecognized command verb" when calling DODEFAULT with parens. Maybe at that moment, you have an error message suppressing handler active, like ON ERROR *.

And doing DODEFAULT() correctly in load also doesn't explain how the cursor creation in init now worked, too. It will be done afterward. It does not matter much in many cases, as controls really wake up binding to their controlsource once the form becomes activated and controls are shown, the drawing of them causes them to look up the value to display in the data. Even grids are not always susceptible to missing their conrtolsource while you're still before the Show() moment making a form visible and letting the grid draw itself, scanning through its recordsource.

So that may also explain why you can actually create cursors "too late" at init, as it's still before the form becomes activated. I just think it's natural you create cursors in the load(), unless it requires knowledge of init parameters to create the cursors, even their empty structure. Just a thought, even if it works now.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Olaf,
I am very happy with the information from Tamar, dodefault without parentheses indeed does not execute. Which in my situation explains why my cursor was not created, since the instruction to do this was given in the parent (the dodefault()) init.
Correcting dodefault into dodefault() makes the parent execute, thus creates the cursor, before anything else, just in time.
Regards,
Koen
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top