Often even if warned not to mix DDT and SDK, we all see the benefits (and awe at the "Why did it crash?") in examples and problems that people have.

I submit the idea that no one way of thinking is ALWAYS correct, but when you mix and match (even when you did not know you did) that this may be of help.

What if you can "Run-Time" Debug??? even after testing with debugger for things you did not think of???

Worth a few or more $$$ to me...and because I hate it when offered a possibly good tool that benefits all I think worth posting in case it can help someone else.

Select if you want to debug, catch errors, log the errors, and build routines from there to prevent the errors

Still a TON to work on ideas, but this should help most people
Modules below, or download the project

Error_Handling_API_and DDT_Demo.bas
Code:
#COMPILE EXE                                                          'Compile as Executable
#DIM ALL                                                              'Force all variables be declared
#DEBUG ERROR OFF                                                      'Force all errors to be logged (including crashes)
#TOOLS ON                                                             'Keep all Integrated tools turned on
'--------------------------------------------------------------------------------
'   ** Includes **
'--------------------------------------------------------------------------------
#INCLUDE "WIN32API.INC"                                               'Windows API routines
#INCLUDE "ErrorHandling.inc"                                          'ErrorHandling routines
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
'   ** Constants **
'--------------------------------------------------------------------------------
%IDD_DIALOG1                  = %WM_USER + 101                        'PbForms but I like to follow SDK Rules using %WM_USER
%IDR_MENU1                    = %WM_USER + 102                        'PbForms but I like to follow SDK Rules using %WM_USER
%IDM_DEBUG_DEBUGON            = %WM_USER + 1001                       'PbForms but I like to follow SDK Rules using %WM_USER
%IDM_DEBUG_DEBUGOFF           = %WM_USER + 1002                       'PbForms but I like to follow SDK Rules using %WM_USER
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
'   ** Declarations **
'--------------------------------------------------------------------------------
DECLARE FUNCTION PBMAIN()                                             'PbForms but I like to declare EVERYTHING
DECLARE FUNCTION AttachMENU1(BYVAL hDlg AS DWORD) AS DWORD            'PbForms but I like to declare EVERYTHING
DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()                           'PbForms but I like to declare EVERYTHING
DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG          'PbForms but I like to declare EVERYTHING
'--------------------------------------------------------------------------------
'*** Now for the FUN Stuff
'***      PB has 'On Error' for handling errors on the DDT side
'***           PB can raise an error just by ERR = some number
'***      Windows has 'GetLastError' to check any errors via SDK
'***           Windows has to check for errors and handle them (errors are not raised)
'***      Windows has "Exceptions" (You've seen them...the default usually shows the typical "*.exe has encountered a problem and needs to close" message)
'***           Windows "Exceptions" can be raised, but default handler is typically fatal, but you can override that fatality
'*** I REALLLLLLY want to know how to do the below without visibly inserting numbers but.....
'***      PB Line numbers (if inserted) can assist in locating where an error occured (larger projects its smarter to contain line numbers to their functions)
'***      PB FUNCNAME$ in conjunction with the line numbers can nail down what line the error occured on
'***           Conjunction, junction, whats your function??? :-)
'*** What makes it all work????
'*** MACRO's baby, yeah baby yeah...(Finally got this one when larger code all had the same multiple commands and got tedious to type or copy/paste)
'*** Globals.....Real Men don't need no stinkin Globals :-) (Finally got this one working deep with Windows API...See "Parameter as Reply" discussion)
'--------------------------------------------------------------------------------
FUNCTION PBMAIN()
1    TraceVariables                                                   'Add To whatever function you want to debug
2    LOCAL CommandLine AS STRING                                      'Variable for if CommandLine was passed to start program
3    CommandLine = UCASE$(COMMAND$)                                   'Get the uppercase version of what the commandline is
'*** METHOD 1 - LOG EVERYTHING (pass a commandline to auto-start either via commandline or shortcut with commandline commands)
4    SELECT CASE CommandLine                                          'Check CommandLine  '<--- Is there a equivelent in API to COMMAND$????
5         CASE "TRACE"                                                'If Trace then
6              StartTrace                                             'Start Tracing Routines
7         CASE ELSE                                                   'If not then don't Trace till told to Trace
8     END SELECT
9     ShowDIALOG1 %HWND_DESKTOP                                       'PbForms function
10     TraceUnHandled                                                 'Macro for Local Variables and Unhandled Errors
END FUNCTION
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
'   ** Menus **
'--------------------------------------------------------------------------------
FUNCTION AttachMENU1(BYVAL hDlg AS DWORD) AS DWORD
1    TraceVariables                                                   'Add To whatever function you want to debug (In this case most top-level possible)
2    LOCAL hMenu AS DWORD
3    LOCAL hPopUp1 AS DWORD
4    MENU NEW BAR TO hMenu
5    MENU NEW POPUP TO hPopUp1
6    MENU ADD POPUP, hMenu, "Debug", hPopUp1, %MF_ENABLED
7         MENU ADD STRING, hPopUp1, "Debug On", %IDM_DEBUG_DEBUGON, %MF_ENABLED
8         MENU ADD STRING, hPopUp1, "Debug Off", %IDM_DEBUG_DEBUGOFF, %MF_ENABLED
9    MENU ATTACH hMenu, hDlg
10   FUNCTION = hMenu
11   TraceUnHandled                                                   'Macro for Local Variables and Unhandled Errors
END FUNCTION
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
'   ** CallBacks **
'--------------------------------------------------------------------------------
CALLBACK FUNCTION ShowDIALOG1Proc()
1    TraceVariables                                                   'Add To whatever function you want to debug (In this case most top-level possible)
2    SELECT CASE CBMSG
3         CASE %WM_COMMAND
4              SELECT CASE CBCTL
'*** For Run-Time Debugging of what you did not think of when originally writing your code
5                   CASE %IDM_DEBUG_DEBUGON
6                        StartTrace                                   'Start Tracing Functions
7                   CASE %IDM_DEBUG_DEBUGOFF
8                        EndTrace                                     'End Tracing Functions
9              END SELECT
10   END SELECT
11   TraceUnHandled                                                   'Macro for Local Variables and Unhandled Errors
END FUNCTION
'--------------------------------------------------------------------------------
'--------------------------------------------------------------------------------
'   ** Dialogs **
'--------------------------------------------------------------------------------
FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
1    TraceVariables                                                   'Add To whatever function you want to debug (In this case most top-level possible)
2    LOCAL lRslt AS LONG
3    LOCAL hDlg AS DWORD
4    DIALOG NEW hParent, "Dialog1", 72, 132, 189, 114, %WS_POPUP OR %WS_BORDER OR _
                    %WS_DLGFRAME OR %WS_CAPTION OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR _
                    %WS_MAXIMIZEBOX OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR _
                    %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_WINDOWEDGE OR _
                    %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
                    %WS_EX_RIGHTSCROLLBAR, TO hDlg
5    AttachMENU1 hDlg
6    DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt            'Show Modal to give a chance to turn debugging on or off
'*** Comment or Uncomment for which ever test you want to try (I left the line numbers conflicting in case your dont comment or uncomment correctly)
''*** PB ON ERROR Test
'7    ERROR 52                                                         'Bogus Error for Demo
''*** Windows API Error Test
'7   SetLastError(6)                                                   'Bogus Error for Demo
'8   LastErrorCheck                                                    'Macro for checking last error
''*** Windows EXCEPTION Test
7   RaiseException %EXCEPTION_BREAKPOINT, %NULL, %NULL, %NULL         'Bogus Fatal Error for Demo (or not fatal since I have control)
9     TraceUnHandled                                                 'Macro for Local Variables and Unhandled Errors
END FUNCTION
'--------------------------------------------------------------------------------
ErrorHandling.inc
Code:
'*** ErrorHandling.inc
'***      Written by: Cliff Nichols - 08-28-2008
'***      Modified by: Cliff Nichols - 09-18-2008
'***      Compiler: 8.04/9.0
'***      Should work on: 7/8/9
'***      Tested on: XP-Pro SP3, Vista-Ultimate
'***      Should work on: 95/98/ME/NT/2K/XP/Vista
'***      Purpose - Beefed up Error Handling Routines to attempt to "Bullet-Proof" apps
'*** Usage:
'***      StartTrace - Create a Trace log file
'***      TraceVariables - Common Variables for each function
'***
'***      TraceUnhandled - Steps for anything that you did not think of when writing and testing your code
'--------------------------------------------------------------------------------
'*** Now for the FUN Stuff
'***      PB has 'On Error' for handling errors on the DDT side
'***           PB can raise an error just by ERR = some number
'***      Windows has 'GetLastError' to check any errors via SDK
'***           Windows has to check for errors and handle them (errors are not raised)
'***      Windows has "Exceptions" (You've seen them...the default usually shows the typical "*.exe has encountered a problem and needs to close" message)
'***           Windows "Exceptions" can be raised, but default handler is typically fatal, but you can override that fatality
'*** I REALLLLLLY want to know how to do the below without visibly inserting numbers but.....
'***      PB Line numbers (if inserted) can assist in locating where an error occured (larger projects its smarter to contain line numbers to their functions)
'***      PB FUNCNAME$ in conjunction with the line numbers can nail down what line the error occured on
'***           Conjunction, junction, whats your function??? :-)
'*** What makes it all work????
'*** MACRO's baby, yeah baby yeah...(Finally got this one when larger code all had the same multiple commands and got tedious to type or copy/paste)
'*** Globals.....Real Men don't need no stinkin Globals :-) (Finally got this one working deep with Windows API...See "Parameter as Reply" discussion)
'--------------------------------------------------------------------------------

'*** If not already declared in your code, then declare this INC
#IF NOT %DEF(%ERRORHANDLING)
     %ERRORHANDLING = 1
'*** Globals
'***      NONE
'***           - Use SetGetDebugTraceRunning to keep value in replacement for a global DebugTraceRunning
'***           - Use SetGetLastFunction to keep value in replacement for a global LastFunction
'*** Constants
     %UNKNOWN_VALUE = -1
'*** Constants not found in Win32Api.Inc
     %EXCEPTION_ILLEGAL_INSTRUCTION  = &HC000001D
     %EXCEPTION_STACK_OVERFLOW       = &HC00000FD
'*************************************************************************************************************
'*** Macro's - When Compiled, replace the name of the macro with all the functions and processes in the macro
'***           As if you had done it yourself in each and every SUB/FUNCTION it was called
'***           Do not add line numbers to Macro's unless you want to renumber functions that use the macros
'*************************************************************************************************************
'*** TraceUnhandled
'***      Macro to replace code at the end of each function being being debugged
'***           Code will jump to end ON ERROR or if told to jump to end
'***           Code relies on TraceVariables to compile
'*************************************************************************************************************
     MACRO TraceUnhandled
          EXIT FUNCTION                                               'Exit to not Execute Function code again
     ErrHandler:
          ErrFunc = GetLastError                                      'Get API Last Error
          TraceLastError FUNCNAME$, ErrFunc, ERR, ERL
          SetUnhandledExceptionFilter %NULL
     END MACRO
'*************************************************************************************************************
'*** TraceVariables
'***      Macro to replace code at the begginning of each function being being debugged
'***           Code sets up variables to jump to end ON ERROR or if told to jump to end
'***           Code relies on TraceUnhandled to compile
'*************************************************************************************************************
     MACRO TraceVariables
          ON ERROR GOTO ErrHandler                                    'Avoid using error numbers higher than 240, as they are reserved for use in critical error situations which can never be trapped with ON ERROR.
          LOCAL DebugTraceRunning AS LONG                             'Variable for if debugging
          LOCAL LastErrorValue AS LONG                                'Variable for GetLastError
          LOCAL PbErrorValue AS LONG                                  'Variable for PB ERR
          LOCAL ErrorLineNumber AS LONG                               'Variable for line number where the error occured (or the last checked line)
          LOCAL ErrFunc AS LONG                                       'Variable for if there was an error in the function
          LOCAL ErrorBuff AS ASCIIZ * %MAX_PATH                       'Variable for Win32Api Error Description
          LOCAL WhatToTrace AS STRING                                 'Variable for what to log for an error
          SetLastError(0)                                             'Ensure the last Windows error is cleared
          ERRCLEAR                                                    'Ensure the last PB error is cleared
'          SetUnhandledExceptionFilter %EXCEPTION_EXECUTE_HANDLER      '<--- Use this exception handler if wanting to use windows default (the typical "*.exe has encountered a problem and needs to close" message)
          SetUnhandledExceptionFilter CODEPTR (TraceExceptionHandler) '<--- Use this exception handler if wanting to make a better crash-proof program
     END MACRO
'*************************************************************************************************************
'*** TraceOn
'***      Macro to replace code that would be blindly TRACE ON
'***           Code only turns the trace on if debugging
'***           Leaving a function will turn TRACE OFF by default (although I like to purposely call it to clean up after myself)
'*************************************************************************************************************
     MACRO TraceOn
          ErrFunc = SetGetDebugTraceRunning(%UNKNOWN_VALUE, DebugTraceRunning, %UNKNOWN_VALUE)      '<---Find out if debugging or not
          SELECT CASE DebugTraceRunning
               CASE 0                                                 'Not running a trace
               CASE ELSE
                    TRACE ON                                          'Turn on trace if debugging
          END SELECT
     END MACRO
'*************************************************************************************************************
'*** TraceOff
'***      Macro to replace code that would be default TRACE OFF
'***           Code only turns the trace off if debugging
'***           Leaving a function will turn TRACE OFF by default (although I like to purposely call it to clean up after myself)
'*************************************************************************************************************
     MACRO TraceOff                                                   '<--- Not needed if exiting function but I am a stickler
          ErrFunc = SetGetDebugTraceRunning(%UNKNOWN_VALUE, DebugTraceRunning, %UNKNOWN_VALUE)
          SELECT CASE DebugTraceRunning
               CASE 0                                                 'Not running a trace
               CASE ELSE
                    TRACE OFF                                         'Turn off trace if debugging
          END SELECT
     END MACRO
'*************************************************************************************************************
'*** LastErrorCheck
'***      Macro to replace code that would be multiple lines for Win32Api GetLastError
'***           Code only traces if debugging
'***           TraceLastError will decide if a Windows or a PB Error and log accordingly
'*************************************************************************************************************
     MACRO LastErrorCheck
          ErrFunc = GetLastError                                      'Get API Last Error
          TraceLastError FUNCNAME$, ErrFunc, ERR, ERL                 'Pass all known info to the function for logging
     END MACRO
'*************************************************************************************************************
'*** NOW FOR THE STANDARD INC SETUP
'*************************************************************************************************************
'*** Declares:
     DECLARE FUNCTION SetGetDebugTraceRunning(ValueToSet AS LONG, ValueResults AS LONG, ResetValue AS LONG) AS LONG
     DECLARE FUNCTION SetGetLastFunction(ValueToSet AS STRING, ValueResults AS STRING, ResetValue AS LONG) AS LONG
     DECLARE FUNCTION SetGetOverRideError(ValueToSet AS LONG, ValueResults AS LONG, ResetValue AS LONG) AS LONG
     DECLARE FUNCTION StartTrace() AS LONG
     DECLARE FUNCTION EndTrace() AS LONG
     DECLARE FUNCTION TraceProgramName(ParentAppName AS ASCIIZ * %MAX_PATH) AS LONG
     DECLARE FUNCTION TraceLastError(FunctionName AS STRING, LastErrorValue AS LONG, PbErrorValue AS LONG, ErrorLineNumber AS LONG) AS LONG
     DECLARE FUNCTION TracePrint(WhatToTrace AS STRING) AS LONG
     DECLARE FUNCTION TraceExceptionHandler(BYREF lpEP AS EXCEPTION_POINTERS) AS LONG
'*** Dependant Inc Files:
'***      None
'*** Functions:
'***      SetGetDebugTraceRunning Replaces the need for global variables so that local variables in other functions are easier to read
     FUNCTION SetGetDebugTraceRunning(ValueToSet AS LONG, ValueResults AS LONG, ResetValue AS LONG) AS LONG
1         TraceVariables                                              'Macro for Declaring variables for error checking
2         STATIC FunctionValue AS LONG                                'Static to hold current value
3         SELECT CASE ResetValue                                      'Decide whether to Set or to Get the current value
4              CASE %False, %UNKNOWN_VALUE                            'If set to False, or -1 Then Get Current Value
5                   ValueResults = FunctionValue                      'Return Results as a parameter
6              CASE = %TRUE                                           'If set to True then Reset the Current Value
7                   FunctionValue = ValueToSet                        'Reset the value
8                   ValueResults = FunctionValue                      'Return Results as a parameter
9         END SELECT
10        FUNCTION = %False                                           'Return if Function Failed
11        TraceUnhandled                                              'Exit Function or handle unhandled errors
     END FUNCTION
'*** SetGetLastFunction Replaces the need for global variables so that local variables in other functions are easier to read
     FUNCTION SetGetLastFunction(ValueToSet AS STRING, ValueResults AS STRING, ResetValue AS LONG) AS LONG
1         TraceVariables                                              'Macro for Declaring variables for error checking
2         STATIC FunctionValue AS STRING                              'Static to hold current value
3         SELECT CASE ResetValue                                      'Decide whether to Set or to Get the current value
4              CASE %False, %UNKNOWN_VALUE                            'If set to False, or -1 Then Get Current Value
5                   ValueResults = FunctionValue                      'Return Results as a parameter
6              CASE = %TRUE                                           'If set to True then Reset the Current Value
7                   FunctionValue = ValueToSet                        'Reset the value
8                   ValueResults = FunctionValue                      'Return Results as a parameter
9         END SELECT
10        FUNCTION = %False                                           'Return if Function Failed
11        TraceUnhandled                                              'Exit Function or handle unhandled errors
     END FUNCTION
'*** SetGetOverRideError Replaces the need for global variables so that local variables in other functions are easier to read
     FUNCTION SetGetOverRideError(ValueToSet AS LONG, ValueResults AS LONG, ResetValue AS LONG) AS LONG
1         TraceVariables                                              'Macro for Declaring variables for error checking
2         STATIC FunctionValue AS LONG                              'Static to hold current value
3         SELECT CASE ResetValue                                      'Decide whether to Set or to Get the current value
4              CASE %False, %UNKNOWN_VALUE                            'If set to False, or -1 Then Get Current Value
5                   ValueResults = FunctionValue                      'Return Results as a parameter
6              CASE = %TRUE                                           'If set to True then Reset the Current Value
7                   FunctionValue = ValueToSet                        'Reset the value
8                   ValueResults = FunctionValue                      'Return Results as a parameter
9         END SELECT
10        FUNCTION = %False                                           'Return if Function Failed
11        TraceUnhandled                                              'Exit Function or handle unhandled errors
     END FUNCTION
'*** Start Tracing
     FUNCTION StartTrace() AS LONG
1         TraceVariables                                              'Macro for Declaring variables for error checking
2         LOCAL TraceLogName AS ASCIIZ * %MAX_PATH
3         ErrFunc = TraceProgramName(TraceLogName)                    'Get a trace log name
4         SELECT CASE ErrFunc                                         'If no error creating the log
5              CASE %FALSE
6                   DebugTraceRunning = %TRUE                         'Set variable for if tracing
7                   TRACE NEW TraceLogName                            'Create the log
8              CASE ELSE                                              'Some Error Occurred
9         END SELECT
10        ErrFunc = SetGetDebugTraceRunning(%TRUE, DebugTraceRunning, %TRUE)    'Set the flag that we are tracing
11        TraceUnHandled                                              'Macro for Local Variables and Unhandled Errors
     END FUNCTION
'*** End Tracing
     FUNCTION EndTrace() AS LONG
1          TraceVariables                                             'Macro for common variables
2          LOCAL TraceLogName AS ASCIIZ * %MAX_PATH
3          ErrFunc = TraceProgramName(TraceLogName)                   'Get a trace log name
4          SELECT CASE ErrFunc                                        'If the trace log name exists (no error) then
5               CASE %FALSE
6                    DebugTraceRunning = %FALSE
7                    TRACE CLOSE                                      'Close Trace File
8               CASE ELSE                                             'Some Error Occurred
9          END SELECT
10          ErrFunc = SetGetDebugTraceRunning(%FALSE, DebugTraceRunning, %TRUE)      'Set the flag for we are no longer tracing
11          TraceUnHandled                                            'Macro for Local Variables and Unhandled Errors
     END FUNCTION
'*** Set up a log file name
     FUNCTION TraceProgramName(ParentAppName AS ASCIIZ * %MAX_PATH) AS LONG
1          LOCAL ErrFunc AS LONG
2          ErrFunc = GetModuleFileName(GetModuleHandle(BYVAL %NULL), ParentAppName, %MAX_PATH)       'Returns current path to owning parent
3          ParentAppName = MID$(ParentAppName, 1, INSTR(ParentAppName, ".exe") - 1)  'Strip all but the parent '.exe' part
4          ParentAppName = ParentAppName + " - Error Log.log"          'Append string to show an error log
5          SELECT CASE ErrFunc
6               CASE 0                                                 'Function Failed
7                    FUNCTION = ErrFunc
8               CASE ELSE                                              'Function Passed
9                    FUNCTION = %False
10          END SELECT
     END FUNCTION
'*** Trace Last Error (if any)
     FUNCTION TraceLastError(FunctionName AS STRING, LastErrorValue AS LONG, PbErrorValue AS LONG, ErrorLineNumber AS LONG) AS LONG
          LOCAL LastError AS LONG
          LOCAL WhatToTrace AS STRING
          LOCAL ErrFunc AS LONG
          LOCAL DebugTraceRunning AS LONG
          LOCAL ErrorBuff AS ASCIIZ * %MAX_PATH

          ERR = PbErrorValue                                          'PB Clears ERR at the end of functions so to preserve it I reset it
          SELECT CASE ERR                                             'Is it a PB Error?
               CASE 0                                                 'Not a PB Error
                    FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %NULL, LastErrorValue, %NULL, ErrorBuff, SIZEOF(ErrorBuff), BYVAL %NULL     'Format the message
                    WhatToTrace = $TAB + "Unhandled WindowsError - " + STR$(LastErrorValue) + " - " + ErrorBuff + $CRLF + $TAB + " Function = " + FunctionName + " at line: " + STR$(ErrorLineNumber)
               CASE ELSE                                              'PB Error
                    LastError = ERR
                    WhatToTrace = WhatToTrace + $CRLF + $TAB + "Unhandled PbError # " + STR$(ERR) + " - " + ERROR$ + $CRLF + $TAB + " Function = " + FunctionName + " at line: " + STR$(ErrorLineNumber)    '<--- ERL not quite working at this time
                    SELECT CASE LastError
                         CASE 0, %ERR_NOERROR                         'No Error
                         CASE 5, %ERR_ILLEGALFUNCTIONCALL             'Illegal function call
                         CASE 6, %ERR_OVERFLOW                        'Overflow                '<---This error is not currently supported.
                         CASE 7, %ERR_OUTOFMEMORY                     'Out of Memory
                         CASE 9, %ERR_SUBSCRIPTPOINTEROUTOFRANGE      'Subscript / Pointer out of range
                         CASE 11, %ERR_DIVISIONBYZERO                 'Division by zero         '<---This error is not currently supported.
                         CASE 24, %ERR_DEVICETIMEOUT                  'Device TimeOut for UDP or TCP communications
                         CASE 51, %ERR_INTERNALERROR                  'Internal Error
                         CASE 52, %ERR_BADFILENAMEORNUMBER            'Bad File Name or Number '<--- Also used for Serial Port Errors
                         CASE 53, %ERR_FILENOTFOUND                   'File not found
                         CASE 54, %ERR_BADFILEMODE                    'Bad File Mode
                         CASE 55, %ERR_FILEISOPEN                     'File is already open    '<--- Also used for Serial Port Errors
                         CASE 57, %ERR_DEVICEIOERROR                  'Device I/O Error        'Serial Port, TCP, UDP
                         CASE 58, %ERR_FILEALREADYEXISTS              'File already exists
                         CASE 61, %ERR_DISKFULL                       'Disk full
                         CASE 62, %ERR_INPUTPASTEND                   'Input past end
                         CASE 63, %ERR_BADRECORDNUMBER                'Bad record number
                         CASE 64, %ERR_BADFILENAME                    'Bad file name
                         CASE 67, %ERR_TOOMANYFILES                   'Too many files
                         CASE 68, %ERR_DEVICEUNAVAILABLE              'Device unavailable
                         CASE 69, %ERR_COMMERROR                      'COMM Error         '<---Serial Port Error
                         CASE 70, %ERR_PERMISSIONDENIED               'Permission Denied
                         CASE 71, %ERR_DISKNOTREADY                   'Disk not ready
                         CASE 72, %ERR_DISKMEDIAERROR                 'Disk media error
                         CASE 74, %ERR_RENAMEACROSSDISKS              'Rename across disks
                         CASE 75, %ERR_PATHFILEACCESSERROR            'Path/File access error
                         CASE 76, %ERR_PATHNOTFOUND                   'Path not found
                         CASE 99, %ERR_OBJECTERROR                    'Object error
                         CASE 241, %ERR_GLOBALMEMORYCORRUPT           'Global Memory Corrupt
                         CASE 242, %ERR_STRINGSPACECORRUPT            'String space corrupt
                         CASE ELSE                                    'Either a 'Compile-Time' error (handled by PB) or Unknown what to do so just exit the function
                    END SELECT
          END SELECT
          TraceOn                                                     'If debugging then trace
          TracePrint WhatToTrace                                      'If debugging then trace what?
     END FUNCTION
'*** Print to trace file if debugging
     FUNCTION TracePrint(WhatToPrint AS STRING) AS LONG
1         TraceVariables                                              'Macro for common variables
2         ErrFunc = SetGetDebugTraceRunning(%UNKNOWN_VALUE, DebugTraceRunning, %UNKNOWN_VALUE)      'Check if Debugging
3         SELECT CASE DebugTraceRunning
4              CASE 0                                                 'Not running a trace
5                   FUNCTION = DebugTraceRunning
6              CASE ELSE
                    TRACE ON
7                   TRACE PRINT WhatToPrint + $CRLF                   '<--- Chose string since I do not know what is to be printed + $CRLF for log file
8                   FUNCTION = %FALSE
9         END SELECT
10        TraceUnHandled                                              'Macro for Local Variables and Unhandled Errors
     END FUNCTION
'--------------------------------------------------------------------------------
'*** Now for the DOOZYYYYyyyy....Handling GPF's and other major fatal errors
'*** Commented fields are ones that I have no value for (yet) but MSDN say they exist
'--------------------------------------------------------------------------------
     FUNCTION TraceExceptionHandler(BYREF lpEP AS EXCEPTION_POINTERS) AS LONG
          STATIC TerminateInProcess AS LONG
          LOCAL ErrorRecord AS EXCEPTION_RECORD POINTER
          LOCAL ErrorCode AS LONG POINTER
          LOCAL WhatToTrace AS STRING
          LOCAL i AS LONG                                                  'For homing in on where the exception occurred
          LOCAL CallStackFunctions AS STRING                               'For homing in on where the exception occurred
          SELECT CASE TerminateInProcess                              'If Unloading due to error let the OS handle it.
               CASE %TRUE
                    SetUnhandledExceptionFilter %EXCEPTION_EXECUTE_HANDLER 'Reactivate default Error Handler
                    RaiseException %NULL, %NULL, %NULL, %NULL              'Force normal Error Handler
'*** Exit the thread (and application if this is the only thread)
                    ExitThread 0
               CASE %FALSE
                    TerminateInProcess = %TRUE
                    ErrorRecord = lpEP.pExceptionRecord                    'Detect the actual exception record
                    DO UNTIL @ErrorRecord.pExceptionRecord = 0             'Gather the exception record(s)
                         CALL MoveMemory(@ErrorRecord, @ErrorRecord.pExceptionRecord, SIZEOF(ErrorRecord))
                    LOOP
                    ErrorCode   = @ErrorRecord.ExceptionCode
'*** Now we have in ErrorCode the ExceptionCode, that raised the crash, log the info
                    SELECT CASE ErrorCode
                         CASE %EXCEPTION_ACCESS_VIOLATION
                              WhatToTrace =   "ACCESS VIOLATION" + " <---> " + "The thread tried to read from or write to a virtual address for which it does not have the appropriate access"
                         CASE %EXCEPTION_ARRAY_BOUNDS_EXCEEDED
                              WhatToTrace =   "ARRAY BOUNDS EXCEEDED" + " <---> " + "The thread tried to access an array element that is out of bounds and the underlying hardware supports bounds checking."
                         CASE %EXCEPTION_BREAKPOINT
                              WhatToTrace = "BREAKPOINT" + " <---> " + "A breakpoint was encountered."
                         CASE %EXCEPTION_DATATYPE_MISALIGNMENT
                              WhatToTrace =   "DATATYPE MISALIGNMENT" + " <---> " + "The thread tried to read or write data that is misaligned on hardware that does not provide alignment. For example, 16-bit values must be aligned on 2-byte boundaries"
                         CASE %EXCEPTION_FLT_DENORMAL_OPERAND
                              WhatToTrace =  "FLOAT DENORMAL OPERAND" + " <---> " + "One of the operands in a floating-point operation is denormal. A denormal value is one that is too small to represent as a standard floating-point value."
                         CASE %EXCEPTION_FLT_DIVIDE_BY_ZERO
                              WhatToTrace =  "FLOAT DIVISION BY ZERO" + " <---> " + "The thread tried to divide a floating-point value by a floating-point divisor of zero."
                         CASE %EXCEPTION_FLT_INEXACT_RESULT
                              WhatToTrace =  "FLOAT INEXACT RESULT" + " <---> " + "The result of a floating-point operation cannot be represented exactly as a decimal fraction."
                         CASE %EXCEPTION_FLT_INVALID_OPERATION
                              WhatToTrace =  "FLOAT INVALID OPERATION" + " <---> " + "This exception represents any floating-point exception not included in this list."
                         CASE %EXCEPTION_FLT_OVERFLOW
                              WhatToTrace =  "FLOAT OVERFLOW" + " <---> " + "The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type."
                         CASE %EXCEPTION_FLT_STACK_CHECK
                              WhatToTrace =  "FLOAT STACK CHECK" + " <---> " + "The stack overflowed or underflowed as the result of a floating-point operation."
                         CASE %EXCEPTION_FLT_UNDERFLOW
                              WhatToTrace =  "FLOAT UNDERFLOW" + " <---> " + "The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type."
                         CASE %EXCEPTION_ILLEGAL_INSTRUCTION
                              WhatToTrace =  "ILLEGAL INSTRUCTION" + " <---> " + "The thread tried to execute an invalid instruction."
                         CASE %EXCEPTION_IN_PAGE_ERROR
                              WhatToTrace = "IN PAGE ERROR" + " <---> "
                              WhatToTrace = WhatToTrace + "The thread tried to access a page that was not present, and the system was unable to load the page."
                              WhatToTrace = WhatToTrace + "For example, this exception might occur if a network connection is lost while running a program over "
                              WhatToTrace = WhatToTrace + "the network."
                         CASE %EXCEPTION_INT_DIVIDE_BY_ZERO
                              WhatToTrace =   "INTEGER DIVISION BY ZERO" + " <---> " + "The thread tried to divide an integer value by an integer divisor of zero."
                         CASE %EXCEPTION_INT_OVERFLOW
                              WhatToTrace =   "INTEGER OVERFLOW" + " <---> " + "The result of an integer operation caused a carry out of the most significant bit of the result."
'                         CASE %EXCEPTION_INVALID_DISPOSITION
'                              WhatToTrace =   "INVALID DISPOSITION" + " <---> " + "An exception handler returned an invalid disposition to the exception dispatcher. Programmers using a high-level language such as C should never encounter this exception."
'                         CASE %EXCEPTION_NONCONTINUABLE_EXCEPTION
'                              WhatToTrace =   "NONCONTINUABLE EXCEPTION" + " <---> " + "The thread tried to continue execution after a noncontinuable exception occurred."
                         CASE %EXCEPTION_PRIV_INSTRUCTION
                              WhatToTrace =   "PRIVATE INSTRUCTION" + " <---> " + "The thread tried to execute an instruction whose operation is not allowed in the current machine mode."
                         CASE %EXCEPTION_SINGLE_STEP
                              WhatToTrace =   "SINGLE STEP" + " <---> " + "A trace trap or other single-instruction mechanism signaled that one instruction has been executed."
                         CASE %EXCEPTION_STACK_OVERFLOW
                              WhatToTrace =  "STACK OVERFLOW" + " <---> " + "The thread used up its stack."
                         CASE ELSE
                              WhatToTrace =  CHR$(0)
                    END SELECT
                    FOR i = CALLSTKCOUNT TO CALLSTKCOUNT - 1 STEP -1
'                    CallStackFunctions = CallStackFunctions + CALLSTK$(i)
                         CallStackFunctions = CALLSTK$(i)
                    NEXT i
'*** Code for writing a crash-log, save opened documents etc...
                    WhatToTrace = $TAB + "Unhandled WindowsException - " + STR$(@ErrorRecord.ExceptionCode) + " - " + WhatToTrace + $CRLF + $TAB + " Function = " + CallStackFunctions + " at line: " + STR$(ERL)
                    TracePrint WhatToTrace
'*** Exit the thread (and application if this is the only thread)
                    ExitThread 0                  'This will stop the typical "*.exe has encountered a problem and needs to close" error message to send a report to M$
          END SELECT
     END FUNCTION
#ENDIF
Any Errors or things I missed, let me know inRaising Errors for Testing
Attached Files