>>ASTK Local A errorlogging >> ( 1, 1) N 1 ( 1,00000000) >> ( 1, 2) C "d:\foxproprojects\zorgenzekerheid\classes\googlemailcomposer.vct" >> ( 1, 3) C "frmgooglemail1.gglmailbox1.gglgrid1.column1.gglcntgrid1.lblname.click" >> ( 1, 4) C "d:\foxproprojects\zorgenzekerheid\classes\googlemailcomposer.vct" >> ( 1, 5) N 1 ( 1,00000000) >> ( 1, 6) C "this.Parent.doit()" >> ( 2, 1) N 2 ( 2,00000000) >> ( 2, 2) C "d:\foxproprojects\zorgenzekerheid\classes\googlemailcomposer.vct" >> ( 2, 3) C "frmgooglemail1.gglmailbox1.gglgrid1.column1.gglcntgrid1.doit" >> ( 2, 4) C "d:\foxproprojects\zorgenzekerheid\classes\googlemailcomposer.vct" >> ( 2, 5) N 77 ( 77,00000000) >> ( 2, 6) C " .Left = m.lnLeft" >> ( 3, 1) N 3 ( 3,00000000) >> ( 3, 2) C "d:\foxproprojects\zorgenzekerheid\progs\errorlogging.fxp" >> ( 3, 3) C "ON... " >> ( 3, 4) C "d:\foxproprojects\zorgenzekerheid\progs\errorlogging.prg" >> ( 3, 5) N 91 ( 91,00000000) >> ( 3, 6) C "= Astackinfo(m.aStk)" >> >>>>
>>For i = Alen(m.aStk, 1) - 1 To 1 Step - 1 >>* I named each element to make it easier to understand (jjh) >> lcCurPrg = m.aStk(m.i, 2) >> lcModule = m.aStk(m.i, 3) >> lcSource = m.aStk(m.i, 4) >> lcModLine = Transform(m.aStk(m.i, 5)) >> lcSrcCode = m.aStk(m.i, 6) >>>>
* Return the call stack as a string LOCAL lnStackSize, laCallStack[1], lcStackInfo, lnStackLevel STORE 0 TO lnStackSize, laCallStack[1], lnStackLevel STORE SPACE(0) TO lcStackInfo * Use ASTACKINFO() lnStackSize = ASTACKINFO(laCallStack) FOR lnStackLevel = 1 TO m.lnStackSize lcStackInfo = m.lcStackInfo + ; " Level: " + TRANSFORM(laCallStack[m.lnStackLevel, 1]) + CHR(13) + CHR(10) + ; " File: " + laCallStack[m.lnStackLevel, 2] + CHR(13) + CHR(10) + ; " Module/Object: " + laCallStack[m.lnStackLevel, 3] + CHR(13) + CHR(10) lcStackInfo = m.lcStackInfo + ; " Line: " + TRANSFORM(laCallStack[m.lnStackLevel, 5]) + ; ": " + laCallStack[m.lnStackLevel, 6] + CHR(13) + CHR(10) ENDFOR lnStackLevel = 1 TO m.lnStackSize RETURN m.lcStackInfoBy having it as a separate function, I can use it other debugging code. For example, when I don't understand why/where a particular property is changing, I'll add an assign method to the property and put code in it like:
DEBUGOUT PROGRAM() DEBUGOUT " New value =", m.tuNewValue DEBUGOUT "" DEBUGOUT "--- Call stack ---" DEBUGOUT getstack() DEBUGOUT "--- End call stack" DEBUGOUT ""Then, I can test and see every time the property gets changed, exactly what was going on.