Welcome to MSDN Blogs Sign in | Join | Help

Application logging and Error methods

I have some Fox classes that run in several modes.

  • The normal fox interactive design environment
  • In a runtime Multithreaded DLL from the fox interactive environment
  • In a runtime Multithreaded DLL from within a client application (like windows explorer)

 

The error methods of those classes do different things depending on _vfp.StartMode(“Returns the Fox Start Mode. 0=None, 1=LocalServer, 2=Runtime EXE Server, 3=Runtime DLL Server, 4=VFP Runtime App, 5=Runtime MTDLL Server”)

 

VFP MT DLLs do not normally do UI (User Interface) because they’re targeted to be used in server applications, such as web servers which have no UI. But you can still call MessageBox by using DECLARE DLL as shown.

 

Many windows APIs that take strings as parameters have two versions: ANSI and Wide char. The ANSI ones use a single byte per character, and the Wide versions use Unicode. If you single step through the assembly code you can see that one version just converts the parameter for the other and then calls it.

 

From winuser.h:

 

#ifdef UNICODE

#define MessageBox  MessageBoxW

#else

#define MessageBox  MessageBoxA

#endif // !UNICODE

 

You can see that both MessageBoxA and MessageBoxW are exported from user32.dll:

link /dump /exports c:\windows\system32\user32.dll

 

The OutputDebugString call outputs to any attached debugger. I typically run with Visual Studio as the debugger, so its output window shows a log of what’s happening.

 

The VFP program has a single PUBLIC integer variable called g_debugFlags which has up to 32 bits, each of which can indicate which things to log to the DebugOutputWindow and/or a logfile. Filtering the events to only those of interest reduces the noise.

 

I have both a RETRY and a RETURN statement: while at a breakpoint in the VFP debugger, I can change variable values or switch to the command window to open tables, etc. A RETRY will try again to execute the erroneous statement, and RETURN will skip that statement and proceed with the following one.

 

 

 

DEFINE CLASS ShellNode AS session

      PROCEDURE error(nError, cMethod, nLine)

            cStr=PROGRAM()+" "+MESSAGE()+" "+MESSAGE(1)+" "+TRANSFORM(nError)+" "+TRANSFORM(cMethod)+" "+TRANSFORM(nLine)

            ?cStr

            IF _vfp.StartMode=0

                  SET STEP ON && open debugger

                  RETRY && to retry statement that triggered err

                  RETURN && SET NEXT Stmt (Shift+Ctrl-F7 here will skip statement that triggered err

            ENDIF

            DECLARE integer MessageBoxA IN WIN32API integer,string,string,integer

            this.logit(cStr,.t.)

            nRet=MessageBoxA(0,cStr,PROGRAM(),2+512+32)

            DO CASE

            CASE nRet=3 &&Abort

                  COMRETURNERROR(PROGRAM(),cStr)

            CASE nRet=4 &&Retry

                  RETRY

            CASE nRet=5 &&Ignore

                  RETURN

            ENDCASE

      PROCEDURE logit(cstr as String,fForce as Boolean)

            IF BITAND(DF_NSELOGFILE + DF_NSEVFP,g_debugflags)>0 OR fForce

                  DECLARE integer OutputDebugString IN WIN32API string

                  cstr=TRANSFORM(DATETIME())+" "+cstr+CHR(13)

                  OutputDebugString(cstr)

                  IF BITAND(DF_NSELOGFILE,g_debugflags)>0 OR fForce

                        STRTOFILE(cstr,LOGFILE,.t.)

                  ENDIF

            ENDIF

ENDDEFINE

 

 

 

63067

 

 

 

 

Published Friday, May 27, 2005 11:50 AM by Calvin_Hsia
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Application logging and Error methods

Saturday, May 28, 2005 4:04 AM by Stefan Wuebbe
Another great article, thanks!
On a probably less-important side aspect - is there a "hidden insight" in not declaring variables like cStr, nRet as Local at that point?

> PROCEDURE error(nError, cMethod, nLine)
> cStr=PROGRAM()+" "+MESSAGE()+"...


-Stefan

# re: Application logging and Error methods

Saturday, May 28, 2005 4:27 AM by Malcolm Greene
Calvin,

Thanks for continuing to post code examples. Every post is a learning experience for me and most of your code posts find their way into my code base almost immediately.

The FOX Rocks!

Thanks for an awesome product,

Malcolm

# re: Application logging and Error methods

Tuesday, May 22, 2007 3:05 AM by Pasan

Is there any way to get the error line code at runtime.VFP help says message(1) is not available at Runtime.

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker