Fixed StripPrefix; refactored ColumnClass instantiation so it happens inside new StripedList local method; changed to make base class dispose of objects; improved column width measurement; removed redundant PROPLIST assignments; and removed old dead COMPILE/OMIT statements need for pre-C6.

                              MEMBER()
!==============================================================================
!If all fields begin with the same prefix, then you can have that auto-stripped
!by uncommenting the following line.
E_StripPrefix                 EQUATE(1)
!==============================================================================
!This controls the max number of characters used to auto-size column width.  You can still resize width manually.
E_EnoughCharacters            EQUATE(25)
!==============================================================================
WidthMultiplier:Narrow        EQUATE(5)  !normal columns (numbers, lowercase, etc.)
WidthMultiplier:Wide          EQUATE(7)  !uppercase columns
DebugQueueCallingItself       BOOL(FALSE)
!==============================================================================
  INCLUDE('Equates.clw')
  INCLUDE('Errors.clw')
  INCLUDE('UltimateDebug.inc'),ONCE
  INCLUDE('UltimateVLB.inc'),ONCE
! ToDo _wsldebug$setlogfile

                              MAP
                                module('kernel')
!see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/debugging_functions.asp
                                  debugbreak(),PASCAL !,RAW,NAME('debugbreak')
                                  OutputDebugString(*CSTRING),PASCAL,RAW,NAME('OutputDebugStringA')
                                end
                                MODULE('C%V%RUN%X%')
                                  debugerNameMessage (*CSTRING, UNSIGNED EventNum ),RAW,NAME('WslDebug$NameMessage')   !Note: use   Event() + EVENT:FIRST  else will get WM_*
                                  COMPILE('** C55+ **',_C55_)
                                  debugerGetFieldName(SIGNED FEQ            ),*CSTRING,RAW,NAME('Cla$FIELDNAME')
                                  !END-COMPILE('** C55+ **',_C55_)
                                  OMIT('** C55+ **',_C55_)
                                  debugerGetFieldName(SIGNED FEQ            ),LONG,RAW,NAME('Cla$FIELDNAME')
                                  !END-OMIT('** C55+ **',_C55_)
                                END
                                !INCLUDE('STDebug.inc')
                              END

!OMIT('_ifdef_',EVENT:APP=08000h)
  COMPILE('_ifdef_',EVENT:APP=0)
EVENT:APP                     EQUATE(08000h)
EVENT:APP_LAST                EQUATE(0BFFFh)
  !END_COMPILE('_ifdef_',EVENT:APP=0)
!==============================================================================

!-----------------------------------
UltimateDebug.Init            PROCEDURE()
!-----------------------------------

  CODE

  RETURN

!-----------------------------------
UltimateDebug.Kill            PROCEDURE()
!-----------------------------------

  CODE

  RETURN

!-----------------------------------------
UltimateDebug.AddCategoryToDebug  PROCEDURE(STRING pCategory)
!-----------------------------------------

  CODE

  SELF.CategoryQueue.Category = pCategory
  GET(SELF.CategoryQueue,SELF.CategoryQueue.Category)
  IF ERROR()
    ADD(SELF.CategoryQueue,SELF.CategoryQueue.Category)
  END

!!!-----------------------------------------
!!UltimateDebug.Debug             PROCEDURE(STRING pCategory,STRING pDebugString)
!!!-----------------------------------------
!!
!!	CODE
!!
!!	SELF.CategoryQueue.Category = pCategory
!!	GET(SELF.CategoryQueue,SELF.CategoryQueue.Category)
!!	IF ERRORCODE() = NoError
!!		SELF.Debug('[' & CLIP(pCategory) & ']' & pDebugString)
!!	END
!!
!!	RETURN
!-----------------------------------------
UltimateDebug.Debug           PROCEDURE(STRING pDebugString,<STRING pCustomPrefix>,BYTE pNoClip = 0)
!-----------------------------------------
ASC1:ASCIIFile                  FILE,PRE(ASC1),DRIVER('ASCII'),NAME(GlobalASCIIFileName),CREATE
RECORD                            RECORD,PRE()
STRING                              STRING(512)
                                  END
                                END

lc_CDebugString                 STRING(10000)
lc_COutDebugString              STRING(10000)
lc_Temp                         STRING(10000)
ll_Count                        LONG
ll_End                          LONG
lb_Flag                         BYTE(FALSE)
lb_FirstTime                    BYTE(TRUE)
lb_FirstLoop                    BYTE(0)
ll_StringPosition               LONG

  CODE
  IF SELF.DebugOff AND ~SELF.SaveToFile;RETURN.

  GlobalASCIIFileName = SELF.ASCIIFileName
  IF SELF.SaveToFile
    IF ~EXISTS(ASC1:ASCIIFile{PROP:Name})
      CREATE(ASC1:ASCIIFile)
    END
    OPEN(ASC1:ASCIIFile)
  END
  ll_Count = 1
  IF SELF.DebugNoCR
    lc_CDebugString = CLIP(pDebugString)
    IF ~SELF.DebugOff
      SELF.SendOutputToDebug(lc_CDebugString,pCustomPrefix,pNoClip)
    END
    IF SELF.SaveToFile
      ASC1:String = '[' & FORMAT(TODAY(),@D17) & '-' & FORMAT(CLOCK(),@T7) & ']- ' & lc_CDebugString
      ADD(ASC1:ASCIIFile)
    END
  ELSE
    IF LEN(CLIP(pDebugString)) = 0
      IF SELF.SaveToFile
        ASC1:String = '[' & FORMAT(TODAY(),@D17) & '-' & FORMAT(CLOCK(),@T7) & ']'
        ADD(ASC1:ASCIIFile)
      END
      IF ~SELF.DebugOff
        lc_COutDebugString = ''
        SELF.SendOutputToDebug(lc_COutDebugString,pCustomPrefix,pNoClip)
      END
    ELSE

      Loop Until lb_Flag
        If Len(Clip(pDebugString)) - ll_Count < 9999 Then
          ll_end = Len(Clip(pDebugString))
          lb_Flag = True
        Else
          ll_end = ll_Count + 9998
        End
        lc_CDebugString = CLIP(pDebugString[ll_Count : ll_end])

        ll_Count = ll_end + 1
        LOOP
          ll_StringPosition = INSTRING('<13>',lc_CDebugString,1,1)

          IF ll_StringPosition
            lc_COutDebugString = SUB(lc_CDebugString,1,ll_StringPosition - 1)
            lc_CDebugString = SUB(lc_CDebugString,ll_StringPosition + 2,10000)
            IF SELF.SaveToFile
              ASC1:String = '[' & FORMAT(TODAY(),@D17) & '-' & FORMAT(CLOCK(),@T7) & ']- ' & lc_COutDebugString
              ADD(ASC1:ASCIIFile)
            END
            IF ~SELF.DebugOff
              SELF.SendOutputToDebug(lc_COutDebugString,pCustomPrefix,pNoClip)
            END

            lb_FirstLoop = TRUE
            CYCLE
          END
          IF SELF.SaveToFile
            ASC1:String = '[' & FORMAT(TODAY(),@D17) & '-' & FORMAT(CLOCK(),@T7) & ']- ' & lc_CDebugString
            ADD(ASC1:ASCIIFile)
          END
          IF ~SELF.DebugOff
            SELF.SendOutputToDebug(lc_CDebugString,pCustomPrefix,pNoClip)
          END
          BREAK
        END
      END
    END
  END
  IF SELF.SaveToFile
    CLOSE(ASC1:ASCIIFile)
  END

!-----------------------------------------------------------------------------------------!
UltimateDebug.SendOutputToDebug   PROCEDURE(STRING pOutput,<STRING pCustomPrefix>,BYTE pNoClip = 0)
!-----------------------------------------------------------------------------------------!

lc_CDebugString                     CSTRING(10000)
lc_COutDebugString                  CSTRING(10000)
lc_Temp                             CSTRING(10000)
Count                               LONG(0)

  CODE

  IF pNoClip
    lc_COutDebugString = CLIP(SELF.DebugPrefix) & pOutput
    OutputDebugString(lc_COutDebugString)
  ELSE
    lc_CDebugString =  CLIP(pOutput)

    LOOP
      Count += 1
      IF LEN(CLIP(lc_CDebugString)) > 160
        IF Count > 1
          lc_COutDebugString = '   ' & lc_CDebugString[1:160]
        ELSE
          lc_COutDebugString = lc_CDebugString[1:160]
        END
        lc_CDebugString = SUB(lc_CDebugString,161,10000)

      ELSE
        lc_COutDebugString = lc_CDebugString
        lc_CDebugString = ''
      END

      lc_COutDebugString = CLIP(SELF.DebugPrefix) & ' ' & CLIP(pCustomPrefix) & ' ' & CLIP(lc_COutDebugString)
      OutputDebugString(lc_COutDebugString)

      IF LEN(CLIP(lc_CDebugString)) = 0
        BREAK
      END

    END

  END

!-----------------------------------------------------------------------------------------!
UltimateDebug.ClearDebugView  PROCEDURE()   !Requires Debugview 4.3 or greater
!-----------------------------------------------------------------------------------------!
!From:  http://www.sysinternals.com/ntw2k/freeware/debugview.shtml
!       Clear-output string: When DebugView sees the special debug output string "DBGVIEWCLEAR" it clears the output.

!Note: If this doesn't appear to work, then you are either:
!          a) using an older version of debugview
!       OR b) you are filtering the message

  CODE

  SELF.Debug('DBGVIEWCLEAR')

!==============================================================================
UltimateDebug.DebugRecord     PROCEDURE(*FILE pFile,STRING pMsg)
!--------------------------------------
G                               &GROUP
!--------------------------------------
  CODE
  IF SELF.DebugOff;RETURN.
  COMPILE('!ENDCOMPILE', ST::DEBUG:Debugging=1)
  G &= pFile{PROP:Record}
  SELF.DebugGroup(G,, pMsg, 'Record')
  !ENDCOMPILE
  RETURN
!==============================================================================
UltimateDebug.DebugRecord     PROCEDURE(*FILE pFile,*FILE pFile2,STRING pMsg)
!--------------------------------------
G1                              &GROUP
G2                              &GROUP
!--------------------------------------
  CODE
  IF SELF.DebugOff;RETURN.
  COMPILE('!ENDCOMPILE', ST::DEBUG:Debugging=1)
  G1 &= pFile{PROP:Record}
  G2 &= pFile2{PROP:Record}
  SELF.DebugGroup(G1, G2, pMsg, 'Record')
  !ENDCOMPILE
  RETURN
!==============================================================================
UltimateDebug.DebugGroup      PROCEDURE(*GROUP pGroup,STRING pMsg,<STRING pStructureType>)
!--------------------------------------
  CODE
  IF SELF.DebugOff;RETURN.
  COMPILE('!ENDCOMPILE', ST::DEBUG:Debugging=1)
  SELF.DebugGroup(pGroup,, pMsg)
  !ENDCOMPILE
  RETURN
!==============================================================================
UltimateDebug.DebugGroup      PROCEDURE(*GROUP pGroup,<*GROUP pGroup2>,STRING pMsg,<STRING pStructureType>)
!--------------------------------------
epGroup2                        EQUATE(2)
SavePointer                     LONG,AUTO
NumFields                       SHORT(0)
NumFields2                      SHORT(0)
FieldQ                          QUEUE
Name                              CSTRING(100)
Value                             CSTRING(1000)
Value2                            CSTRING(1000)
                                END
MsgLineQ                        QUEUE
Text                              STRING(100)
                                END
!--------------------------------------
Window                          WINDOW('Debug'),AT(,,676,416),FONT('Tahoma',8,,),CENTER,SYSTEM,GRAY,DOUBLE
                                  LIST,AT(4,4,668,356),USE(?DebugList),VSCROLL,FORMAT('125L(2)|M~Field Name~S(1)@S100@180L(2)|M~Value~S(1)@S255@1000L(2)|M~Value2~S(1)@' &|
                                      'S255@'),FROM(FieldQ)
                                  LIST,AT(4,364,668,48),USE(?MessageList),VSCROLL,FROM(MsgLineQ)
                                END
!--------------------------------------
  CODE
  IF SELF.DebugOff;RETURN.
  COMPILE('!ENDCOMPILE', ST::DEBUG:Debugging=1)
  DO LoadFieldQ
  !--- Prepare window
  OPEN(Window)
  IF OMITTED(epGroup2)
    ?DebugList{PROPLIST:Width, 2} = 1000
  END
  0{PROP:Text} = 0{PROP:Text} &' '& CHOOSE(pStructureType='', 'Group', pStructureType) &' ('& NumFields &' Fields)'
  IF pMsg
    SELF.FormatMessageList(pMsg, MsgLineQ)
  ELSE
    HIDE(?MessageList)
    ?DebugList{PROP:Height} = ?DebugList{PROP:Height} + ?MessageList{PROP:Height} + 4
  END
  !--- Display window
  ACCEPT
  END
  !ENDCOMPILE
  RETURN
!======================================
LoadFieldQ                    ROUTINE
!--------------------------------------
  DATA
F   ANY                  !Field reference for value assignment
X   SHORT,AUTO
M   SHORT(0)
!--------------------------------------
  CODE
  OMIT('!+++!!!+++!')
  LOOP X = 10000 TO 1 BY -1
    IF NumFields = 0 AND WHO(pGroup, X) <> ''
      NumFields = X
      IF M = 0
        M = NumFields
      END
    END
    IF NOT OMITTED(epGroup2)  |
        AND NumFields2 = 0 AND WHO(pGroup2, X) <> ''
      NumFields2 = X
      IF M = 0
        M = NumFields2
      END
    END
    IF M = 0 AND (NumFields OR NumFields2)
      M = X
    END
    IF NumFields AND (OMITTED(epGroup2) OR NumFields2)
      BREAK
    END
  END
  LOOP X = 1 TO M
    CLEAR(FieldQ)
    IF NumFields >= X
      FieldQ.Name   = WHO(pGroup, X)
      F            &= WHAT(pGroup, X, 1)
      FieldQ.Value  = F
      IF NumFields2 >= X
        DO AssignValue2
      END
    ELSE
      FieldQ.Name   = WHO(pGroup2, X)
      DO AssignValue2
    END
    ADD(FieldQ)
    ASSERT(ERRORCODE()=0)
  END
  !+++!!!+++!
  EXIT
!======================================
AssignValue2                  ROUTINE
!--------------------------------------
  OMIT('!+++!!!+++!')
  F            &= WHAT(pGroup2, X, 1)
  FieldQ.Value2 = F
  !+++!!!+++!
  EXIT
!==============================================================================
UltimateDebug.DebugQueue      PROCEDURE(*QUEUE pQueue,<STRING pMsg>,<BYTE pNoTouch>)
                              MAP
LoadFieldQ                      PROCEDURE
CalculateColumnWidths           PROCEDURE
                              END
!--------------------------------------
SavePointer                     LONG,AUTO
NumFields                       SHORT,AUTO
                                COMPILE('***---***', E_StripPrefix)
StripPrefixLength               BYTE(0)
                                ***---***
StripedList                     CLASS(UltimateVLB)
AddColumn                         PROCEDURE(*? FieldRef,STRING Header,STRING Picture,SHORT Width,STRING Justification),*UltVLB:ColumnClass,PROC
                                END
DummyColumn                     STRING(1)
FieldQ                          QUEUE
ColumnObject                      &UltVLB:ColumnClass
Width                             LONG
IsDataUpper                       BOOL
IsDataNumeric                     BOOL
IsGroup                           BOOL
HeaderLength                      LONG
DataLength                        LONG
Header                            CSTRING(100)
                                END
MsgLineQ                        QUEUE
Text                              STRING(1000)
                                END
!--------------------------------------
Window                          WINDOW('Debug Queue'),SYSTEM,AT(,,676,416),CENTER,FONT('Tahoma', 8),GRAY,DOUBLE
                                  LIST, AT(4,4,668,356), USE(?DebugList), HVSCROLL
                                  LIST, AT(4,364,668,48), USE(?MessageList), VSCROLL, FROM(MsgLineQ)
                                END
!--------------------------------------
  CODE
  IF SELF.DebugOff;RETURN.
  !ST::Debug('ST::DebugQueue/IN')
  COMPILE('!ENDCOMPILE', ST::DEBUG:Debugging=1)
  IF pQueue &= NULL
    MESSAGE('Queue passed to ST::DebugQueue was a NULL pointer!', 'Debug Queue')
  ELSE
    !--- Save current queue pointer
    SavePointer = CHOOSE(RECORDS(pQueue)=0, 0, POINTER(pQueue))
    !--- Scan passed queue
    DO FindLastField
    IF NumFields = 0
      MESSAGE('Queue passed to ST::DebugQueue has no fields!', 'Debug Queue')
    ELSE
      LoadFieldQ
      COMPILE('***---***', E_StripPrefix)
      DO CheckStripPrefix
      ***---***
      CalculateColumnWidths
      !--- Prepare window
      OPEN(Window)
      0{PROP:Text} = 0{PROP:Text} &' ('& NumFields &' Fields, '& RECORDS(pQueue) &' Records)'
      DO FormatFieldList
      IF pMsg
        SELF.FormatMessageList(pMsg, MsgLineQ)
      ELSE
        HIDE(?MessageList)
        ?DebugList{PROP:Height} = ?DebugList{PROP:Height} + ?MessageList{PROP:Height} + 4
      END
      StripedList.Init(?DebugList, pQueue)
      SELF.Debug(?DebugList{PROP:Format})
      ?DebugList{PROP:Selected} = SavePointer
      IF NOT DebugQueueCallingItself
        DebugQueueCallingItself = TRUE
        !SELF.DebugQueue(FieldQ)
        DebugQueueCallingItself = FALSE
      END
      !--- Display window
      ACCEPT
      END
      !--- Restore queue pointer
      IF SavePointer <> 0 AND pNoTouch <> 1
        GET(pQueue, SavePointer)
      END
    END
  END
  FREE(FieldQ)
  !ENDCOMPILE
  !ST::Debug('ST::DebugQueue/OUT')

!======================================
FindLastField                 ROUTINE
!--------------------------------------
  NumFields = 5000
  LOOP WHILE NumFields > 0  |
      AND   WHO(pQueue, NumFields) = ''
    NumFields -= 1
  END
  ASSERT(NumFields > 0)

!**************************************
  COMPILE('***---***', E_StripPrefix)
!======================================
CheckStripPrefix              ROUTINE
!--------------------------------------
  DATA
FieldNo LONG,AUTO
PrefixFound CSTRING(20)
!--------------------------------------
  CODE
  LOOP FieldNo = 1 TO NumFields
    FieldQ.Header = WHO(pQueue, FieldNo)

    StripPrefixLength = INSTRING(':', FieldQ.Header)
    IF StripPrefixLength > 0
      IF FieldNo = 1
        PrefixFound = FieldQ.Header[1:StripPrefixLength]
      ELSIF FieldQ.Header[1:StripPrefixLength] <> PrefixFound
        StripPrefixLength = 0
        BREAK
      END
    ELSIF PrefixFound
      StripPrefixLength = 0
      BREAK
    END
  END
  IF StripPrefixLength > 0
    LOOP FieldNo = 1 TO NumFields
      GET(FieldQ, FieldNo)
      FieldQ.Header        = SUB(FieldQ.Header, StripPrefixLength+1, LEN(CLIP(FieldQ.Header))-StripPrefixLength)
      FieldQ.HeaderLength -= StripPrefixLength
      PUT(FieldQ)
    END
  END
  ***---***

!======================================
FormatFieldList               ROUTINE
!--------------------------------------
  DATA
FieldNo LONG,AUTO
ColumnNo    SHORT(0)
!--------------------------------------
  CODE
  !?DebugList{PROP:From} = pQueue
  LOOP FieldNo = 1 TO NumFields
    GET(FieldQ, FieldNo)
    IF FieldQ.IsGroup
      CYCLE
    END
    ColumnNo += 1
    ?DebugList{PROPLIST:RightBorder+PROPLIST:Group, ColumnNo} = 1

    FieldQ.ColumnObject &= StripedList.AddColumn( |
        WHAT(pQueue, FieldNo), |
        FieldQ.Header, |
        '@S'& FieldQ.DataLength, |
        FieldQ.Width, |
        CHOOSE(~FieldQ.IsDataNumeric, UltVLB:Justify:Left, UltVLB:Justify:Right))
    PUT(FieldQ)
  END
  StripedList.AddColumn(DummyColumn, '', '@S1', 1, UltVLB:Justify:Left)
  !ST::DebugQueue(FieldQ, 'FormatFieldList')

!======================================
StripedList.AddColumn         PROCEDURE(*? FieldRef,STRING Header,STRING Picture,SHORT Width,STRING Justification)!,*UltVLB:ColumnClass
!--------------------------------------
ColumnObj                       &UltVLB:ColumnClass
!--------------------------------------
  CODE
  ColumnObj              &= NEW UltVLB:ColumnClass
  ColumnObj.FieldRef     &= FieldRef
  ColumnObj.Header        = Header
  ColumnObj.Picture       = Picture
  ColumnObj.Width         = Width
  ColumnObj.Justification = Justification
  IF ColumnObj.Justification = UltVLB:Justify:Right
    ColumnObj.HJustification = UltVLB:Justify:Center
    ColumnObj.HOffset        = 0
  END
  SELF.AddColumn(ColumnObj, TRUE)  !TRUE tells it to DISPOSE for us.
  RETURN ColumnObj

!======================================
LoadFieldQ                    PROCEDURE
!--------------------------------------
FieldNo                         LONG,AUTO
FieldRef                        ANY
RecNo                           LONG,AUTO
SampleLength                    LONG,AUTO
IsDataEmpty                     BOOL,AUTO
!--------------------------------------
  CODE
  !ST::Debug('ST::DebugQueue/LoadFieldQ/IN: NumFields='& NumFields)
  LOOP FieldNo = 1 TO NumFields
    CLEAR(FieldQ)
    !ST::Debug('ST::DebugQueue/LoadFieldQ: FieldNo='& FieldNo)
    FieldQ.Header                  = LOWER(WHO(pQueue, FieldNo))
    FieldQ.HeaderLength            = LEN(FieldQ.Header)
    IF FieldQ.HeaderLength < 1
      FieldQ.HeaderLength          = 1
    END
    FieldRef                      &= WHAT(pQueue, FieldNo, 1)
    IsDataEmpty                    = TRUE
    FieldQ.IsDataNumeric           = TRUE
    FieldQ.IsDataUpper             = FALSE
    FieldQ.IsGroup                 = ISGROUP(pQueue, FieldNo)
    !ST::Debug('ST::DebugQueue/LoadFieldQ: RECORDS(pQueue)='& RECORDS(pQueue))
    IF RECORDS(pQueue) > 0 AND pNoTouch <> 1
      FieldQ.DataLength            = 0
      LOOP RecNo = 1 TO RECORDS(pQueue)
        GET(pQueue, RecNo)
        !ST::Debug('ST::DebugQueue/LoadFieldQ: RecNo='& RecNo &'; FieldRef='& FieldRef)
        IF FieldRef <> ''
          IF NOT NUMERIC(FieldRef)
            FieldQ.IsDataNumeric   = FALSE
          END
          IF FieldRef <> ''
            IsDataEmpty            = FALSE
          END
          SampleLength = LEN(CLIP(FieldRef))
          IF NOT FieldQ.IsDataNumeric AND UPPER(FieldRef) = FieldRef
            FieldQ.IsDataUpper     = TRUE
          END
          IF SampleLength > E_EnoughCharacters
            SampleLength           = E_EnoughCharacters
          END
          IF SampleLength > FieldQ.DataLength
            FieldQ.DataLength      = SampleLength
          END
        END
      END
      IF IsDataEmpty
        FieldQ.IsDataNumeric       = FALSE
      END
    ELSE
      FieldQ.IsDataNumeric         = FALSE
      FieldQ.IsDataUpper           = TRUE
      FieldQ.DataLength            = LEN(FieldRef)
    END
    ADD(FieldQ)
  END
  !ST::DebugQueue(FieldQ, 'LoadFieldQ')
  !ST::Debug('ST::DebugQueue/LoadFieldQ/OUT')

!======================================
CalculateColumnWidths         PROCEDURE
!--------------------------------------
FieldNo                       LONG,AUTO
HeaderWidth                   SHORT,AUTO
DataWidth                     SHORT,AUTO
!--------------------------------------
  CODE
  !ST::Debug('ST::DebugQueue/LoadFieldQ/IN: NumFields='& NumFields)
  LOOP FieldNo = 1 TO NumFields
    GET(FieldQ, FieldNo)
    DataWidth    = FieldQ.DataLength   * CHOOSE(~FieldQ.IsDataUpper, WidthMultiplier:Narrow, WidthMultiplier:Wide) + 2*UltVLB:Offset:Data
    HeaderWidth  = FieldQ.HeaderLength *                             WidthMultiplier:Narrow                        + 2*UltVLB:Offset:Header
    FieldQ.Width = CHOOSE(DataWidth > HeaderWidth, DataWidth, HeaderWidth)
    IF FieldQ.Width < 8 THEN FieldQ.Width = 8.
    !SELF.Debug(FieldQ.Header &' - '& FieldQ.HeaderLength &' - '& FieldQ.DataLength &' - '& HeaderWidth &' - '& DataWidth &' - '& FieldQ.Width)
    PUT(FieldQ)
  END
  !ST::DebugQueue(FieldQ, 'CalculateColumnWidths')

!==============================================================================
UltimateDebug.Message         PROCEDURE(STRING pDebugString)

  CODE
  SELF.Debug(pDebugString)

!==============================================================================

UltimateDebug.SetApplicationName  PROCEDURE(STRING pApplicationName,STRING pProgramExtension)    !,STRING

ApplicationName                     STRING(50)

  CODE
  CASE (pProgramExtension)
  OF ('EXE')
    ApplicationName = 'Application  <9>' & pApplicationName & '.EXE'
  OF ('DLL')
    ApplicationName = 'DLL          <9>' & pApplicationName & '.DLL'
  OF ('LIB')
    ApplicationName = 'Library      <9>' & pApplicationName & '.LIB'
  END

  RETURN ApplicationName

!==============================================================================

UltimateDebug.SetShortApplicationName PROCEDURE(STRING pApplicationName,STRING pProgramExtension)    !,STRING

ApplicationName                         STRING(50)

  CODE
  CASE (pProgramExtension)
  OF ('EXE')
    ApplicationName = pApplicationName & '.EXE'
  OF ('DLL')
    ApplicationName = pApplicationName & '.DLL'
  OF ('LIB')
    ApplicationName = pApplicationName & '.LIB'
  END

  RETURN ApplicationName
!==============================================================================
UltimateDebug.ShowProcedureInfo   PROCEDURE(STRING pProcedure,STRING pApplication,STRING pHelpID,STRING pCreated,STRING pModified,STRING pCompiled)

TheStats                            STRING(500)

Window                              WINDOW('Procedure Information'),AT(,,275,121),CENTER,GRAY
                                      GROUP('Procedure Information'),AT(3,8,190,102),USE(?GROUP1),BOXED
                                      END
                                      TEXT,AT(11,20,176,84),USE(TheStats),SKIP,TRN
                                      BUTTON('Send To Clipboard'),AT(198,61,72),USE(?BUTTONToClipboard)
                                      BUTTON('Send To Debug'),AT(198,78,72),USE(?BUTTONToDebug)
                                      BUTTON('Close'),AT(198,96,72),USE(?BUTTONClose)
                                    END

  CODE
  LOOP WHILE KEYBOARD() !Empty the keyboard buffer
    ASK                  !without processing keystrokes
  END
  SETKEYCODE(0)
  TheStats = ('Procedure:<9>' & CLIP(pProcedure) & '<13,10>' & |
      CLIP(pApplication) & '<13,10><13,10>' & |
      'Help ID    <9>' & CLIP(pHelpID) & '<13,10>' & |
      'Created  On<9>' & CLIP(pCreated) & '<13,10>' & |
      'Modified On<9>' & CLIP(pModified) & '<13,10>' & |
      'Compiled On<9>' & CLIP(pCompiled))
  OPEN(Window)
  ACCEPT
    CASE FIELD()
    OF ?BUTTONClose
      CASE EVENT()
      OF EVENT:Accepted
        BREAK
      END
    OF ?BUTTONToClipboard
      CASE EVENT()
      OF EVENT:Accepted
        SETCLIPBOARD(TheStats)
      END
    OF ?BUTTONToDebug
      CASE EVENT()
      OF EVENT:Accepted
        Self.Debug(TheStats)
      END
    END

  END

  LOOP WHILE KEYBOARD() !Empty the keyboard buffer
    ASK                  !without processing keystrokes
  END
  SETKEYCODE(0)
!==============================================================================
UltimateDebug.FormatMessageList   PROCEDURE(STRING pMsg,*QUEUE pMsgQueue)

!--------------------------------------
StartPos                            LONG(1)
Pos                                 LONG,AUTO
!--------------------------------------
  CODE
  IF pMsg
    LOOP WHILE StartPos
      Pos = INSTRING('|', pMsg, 1, StartPos)
      pMsgQueue = CHOOSE(Pos=0, pMsg[StartPos : LEN(pMsg)], pMsg[StartPos : Pos-1])
      ADD(pMsgQueue)
      ASSERT(ERRORCODE()=0)
      StartPos = Pos+1
    UNTIL Pos = 0
  END
  RETURN
!==============================================================================
!==============================================================================
UltimateDebug.Construct       PROCEDURE

  CODE

  SELF.EventQ        &= NEW ST::DebugEventQueue
  SELF.IgnoreEventQ  &= NEW ST::DebugEventQueue
  SELF.CategoryQueue &= NEW DebugCategoryQueue

  SELF.SetPurgeTime(5*60*100)  !5 minutes
  SELF.SetEventOffset

  SELF.ShowAll        = TRUE
  SELF.ShowField      = FALSE
  SELF.ShowFocus      = FALSE
  SELF.ShowSelected   = FALSE
  SELF.ShowSelStart   = FALSE
  SELF.ShowSelEnd     = FALSE
  SELF.ShowKeyCode    = FALSE
  SELF.ShowError      = FALSE
  SELF.ShowThread     = FALSE
  SELF.ShowContents   = FALSE
  SELF.ShowScreenText = FALSE
  SELF.ShowAcceptAll  = FALSE

!    REGISTER(EVENT:AlertKey,ADDRESS(SELF.ShowProcedureInfo),ADDRESS(SELF))

UltimateDebug.SetEventOffSet  PROCEDURE

  code
  SELF.EventOffset = 0A000h
  IF UPPER(SELF.GetEventDescr(EVENT:ACCEPTED)) <> 'EVENT:ACCEPTED'
    self.HuntForOffSet
  end

UltimateDebug.HuntForOffset   procedure
EventNum                        LONG
Pass                            BYTE
Lo                              LONG
Hi                              LONG
  code

  SELF.Debug('SELF.EventOffset is not correct, trying to find a correct value')

  SELF.EventOffset = CHOOSE(SELF.EventOffset = 01400h, 0A000h, 01400h)
  if UPPER(SELF.GetEventDescr(EVENT:ACCEPTED)) = 'EVENT:ACCEPTED' THEN RETURN END

  SELF.EventOffset = GETINI('Debuger','EventOffset', -1)
  CASE SELF.EventOffset
  OF -2; SELF.Debug('Stored value for EventOffset indicates no valid offset to be found, not searching')
  OF -1; SELF.Debug('SELF.EventOffset is not correct, searching for correct value')
  ELSE   ; IF UPPER(SELF.GetEventDescr(EVENT:ACCEPTED)) = 'EVENT:ACCEPTED'
    SELF.Debug('Using stored value for SELF.EventOffset')
    RETURN
  END
  END

  !The loops are split out to search more likely ranges first
  !for efficiency it makes more sense to check offsets incrementing by 100, searching for a result that starts with 'EVENT'
  LOOP Pass = 1 TO 4
    EXECUTE Pass
      BEGIN; Lo = 0A000h; Hi = 0AFFFh END
      BEGIN; Lo = 01000h; Hi = 01FFFh END
      BEGIN; Lo = 00000h; Hi = 00FFFh END
      BEGIN; Lo = 0B000h; Hi = 0FFFFh END
    END
    LOOP EventNum = Lo TO Hi
      SELF.EventOffset = EventNum
      IF UPPER(SELF.GetEventDescr(EVENT:ACCEPTED)) = 'EVENT:ACCEPTED'
        PUTINI('Debuger','EventOffset',SELF.EventOffset)
        RETURN
      END
    END
  END

  SELF.Debug('Could not find a working offset for .EventOffset')
  SELF.EventOffset = -2
  PUTINI('Debuger','EventOffset',SELF.EventOffset)

UltimateDebug.Destruct        PROCEDURE
  CODE
!	FREE(SELF.ControlQ)
!	DISPOSE(SELF.ControlQ)

  FREE(SELF.EventQ)
  DISPOSE(SELF.EventQ)

  FREE(SELF.IgnoreEventQ)
  DISPOSE(SELF.IgnoreEventQ)

  FREE(SELF.CategoryQueue)
  DISPOSE(SELF.CategoryQueue)

UltimateDebug.SetDebugEvent   PROCEDURE(SIGNED Event)
  CODE
  SELF.DebugEvent = Event

UltimateDebug.SetHotKey       PROCEDURE(UNSIGNED HotKey)
  CODE
  0{PROP:Alrt, 255} = HotKey
  SELF.HotKey = HotKey
  SELF.SetDebugEvent(EVENT:AlertKey)

UltimateDebug.SetPurgeTime    PROCEDURE(LONG PurgeTime)
  CODE
  IF PurgeTime <= 0
    SELF.PurgeStarTime = 0
  ELSE
    SELF.PurgeStarTime = SELF.CalcStarDate(0, PurgeTime)
  END

UltimateDebug.IgnoreEvent     PROCEDURE(SIGNED Event)
X                               LONG,AUTO
  CODE
  CLEAR(SELF.IgnoreEventQ)
  SELF.IgnoreEventQ.EventNo = Event
  ADD(SELF.IgnoreEventQ, SELF.IgnoreEventQ.EventNo)

  ! Purge existing logged events
  LOOP X = RECORDS(SELF.EventQ) TO 1 BY -1
    GET(SELF.EventQ, X)
    IF SELF.EventQ.EventNo = Event
      DELETE(SELF.EventQ)
    END
  END

UltimateDebug.TakeEvent       PROCEDURE
  CODE
!	? !UltimateDebug.Debug('UltimateDebug.TakeEvent: DebugEvent='& SELF.DebugEvent &'; Event='& EVENT() &'-'& SELF.GetEventName(EVENT()) &'; Keycode='& KEYCODE())
  CASE EVENT()
  OF 0
  OROF EVENT:Suspend
  OROF EVENT:Resume
!		?   !Self.Debug('...Ignore It')
    !Ignore it
  OF SELF.DebugEvent
!		?   !Self.Debug('...Debug Event  '& SELF.DebugEvent &'/'& EVENT:AlertKey &'  ' & KEYCODE() &'/'& SELF.HotKey)
    IF SELF.DebugEvent <> EVENT:AlertKey |
        OR KEYCODE() = SELF.HotKey
      SELF.Debug('')
    ELSE
      SELF.LogEvent
    END
  ELSE
!		?   !SELF.Debug('...Logger')
    IF SELF.DebugEvent <> EVENT:AlertKey     |
        OR EVENT()         <> EVENT:PreAlertKey  |
        OR KEYCODE()       <> SELF.HotKey
      SELF.LogEvent
    END
  END

UltimateDebug.LogEvent        PROCEDURE
  CODE
  SELF.IgnoreEventQ.EventNo = EVENT()
  GET(SELF.IgnoreEventQ, SELF.IgnoreEventQ.EventNo)
  IF ERRORCODE() <> 0
    CLEAR(SELF.EventQ)
    SELF.EventQ.Date      = FORMAT(TODAY(), @D10)
    SELF.EventQ.Time      = FORMAT(CLOCK(), @T6)
    SELF.EventQ.StarDate  = SELF.CalcStarDate()
    SELF.EventQ.EventNo   = EVENT()
    SELF.EventQ.EventName = SELF.GetEventName(EVENT())
    SELF.EventQ.FieldFeq  = FIELD()
!		SELF.EventQ.FieldName = SELF.GetControlName(FIELD()) TODO
    SELF.EventQ.Keycode   = KEYCODE()
    ADD(SELF.EventQ, SELF.EventQ.StarDate)
  END
  ! Purge old events
  LOOP WHILE SELF.PurgeStarTime <> 0 AND RECORDS(SELF.EventQ)
    GET(SELF.EventQ, 1)
    IF SELF.EventQ.StarDate > SELF.CalcStarDate() - SELF.PurgeStarTime THEN BREAK.
    DELETE(SELF.EventQ)
  END

UltimateDebug.CalcStarDate    PROCEDURE(<LONG D>,<LONG T>)!,REAL
  CODE
  IF OMITTED(D) THEN D = TODAY().
  IF OMITTED(T) THEN T = CLOCK().
  RETURN D + (T-1)/8640000

UltimateDebug.GetEventName    PROCEDURE(SIGNED Event)!,STRING
  CODE
  CASE Event

    ! Field-dependent events

  OF 01H;  RETURN 'Accepted'
  OF 02H;  RETURN 'NewSelection'
  OF 02H;  RETURN 'ScrollUp'
  OF 04H;  RETURN 'ScrollDown'
  OF 05H;  RETURN 'PageUp'
  OF 06H;  RETURN 'PageDown'
  OF 07H;  RETURN 'ScrollTop'
  OF 08H;  RETURN 'ScrollBottom'
  OF 09H;  RETURN 'Locate'

  OF 01H;  RETURN 'MouseDown'
  OF 0aH;  RETURN 'MouseUp'
  OF 0bH;  RETURN 'MouseIn'
  OF 0cH;  RETURN 'MouseOut'
  OF 0dH;  RETURN 'MouseMove'
  OF 0eH;  RETURN 'VBXevent'
  OF 0fH;  RETURN 'AlertKey'
  OF 10H;  RETURN 'PreAlertKey'
  OF 11H;  RETURN 'Dragging'
  OF 12H;  RETURN 'Drag'
  OF 13H;  RETURN 'Drop'
  OF 14H;  RETURN 'ScrollDrag'
  OF 15H;  RETURN 'TabChanging'
  OF 16H;  RETURN 'Expanding'
  OF 17H;  RETURN 'Contracting'
  OF 18H;  RETURN 'Expanded'
  OF 19H;  RETURN 'Contracted'
  OF 1AH;  RETURN 'Rejected'
  OF 1BH;  RETURN 'DroppingDown'
  OF 1CH;  RETURN 'DroppedDown'
  OF 1DH;  RETURN 'ScrollTrack'
  OF 1EH;  RETURN 'ColumnResize'

  OF 101H;  RETURN 'Selected'
  OF 102H;  RETURN 'Selecting'

    ! Field-independent events (FIELD() returns 0)

  OF 201H;  RETURN 'CloseWindow'
  OF 202H;  RETURN 'CloseDown'
  OF 203H;  RETURN 'OpenWindow'
  OF 204H;  RETURN 'OpenFailed'
  OF 205H;  RETURN 'LoseFocus'
  OF 206H;  RETURN 'GainFocus'

  OF 208H;  RETURN 'Suspend'
  OF 209H;  RETURN 'Resume'
  OF 20AH;  RETURN 'Notify'

  OF 20BH;  RETURN 'Timer'
  OF 20CH;  RETURN 'DDErequest'
  OF 20DH;  RETURN 'DDEadvise'
  OF 20EH;  RETURN 'DDEdata'
  OF 20FH;  RETURN 'DDEexecute'
  OF 210H;  RETURN 'DDEpoke'
  OF 211H;  RETURN 'DDEclosed'

  OF 220H;  RETURN 'Move'
  OF 221H;  RETURN 'Size'
  OF 222H;  RETURN 'Restore'
  OF 223H;  RETURN 'Maximize'
  OF 224H;  RETURN 'Iconize'
  OF 225H;  RETURN 'Completed'
  OF 230H;  RETURN 'Moved'
  OF 231H;  RETURN 'Sized'
  OF 232H;  RETURN 'Restored'
  OF 233H;  RETURN 'Maximized'
  OF 234H;  RETURN 'Iconized'
  OF 235H;  RETURN 'Docked'
  OF 236H;  RETURN 'Undocked'

  OF 240H;  RETURN 'BuildFile'
  OF 241H;  RETURN 'BuildKey'
  OF 242H;  RETURN 'BuildDone'

    ! User-definable events

  OF 3FFH;  RETURN 'DoResize'
  OF 400H;  RETURN 'User'
  END
  RETURN '???'
!==============================================================================
!-----------------------------------------------------------------------
! NOTES:
! Construct procedure executes automatically at the beginning of each procedure
! Destruct procedure executes automatically at the end of each procedure
! Construct/Destruct Procedures are implicit under the hood but don't have to be declared in the class as such if there is no need.
! It's ok to have them there for good measure, although some programmers only include them as needed.
! Normally some prefer Init() and Kill(),  but Destruct() can be handy to DISPOSE of stuff (to avoid mem leak)
!-----------------------------------------------------------------------
UltimateDebug.AddUserEvent    PROCEDURE(STRING argEventName,LONG argEventEquate)
  CODE
  IF ~SELF.UserEventNameQ &= NULL
    IF SELF.GetUserEvent(argEventEquate)
      SELF.UserEventNameQ.EventName    = argEventName
      PUT(SELF.UserEventNameQ)
    ELSE
      SELF.UserEventNameQ.EventEquate  = argEventEquate
      SELF.UserEventNameQ.EventName    = argEventName
      ADD(SELF.UserEventNameQ)
    END
  END

!-----------------------------------------------------------------------------------------!
UltimateDebug.GetUserEvent    PROCEDURE(LONG argEventEquate)!string
  CODE
  IF ~SELF.UserEventNameQ &= NULL
    SELF.UserEventNameQ.EventEquate  = argEventEquate
    GET(SELF.UserEventNameQ, SELF.UserEventNameQ.EventEquate)
    RETURN CHOOSE( ERRORCODE()=0, SELF.UserEventNameQ.EventName, '')
  ELSE
    RETURN ''
  END
!-----------------------------------------------------------------------------------------!
UltimateDebug.GetEventDescr   PROCEDURE(LONG argEvent)!,string  !prototype set to default to -1
lcl:Retval                      LIKE(qtUserEventName.EventName)
lcl:EventNum                    UNSIGNED
lcl:Position                    LONG

  CODE
  IF argEvent = -1
    argEvent = EVENT()
  END
  lcl:RetVal = SELF.GetUserEvent( argEvent )
  IF ~lcl:RetVal
    CASE argEvent
    OF Event:User                      ; lcl:RetVal = 'EVENT:User'
    OF Event:User + 1 TO Event:Last    ; lcl:RetVal = 'EVENT:User + '& argEvent - Event:User
    OF Event:APP                       ; lcl:RetVal = 'EVENT:App'
    OF Event:APP  + 1 TO Event:APP_LAST; lcl:RetVal = 'EVENT:App + ' & argEvent - Event:APP

    ELSE
      IF SELF.EventOffset = -2   !indicates could not find a valid offset
        lcl:RetVal = 'EVENT['& argEvent &']'
      ELSE
        lcl:EventNum = argEvent + SELF.EventOffset  ! 1400h (pre c6) or A000h (c6) !EVENT:FIRST equate(01400h)/(0A000h)
        debugerNameMessage(lcl:RetVal, lcl:EventNum)
      END
    END
  END

  RETURN lcl:RetVal   ![7:LEN(CLIP(lcl:RetVal))]

!-----------------------------------------------------------------------------------------!
UltimateDebug.GetFEQDescr     PROCEDURE(SIGNED argFEQ)!,string  !prototype set to default to -1

lcl:Retval                      CSTRING(40) !<--- some arbitrary length
lcl:FEQ                         SIGNED
szRef                           &CSTRING

  CODE
  lcl:FEQ     = CHOOSE(argFEQ = -1, FIELD(), argFEQ)
  COMPILE('** C55+ **',_C55_)
  lcl:RetVal  = debugerGetFieldName(lcl:FEQ)
  !END-COMPILE('** C55+ **',_C55_)
  OMIT('** C55+ **',_C55_)
  szRef      &= debugerGetFieldName(lcl:FEQ)
  lcl:RetVal  = szRef
  !END-OMIT('** C55+ **',_C55_)

  RETURN lcl:RetVal !CLIP(lcl:RetVal)

!-----------------------------------------------------------------------------------------!
!UltimateDebug.DebugEvent
!Used to show Events as they are processed.
!Code by Mark Goldbert
!-----------------------------------------------------------------------------------------!

UltimateDebug.DebugEvent      PROCEDURE(<STRING pDebugProcedure>)

cs_DebugString                  string(600)
cl_Offset                       LONG
cb_DebugNoCR                    BYTE(0)
cs_Event                        STRING(4)
cs_Procedure                    STRING(20)
cl_ProcedureOffset              LONG

  CODE

  cl_Offset = 24
  cs_Procedure = pDebugProcedure
!  cs_DebugString = FORMAT(SELF.GetEventDescr(),@s30) & EVENT()
  cs_Event = EVENT()
  cs_DebugString =  cs_Event & ' ' & SUB(SELF.GetEventDescr(),7,100)
  IF cs_Procedure

    cl_ProcedureOffset = LEN(CLIP(cs_DebugString)) + 2
    cl_Offset = 24 + cl_ProcedureOffset
    cs_DebugString = cs_Procedure[1:cl_ProcedureOffset] & cs_DebugString

  END

  if self.ShowField or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'Field(' & SELF.GetFEQDescr() & ' = ' & FIELD()  &')'
    cl_Offset += 34
  end

  if self.ShowFocus or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'Focus(' & SELF.GetFEQDescr(FOCUS()) & ' =' & FOCUS() & ')'
    cl_Offset += 34
  end

  if self.ShowSelected or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'Selected(' & SELF.GetFEQDescr(SELECTED()) & ' =' & SELECTED() & ')'
    cl_Offset += 34
  end

  if self.ShowSelStart or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'SelStart(' & FOCUS(){prop:SelStart} & ')'
    cl_Offset += 14
  end

  if self.ShowSelEnd or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'SelEnd(' & FOCUS(){prop:SelEnd} & ')'
    cl_Offset += 14
  end

  if self.ShowKeyCode or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'KeyCode(' & KEYCODE() & ')'
    cl_Offset += 14
  end

  if self.ShowError or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'Error('& ERRORCODE() & ': ' & CLIP(ERROR()) & ')'
    cl_Offset += 24
  end

  if self.ShowThread or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'Thread('& THREAD() & ')'
    cl_Offset += 14
  end

  if self.ShowAcceptAll or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'AcceptAll('& 0{prop:AcceptAll} & ')'
    cl_Offset += 14
  end

  if self.ShowContents or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'Contents('& CONTENTS(FOCUS()) & ')'
    cl_Offset += 24
  end

  if self.ShowScreenText or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'ScreenText('& FOCUS(){prop:ScreenText} & ')'
    cl_Offset += 50
  end
  cs_DebugString = cs_DebugString[1:cl_Offset]
  cb_DebugNoCR = SELF.DebugNoCR
  SELF.DebugNoCR = TRUE
  SELF.DEBUG(clip(cs_DebugString),'',TRUE)
  SELF.DebugNoCR = cb_DebugNoCR

UltimateDebug.GPF             PROCEDURE()

  CODE
  DebugBreak()

                              MEMBER()
  omit('***',_c55_)
_ABCDllMode_                  EQUATE(0)
_ABCLinkMode_                 EQUATE(1)
  ***
!
!--------------------------
!ClarionLive Skeleton Class
!--------------------------
!==============================================================================
!If all fields begin with the same prefix, then you can have that auto-stripped
!by uncommenting the following line.
!E_StripPrefix                 EQUATE(1)
!==============================================================================
WidthMultiplier:Narrow        EQUATE(5)  !normal columns (numbers, lowercase, etc.)
WidthMultiplier:Wide          EQUATE(7)  !uppercase columns
DebugQueueCallingItself       BOOL(FALSE)
!==============================================================================
  INCLUDE('Equates.clw')
  INCLUDE('Errors.clw')
  INCLUDE('UltimateDebug.inc'),ONCE
  INCLUDE('UltimateVLB.inc'),ONCE
! ToDo _wsldebug$setlogfile

                              MAP
                                module('kernel')
!see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/debugging_functions.asp
                                  debugbreak(),PASCAL !,RAW,NAME('debugbreak')
                                  OutputDebugString(*CSTRING),PASCAL,RAW,NAME('OutputDebugStringA')
                                end
                                MODULE('C%V%RUN%X%')
                                  debugerNameMessage (*CSTRING, UNSIGNED EventNum ),RAW,NAME('WslDebug$NameMessage')   !Note: use   Event() + EVENT:FIRST  else will get WM_*
                                  COMPILE('** C55+ **',_C55_)
                                  debugerGetFieldName(SIGNED FEQ            ),*CSTRING,RAW,NAME('Cla$FIELDNAME')
                                  !END-COMPILE('** C55+ **',_C55_)
                                  OMIT('** C55+ **',_C55_)
                                  debugerGetFieldName(SIGNED FEQ            ),LONG,RAW,NAME('Cla$FIELDNAME')
                                  !END-OMIT('** C55+ **',_C55_)
                                END
                              END

!OMIT('_ifdef_',EVENT:APP=08000h)
  COMPILE('_ifdef_',EVENT:APP=0)
EVENT:APP                     EQUATE(08000h)
EVENT:APP_LAST                EQUATE(0BFFFh)
  !END_COMPILE('_ifdef_',EVENT:APP=0)
!==============================================================================

!-----------------------------------
UltimateDebug.Init            PROCEDURE()
!-----------------------------------

  CODE

  RETURN

!-----------------------------------
UltimateDebug.Kill            PROCEDURE()
!-----------------------------------

  CODE

  RETURN

!-----------------------------------------
UltimateDebug.AddCategoryToDebug  PROCEDURE(STRING pCategory)
!-----------------------------------------

  CODE

  SELF.CategoryQueue.Category = pCategory
  GET(SELF.CategoryQueue,SELF.CategoryQueue.Category)
  IF ERROR()
    ADD(SELF.CategoryQueue,SELF.CategoryQueue.Category)
  END

!!!-----------------------------------------
!!UltimateDebug.Debug             PROCEDURE(STRING pCategory,STRING pDebugString)
!!!-----------------------------------------
!!
!!	CODE
!!
!!	SELF.CategoryQueue.Category = pCategory
!!	GET(SELF.CategoryQueue,SELF.CategoryQueue.Category)
!!	IF ERRORCODE() = NoError
!!		SELF.Debug('[' & CLIP(pCategory) & ']' & pDebugString)
!!	END
!!
!!	RETURN
!-----------------------------------------
UltimateDebug.Debug           PROCEDURE(STRING pDebugString,<STRING pCustomPrefix>,BYTE pNoClip = 0)
!-----------------------------------------
ASC1:ASCIIFile                  FILE,PRE(ASC1),DRIVER('ASCII'),NAME(GlobalASCIIFileName),CREATE
RECORD                            RECORD,PRE()
STRING                              STRING(512)
                                  END
                                END

lc_CDebugString                 STRING(10000)
lc_COutDebugString              STRING(10000)
lc_Temp                         STRING(10000)
ll_Count                        LONG
ll_End                          LONG
lb_Flag                         BYTE(FALSE)
lb_FirstTime                    BYTE(TRUE)
lb_FirstLoop                    BYTE(0)
ll_StringPosition               LONG

  CODE
  IF SELF.DebugOff AND ~SELF.SaveToFile;RETURN.

  GlobalASCIIFileName = SELF.ASCIIFileName
  IF SELF.SaveToFile
    IF ~EXISTS(ASC1:ASCIIFile{PROP:Name})
      CREATE(ASC1:ASCIIFile)
    END
    OPEN(ASC1:ASCIIFile)
  END
  ll_Count = 1
  IF SELF.DebugNoCR
    lc_CDebugString = CLIP(pDebugString)
    IF ~SELF.DebugOff
      SELF.SendOutputToDebug(lc_CDebugString,pCustomPrefix,pNoClip)
    END
    IF SELF.SaveToFile
      ASC1:String = '[' & FORMAT(TODAY(),@D17) & '-' & FORMAT(CLOCK(),@T7) & ']- ' & lc_CDebugString
      ADD(ASC1:ASCIIFile)
    END
  ELSE
    IF LEN(CLIP(pDebugString)) = 0
      IF SELF.SaveToFile
        ASC1:String = '[' & FORMAT(TODAY(),@D17) & '-' & FORMAT(CLOCK(),@T7) & ']'
        ADD(ASC1:ASCIIFile)
      END
      IF ~SELF.DebugOff
        lc_COutDebugString = ''
        SELF.SendOutputToDebug(lc_COutDebugString,pCustomPrefix,pNoClip)
      END
    ELSE

      Loop Until lb_Flag
        If Len(Clip(pDebugString)) - ll_Count < 9999 Then
          ll_end = Len(Clip(pDebugString))
          lb_Flag = True
        Else
          ll_end = ll_Count + 9998
        End
        lc_CDebugString = CLIP(pDebugString[ll_Count : ll_end])

        ll_Count = ll_end + 1
        LOOP
          ll_StringPosition = INSTRING('<13>',lc_CDebugString,1,1)

          IF ll_StringPosition
            lc_COutDebugString = SUB(lc_CDebugString,1,ll_StringPosition - 1)
            lc_CDebugString = SUB(lc_CDebugString,ll_StringPosition + 2,10000)
            IF SELF.SaveToFile
              ASC1:String = '[' & FORMAT(TODAY(),@D17) & '-' & FORMAT(CLOCK(),@T7) & ']- ' & lc_COutDebugString
              ADD(ASC1:ASCIIFile)
            END
            IF ~SELF.DebugOff
              SELF.SendOutputToDebug(lc_COutDebugString,pCustomPrefix,pNoClip)
            END

            lb_FirstLoop = TRUE
            CYCLE
          END
          IF SELF.SaveToFile
            ASC1:String = '[' & FORMAT(TODAY(),@D17) & '-' & FORMAT(CLOCK(),@T7) & ']- ' & lc_CDebugString
            ADD(ASC1:ASCIIFile)
          END
          IF ~SELF.DebugOff
            SELF.SendOutputToDebug(lc_CDebugString,pCustomPrefix,pNoClip)
          END
          BREAK
        END
      END
    END
  END
  IF SELF.SaveToFile
    CLOSE(ASC1:ASCIIFile)
  END

!-----------------------------------------------------------------------------------------!
UltimateDebug.SendOutputToDebug   PROCEDURE(STRING pOutput,<STRING pCustomPrefix>,BYTE pNoClip = 0)
!-----------------------------------------------------------------------------------------!

lc_CDebugString                     CSTRING(10000)
lc_COutDebugString                  CSTRING(10000)
lc_Temp                             CSTRING(10000)
Count                               LONG(0)

  CODE

  IF pNoClip
    lc_COutDebugString = CLIP(SELF.DebugPrefix) & pOutput
    OutputDebugString(lc_COutDebugString)
  ELSE
    lc_CDebugString =  CLIP(pOutput)

    LOOP
      Count += 1
      IF LEN(CLIP(lc_CDebugString)) > 160
        IF Count > 1
          lc_COutDebugString = '   ' & lc_CDebugString[1:160]
        ELSE
          lc_COutDebugString = lc_CDebugString[1:160]
        END
        lc_CDebugString = SUB(lc_CDebugString,161,10000)

      ELSE
        lc_COutDebugString = lc_CDebugString
        lc_CDebugString = ''
      END

      lc_COutDebugString = CLIP(SELF.DebugPrefix) & ' ' & CLIP(pCustomPrefix) & ' ' & CLIP(lc_COutDebugString)
      OutputDebugString(lc_COutDebugString)

      IF LEN(CLIP(lc_CDebugString)) = 0
        BREAK
      END

    END

  END

!-----------------------------------------------------------------------------------------!
UltimateDebug.ClearDebugView  PROCEDURE()   !Requires Debugview 4.3 or greater
!-----------------------------------------------------------------------------------------!
!From:  http://www.sysinternals.com/ntw2k/freeware/debugview.shtml
!       Clear-output string: When DebugView sees the special debug output string "DBGVIEWCLEAR" it clears the output.

!Note: If this doesn't appear to work, then you are either:
!          a) using an older version of debugview
!       OR b) you are filtering the message

  CODE

  SELF.Debug('DBGVIEWCLEAR')

!==============================================================================
UltimateDebug.DebugRecord     PROCEDURE(*FILE pFile,STRING pMsg)
!--------------------------------------
G                               &GROUP
!--------------------------------------
  CODE
  IF SELF.DebugOff;RETURN.
  COMPILE('!ENDCOMPILE', ST::DEBUG:Debugging=1)
  G &= pFile{PROP:Record}
  SELF.DebugGroup(G,, pMsg, 'Record')
  !ENDCOMPILE
  RETURN
!==============================================================================
UltimateDebug.DebugRecord     PROCEDURE(*FILE pFile,*FILE pFile2,STRING pMsg)
!--------------------------------------
G1                              &GROUP
G2                              &GROUP
!--------------------------------------
  CODE
  IF SELF.DebugOff;RETURN.
  COMPILE('!ENDCOMPILE', ST::DEBUG:Debugging=1)
  G1 &= pFile{PROP:Record}
  G2 &= pFile2{PROP:Record}
  SELF.DebugGroup(G1, G2, pMsg, 'Record')
  !ENDCOMPILE
  RETURN
!==============================================================================
UltimateDebug.DebugGroup      PROCEDURE(*GROUP pGroup,STRING pMsg,<STRING pStructureType>)
!--------------------------------------
  CODE
  IF SELF.DebugOff;RETURN.
  COMPILE('!ENDCOMPILE', ST::DEBUG:Debugging=1)
  SELF.DebugGroup(pGroup,, pMsg)
  !ENDCOMPILE
  RETURN
!==============================================================================
UltimateDebug.DebugGroup      PROCEDURE(*GROUP pGroup,<*GROUP pGroup2>,STRING pMsg,<STRING pStructureType>)
!--------------------------------------
epGroup2                        EQUATE(2)
SavePointer                     LONG,AUTO
NumFields                       SHORT(0)
NumFields2                      SHORT(0)
FieldQ                          QUEUE
Name                              CSTRING(100)
Value                             CSTRING(1000)
Value2                            CSTRING(1000)
                                END
MsgLineQ                        QUEUE
Text                              STRING(100)
                                END
!--------------------------------------
Window                          WINDOW('Debug'),AT(,,676,416),FONT('Tahoma',8,,),CENTER,SYSTEM,GRAY,DOUBLE
                                  LIST,AT(4,4,668,356),USE(?DebugList),VSCROLL,FORMAT('125L(2)|M~Field Name~S(1)@S100@180L(2)|M~Value~S(1)@S255@1000L(2)|M~Value2~S(1)@' &|
                                      'S255@'),FROM(FieldQ)
                                  LIST,AT(4,364,668,48),USE(?MessageList),VSCROLL,FROM(MsgLineQ)
                                END
!--------------------------------------
  CODE
  IF SELF.DebugOff;RETURN.
  COMPILE('!ENDCOMPILE', ST::DEBUG:Debugging=1)
  DO LoadFieldQ
  !--- Prepare window
  OPEN(Window)
  IF OMITTED(epGroup2)
    ?DebugList{PROPLIST:Width, 2} = 1000
  END
  0{PROP:Text} = 0{PROP:Text} &' '& CHOOSE(pStructureType='', 'Group', pStructureType) &' ('& NumFields &' Fields)'
  IF pMsg
    SELF.FormatMessageList(pMsg, MsgLineQ)
  ELSE
    HIDE(?MessageList)
    ?DebugList{PROP:Height} = ?DebugList{PROP:Height} + ?MessageList{PROP:Height} + 4
  END
  !--- Display window
  ACCEPT
  END
  !ENDCOMPILE
  RETURN
!======================================
LoadFieldQ                    ROUTINE
!--------------------------------------
  DATA
F   ANY                  !Field reference for value assignment
X   SHORT,AUTO
M   SHORT(0)
!--------------------------------------
  CODE
  OMIT('!+++!!!+++!')
  LOOP X = 10000 TO 1 BY -1
    IF NumFields = 0 AND WHO(pGroup, X) <> ''
      NumFields = X
      IF M = 0
        M = NumFields
      END
    END
    IF NOT OMITTED(epGroup2)  |
        AND NumFields2 = 0 AND WHO(pGroup2, X) <> ''
      NumFields2 = X
      IF M = 0
        M = NumFields2
      END
    END
    IF M = 0 AND (NumFields OR NumFields2)
      M = X
    END
    IF NumFields AND (OMITTED(epGroup2) OR NumFields2)
      BREAK
    END
  END
  LOOP X = 1 TO M
    CLEAR(FieldQ)
    IF NumFields >= X
      FieldQ.Name   = WHO(pGroup, X)
      F            &= WHAT(pGroup, X, 1)
      FieldQ.Value  = F
      IF NumFields2 >= X
        DO AssignValue2
      END
    ELSE
      FieldQ.Name   = WHO(pGroup2, X)
      DO AssignValue2
    END
    ADD(FieldQ)
    ASSERT(ERRORCODE()=0)
  END
  !+++!!!+++!
  EXIT
!======================================
AssignValue2                  ROUTINE
!--------------------------------------
  OMIT('!+++!!!+++!')
  F            &= WHAT(pGroup2, X, 1)
  FieldQ.Value2 = F
  !+++!!!+++!
  EXIT
!==============================================================================
UltimateDebug.DebugQueue      PROCEDURE(*QUEUE pQueue,<STRING pMsg>,<BYTE pNoTouch>)
                              MAP
LoadFieldQ                      PROCEDURE
                              END
!--------------------------------------
SavePointer                     LONG,AUTO
NumFields                       SHORT,AUTO
                                COMPILE('***---***', E_StripPrefix)
StripPrefixLength               BYTE,AUTO
                                ***---***
StripedList                     UltimateVLB
StripedList_ColumnClass         CLASS(UltVLB:ColumnClass),TYPE
Init                              PROCEDURE(LONG FieldNo,*? FieldRef,STRING Header,STRING Picture,SHORT Width,STRING Justification)
                                END
DummyColumn                     STRING(1)
ColumnObj                       &StripedList_ColumnClass
FieldQ                          QUEUE
Header                            CSTRING(100)
Width                             LONG
IsNumeric                         BOOL
IsGroup                           BOOL
ColumnObject                      &UltVLB:ColumnClass
                                END
MsgLineQ                        QUEUE
Text                              STRING(1000)
                                END
!NumberColumn                  CLASS(UltVLB:ColumnClass)
!Init                            PROCEDURE(LONG FieldNo,*? FieldRef,STRING Header,STRING Picture),*UltVLB:ColumnClass
!                              END
!--------------------------------------
Window                          WINDOW('Debug Queue'),SYSTEM,AT(,,676,416),CENTER,FONT('Tahoma', 8),GRAY,DOUBLE
                                  LIST, AT(4,4,668,356), USE(?DebugList), HVSCROLL
                                  LIST, AT(4,364,668,48), USE(?MessageList), VSCROLL, FROM(MsgLineQ)
                                END
!--------------------------------------
  CODE
  IF SELF.DebugOff;RETURN.
  !ST::Debug('ST::DebugQueue/IN')
  COMPILE('!ENDCOMPILE', ST::DEBUG:Debugging=1)
  IF pQueue &= NULL
    MESSAGE('Queue passed to ST::DebugQueue was a NULL pointer!', 'Debug Queue')
  ELSE
    !--- Save current queue pointer
    SavePointer = CHOOSE(RECORDS(pQueue)=0, 0, POINTER(pQueue))
    !--- Scan passed queue
    DO FindLastField
    IF NumFields = 0
      MESSAGE('Queue passed to ST::DebugQueue has no fields!', 'Debug Queue')
    ELSE
      LoadFieldQ
      COMPILE('***---***', E_StripPrefix)
      DO CheckStripPrefix
      ***---***
      !--- Prepare window
      OPEN(Window)
      0{PROP:Text} = 0{PROP:Text} &' ('& NumFields &' Fields, '& RECORDS(pQueue) &' Records)'
      DO FormatFieldList
      IF pMsg
        SELF.FormatMessageList(pMsg, MsgLineQ)
      ELSE
        HIDE(?MessageList)
        ?DebugList{PROP:Height} = ?DebugList{PROP:Height} + ?MessageList{PROP:Height} + 4
      END
      StripedList.Init(?DebugList, pQueue)
      SELF.Debug(?DebugList{PROP:Format})
      ?DebugList{PROP:Selected} = SavePointer
      IF NOT DebugQueueCallingItself
        DebugQueueCallingItself = TRUE
        !SELF.DebugQueue(FieldQ)
        DebugQueueCallingItself = FALSE
      END
      !--- Display window
      ACCEPT
      END
      !--- Restore queue pointer
      IF SavePointer <> 0 AND pNoTouch <> 1
        GET(pQueue, SavePointer)
      END
    END
  END
  DO FreeFieldQ
  !ENDCOMPILE
  !ST::Debug('ST::DebugQueue/OUT')
  RETURN
!======================================
FreeFieldQ                    ROUTINE
!--------------------------------------
  DATA
X   LONG
  CODE
!--------------------------------------
  LOOP X = 1 TO RECORDS(FieldQ)
    GET(FieldQ, X)
    DISPOSE(FieldQ.ColumnObject)
  END
  FREE(FieldQ)
  DISPOSE(ColumnObj)

!======================================
FindLastField                 ROUTINE
!--------------------------------------
  NumFields = 5000
  LOOP WHILE NumFields > 0  |
      AND   WHO(pQueue, NumFields) = ''
    NumFields -= 1
  END

!**************************************
  COMPILE('***---***', E_StripPrefix)
!======================================
CheckStripPrefix              ROUTINE
!--------------------------------------
  DATA
FieldNo SHORT,AUTO
PrefixFound CSTRING(20)
!--------------------------------------
  CODE
  LOOP FieldNo = 1 TO NumFields
    FieldQ.Header = WHO(pQueue, FieldNo)

    StripPrefixLength = INSTRING(':', FieldQ.Header)
    IF StripPrefixLength
      IF FieldNo = 1
        PrefixFound = FieldQ.Header[1:StripPrefixLength]
      ELSIF FieldQ.Header[1:StripPrefixLength] <> PrefixFound
        StripPrefixLength = 0
        BREAK
      END
    ELSIF PrefixFound
      StripPrefixLength = 0
      BREAK
    END
  END
  EXIT
  ***---***
!======================================
FormatFieldList               ROUTINE
!--------------------------------------
  DATA
FieldNo SHORT,AUTO
ColumnNo    SHORT(0)
Picture CSTRING(5)
!--------------------------------------
  CODE
  !?DebugList{PROP:From} = pQueue
  LOOP FieldNo = 1 TO NumFields
    GET(FieldQ, FieldNo)
    IF FieldQ.IsGroup
      CYCLE
    END
    ColumnNo += 1
    Picture = '@S'& FieldQ.Width
    ?DebugList{PROPLIST:Header                    , ColumnNo} = FieldQ.Header
    ?DebugList{PROPLIST:Picture                   , ColumnNo} = Picture
!   ?DebugList{PROPLIST:Width                     , ColumnNo} = FieldQ.Width
!   ?DebugList{PROPLIST:HeaderCenter              , ColumnNo} = True
!   ?DebugList{PROPLIST:HeaderLeft                , ColumnNo} = True
!   ?DebugList{PROPLIST:HeaderLeftOffset          , ColumnNo} = 1
!   IF FieldQ.IsNumeric
!     ?DebugList{PROPLIST:Right                 , ColumnNo} = True
!     ?DebugList{PROPLIST:RightOffset           , ColumnNo} = 1
!   ELSE
!     ?DebugList{PROPLIST:Left                  , ColumnNo} = True
!     ?DebugList{PROPLIST:LeftOffset            , ColumnNo} = 1
!   END
    ?DebugList{PROPLIST:FieldNo                   , ColumnNo} = FieldNo
!   ?DebugList{PROPLIST:RightBorder               , ColumnNo} = 1
    ?DebugList{PROPLIST:RightBorder+PROPLIST:Group, ColumnNo} = 1
!   ?DebugList{PROPLIST:Resize                    , ColumnNo} = 1

    ColumnObj &= NEW StripedList_ColumnClass
    ColumnObj.Init(FieldNo, WHAT(pQueue, FieldNo), FieldQ.Header, Picture, FieldQ.Width, CHOOSE(~FieldQ.IsNumeric, 'L', 'R'))
    FieldQ.ColumnObject &= ColumnObj
    PUT(FieldQ)
    StripedList.AddColumn(FieldQ.ColumnObject)
  END
  ColumnObj &= NEW StripedList_ColumnClass
  ColumnObj.Init(NumFields+1, DummyColumn, '', '@S1', 1, 'L')
  StripedList.AddColumn(ColumnObj)

!**************************************
!======================================
StripedList_ColumnClass.Init    PROCEDURE(LONG FieldNo,*? FieldRef,STRING Header,STRING Picture,SHORT Width,STRING Justification)
  CODE
  SELF.FieldNo       = FieldNo
  SELF.FieldRef     &= FieldRef
  SELF.Header        = Header
  SELF.Picture       = Picture
  SELF.Width         = Width
  SELF.Justification = Justification
  IF SELF.Justification = 'R'
    SELF.HJustification = 'C'
    SELF.HOffset        = 0
  END

!======================================
LoadFieldQ                    PROCEDURE
!--------------------------------------
FieldNo                         SHORT,AUTO
FieldRef                        ANY
RecNo                           LONG,AUTO
SampleLength                    LONG,AUTO
HeaderLength                    LONG,AUTO
DataLength                      LONG,AUTO
IsDataUpper                     BOOL,AUTO
!--------------------------------------
  CODE
  !ST::Debug('ST::DebugQueue/LoadFieldQ/IN: NumFields='& NumFields)
  LOOP FieldNo = 1 TO NumFields
    CLEAR(FieldQ)
    !ST::Debug('ST::DebugQueue/LoadFieldQ: FieldNo='& FieldNo)
    FieldQ.Header                  = LOWER(WHO(pQueue, FieldNo))
    COMPILE('***---***', E_StripPrefix)
    IF StripPrefixLength
      HeaderLength                 = LEN(FieldQ.Header) - StripPrefixLength
      FieldQ.Header                = SUB(FieldQ.Header, StripPrefixLength+1, HeaderLength)
    ELSE
      ***---***
      HeaderLength                 = LEN(FieldQ.Header)
      COMPILE('***---***', E_StripPrefix)
    END
    ***---***
    IF HeaderLength < 1
      HeaderLength                 = 1
    END
    COMPILE('***---***', _C60_)
    FieldRef                      &= WHAT(pQueue, FieldNo, 1)
    ***---***
    OMIT('***---***', _C60_)
    FieldRef                      &= WHAT(pQueue, FieldNo)
    ***---***
    FieldQ.IsGroup                 = ISGROUP(pQueue, FieldNo)
    FieldQ.IsNumeric               = TRUE
    IsDataUpper                    = FALSE
    !ST::Debug('ST::DebugQueue/LoadFieldQ: RECORDS(pQueue)='& RECORDS(pQueue))
    IF RECORDS(pQueue) > 0 AND pNoTouch <> 1
      DataLength                   = 0
      LOOP RecNo = 1 TO RECORDS(pQueue)
        GET(pQueue, RecNo)
        !ST::Debug('ST::DebugQueue/LoadFieldQ: RecNo='& RecNo &'; FieldRef='& FieldRef)
        IF FieldRef <> ''
          IF NOT NUMERIC(FieldRef)
            FieldQ.IsNumeric       = FALSE
          END
          SampleLength = LEN(CLIP(FieldRef))
          IF NOT FieldQ.IsNumeric AND UPPER(FieldRef) = FieldRef
            IsDataUpper            = TRUE
          END
          IF SampleLength > 25
            DataLength             = 25
          ELSIF DataLength < SampleLength
            DataLength             = SampleLength
          END
        END
      END
    ELSE
      IsDataUpper                  = TRUE
      FieldQ.IsNumeric             = FALSE
      DataLength                   = LEN(FieldRef)
    END
    DO CalculateColumnWidth
    ADD(FieldQ)
  END
  !ST::Debug('ST::DebugQueue/LoadFieldQ/OUT')

CalculateColumnWidth          ROUTINE
  DATA
HeaderWidth SHORT,AUTO
DataWidth   SHORT,AUTO
  CODE
  HeaderWidth  = HeaderLength * WidthMultiplier:Narrow + UltVLB:HeaderOffset
  DataWidth    = DataLength * CHOOSE(~IsDataUpper, WidthMultiplier:Narrow, WidthMultiplier:Wide) + UltVLB:DataOffset
  FieldQ.Width = CHOOSE(DataWidth > HeaderWidth, DataWidth, HeaderWidth)
  SELF.Debug(FieldQ.Header &' - '& HeaderLength &' - '& DataLength &' - '& HeaderWidth &' - '& DataWidth &' - '& FieldQ.Width)

!==============================================================================
UltimateDebug.Message         PROCEDURE(STRING pDebugString)

  CODE
  SELF.Debug(pDebugString)

!==============================================================================

UltimateDebug.SetApplicationName  PROCEDURE(STRING pApplicationName,STRING pProgramExtension)    !,STRING

ApplicationName                     STRING(50)

  CODE
  CASE (pProgramExtension)
  OF ('EXE')
    ApplicationName = 'Application  <9>' & pApplicationName & '.EXE'
  OF ('DLL')
    ApplicationName = 'DLL          <9>' & pApplicationName & '.DLL'
  OF ('LIB')
    ApplicationName = 'Library      <9>' & pApplicationName & '.LIB'
  END

  RETURN ApplicationName

!==============================================================================

UltimateDebug.SetShortApplicationName PROCEDURE(STRING pApplicationName,STRING pProgramExtension)    !,STRING

ApplicationName                         STRING(50)

  CODE
  CASE (pProgramExtension)
  OF ('EXE')
    ApplicationName = pApplicationName & '.EXE'
  OF ('DLL')
    ApplicationName = pApplicationName & '.DLL'
  OF ('LIB')
    ApplicationName = pApplicationName & '.LIB'
  END

  RETURN ApplicationName
!==============================================================================
UltimateDebug.ShowProcedureInfo   PROCEDURE(STRING pProcedure,STRING pApplication,STRING pHelpID,STRING pCreated,STRING pModified,STRING pCompiled)

TheStats                            STRING(500)

Window                              WINDOW('Procedure Information'),AT(,,275,121),CENTER,GRAY
                                      GROUP('Procedure Information'),AT(3,8,190,102),USE(?GROUP1),BOXED
                                      END
                                      TEXT,AT(11,20,176,84),USE(TheStats),SKIP,TRN
                                      BUTTON('Send To Clipboard'),AT(198,61,72),USE(?BUTTONToClipboard)
                                      BUTTON('Send To Debug'),AT(198,78,72),USE(?BUTTONToDebug)
                                      BUTTON('Close'),AT(198,96,72),USE(?BUTTONClose)
                                    END

  CODE
  LOOP WHILE KEYBOARD() !Empty the keyboard buffer
    ASK                  !without processing keystrokes
  END
  SETKEYCODE(0)
  TheStats = ('Procedure:<9>' & CLIP(pProcedure) & '<13,10>' & |
      CLIP(pApplication) & '<13,10><13,10>' & |
      'Help ID    <9>' & CLIP(pHelpID) & '<13,10>' & |
      'Created  On<9>' & CLIP(pCreated) & '<13,10>' & |
      'Modified On<9>' & CLIP(pModified) & '<13,10>' & |
      'Compiled On<9>' & CLIP(pCompiled))
  OPEN(Window)
  ACCEPT
    CASE FIELD()
    OF ?BUTTONClose
      CASE EVENT()
      OF EVENT:Accepted
        BREAK
      END
    OF ?BUTTONToClipboard
      CASE EVENT()
      OF EVENT:Accepted
        SETCLIPBOARD(TheStats)
      END
    OF ?BUTTONToDebug
      CASE EVENT()
      OF EVENT:Accepted
        Self.Debug(TheStats)
      END
    END

  END

  LOOP WHILE KEYBOARD() !Empty the keyboard buffer
    ASK                  !without processing keystrokes
  END
  SETKEYCODE(0)
!==============================================================================
UltimateDebug.FormatMessageList   PROCEDURE(STRING pMsg,*QUEUE pMsgQueue)

!--------------------------------------
StartPos                            LONG(1)
Pos                                 LONG,AUTO
!--------------------------------------
  CODE
  IF pMsg
    LOOP WHILE StartPos
      Pos = INSTRING('|', pMsg, 1, StartPos)
      pMsgQueue = CHOOSE(Pos=0, pMsg[StartPos : LEN(pMsg)], pMsg[StartPos : Pos-1])
      ADD(pMsgQueue)
      ASSERT(ERRORCODE()=0)
      StartPos = Pos+1
    UNTIL Pos = 0
  END
  RETURN
!==============================================================================
!==============================================================================
UltimateDebug.Construct       PROCEDURE

  CODE

  SELF.EventQ        &= NEW ST::DebugEventQueue
  SELF.IgnoreEventQ  &= NEW ST::DebugEventQueue
  SELF.CategoryQueue &= NEW DebugCategoryQueue

  SELF.SetPurgeTime(5*60*100)  !5 minutes
  SELF.SetEventOffset

  SELF.ShowAll        = TRUE
  SELF.ShowField      = FALSE
  SELF.ShowFocus      = FALSE
  SELF.ShowSelected   = FALSE
  SELF.ShowSelStart   = FALSE
  SELF.ShowSelEnd     = FALSE
  SELF.ShowKeyCode    = FALSE
  SELF.ShowError      = FALSE
  SELF.ShowThread     = FALSE
  SELF.ShowContents   = FALSE
  SELF.ShowScreenText = FALSE
  SELF.ShowAcceptAll  = FALSE

!    REGISTER(EVENT:AlertKey,ADDRESS(SELF.ShowProcedureInfo),ADDRESS(SELF))

UltimateDebug.SetEventOffSet  PROCEDURE

  code

  COMPILE('**++** _C60_Plus_',_C60_)
  SELF.EventOffset = 0A000h
  !  **++** _C60_Plus_
  OMIT   ('**--** _PRE_C6_',_C60_)
  SELF.EventOffset = 01400h
  !  **--** _PRE_C6_

  IF UPPER(SELF.GetEventDescr(EVENT:ACCEPTED)) <> 'EVENT:ACCEPTED'
    self.HuntForOffSet
  end

UltimateDebug.HuntForOffset   procedure
EventNum                        LONG
Pass                            BYTE
Lo                              LONG
Hi                              LONG
  code

  SELF.Debug('SELF.EventOffset is not correct, trying to find a correct value')

  SELF.EventOffset = CHOOSE(SELF.EventOffset = 01400h, 0A000h, 01400h)
  if UPPER(SELF.GetEventDescr(EVENT:ACCEPTED)) = 'EVENT:ACCEPTED' THEN RETURN END

  SELF.EventOffset = GETINI('Debuger','EventOffset', -1)
  CASE SELF.EventOffset
  OF -2; SELF.Debug('Stored value for EventOffset indicates no valid offset to be found, not searching')
  OF -1; SELF.Debug('SELF.EventOffset is not correct, searching for correct value')
  ELSE   ; IF UPPER(SELF.GetEventDescr(EVENT:ACCEPTED)) = 'EVENT:ACCEPTED'
    SELF.Debug('Using stored value for SELF.EventOffset')
    RETURN
  END
  END

  !The loops are split out to search more likely ranges first
  !for efficiency it makes more sense to check offsets incrementing by 100, searching for a result that starts with 'EVENT'
  LOOP Pass = 1 TO 4
    EXECUTE Pass
      BEGIN; Lo = 0A000h; Hi = 0AFFFh END
      BEGIN; Lo = 01000h; Hi = 01FFFh END
      BEGIN; Lo = 00000h; Hi = 00FFFh END
      BEGIN; Lo = 0B000h; Hi = 0FFFFh END
    END
    LOOP EventNum = Lo TO Hi
      SELF.EventOffset = EventNum
      IF UPPER(SELF.GetEventDescr(EVENT:ACCEPTED)) = 'EVENT:ACCEPTED'
        PUTINI('Debuger','EventOffset',SELF.EventOffset)
        RETURN
      END
    END
  END

  SELF.Debug('Could not find a working offset for .EventOffset')
  SELF.EventOffset = -2
  PUTINI('Debuger','EventOffset',SELF.EventOffset)

UltimateDebug.Destruct        PROCEDURE
  CODE
!	FREE(SELF.ControlQ)
!	DISPOSE(SELF.ControlQ)

  FREE(SELF.EventQ)
  DISPOSE(SELF.EventQ)

  FREE(SELF.IgnoreEventQ)
  DISPOSE(SELF.IgnoreEventQ)

  FREE(SELF.CategoryQueue)
  DISPOSE(SELF.CategoryQueue)

UltimateDebug.SetDebugEvent   PROCEDURE(SIGNED Event)
  CODE
  SELF.DebugEvent = Event

UltimateDebug.SetHotKey       PROCEDURE(UNSIGNED HotKey)
  CODE
  0{PROP:Alrt, 255} = HotKey
  SELF.HotKey = HotKey
  SELF.SetDebugEvent(EVENT:AlertKey)

UltimateDebug.SetPurgeTime    PROCEDURE(LONG PurgeTime)
  CODE
  IF PurgeTime <= 0
    SELF.PurgeStarTime = 0
  ELSE
    SELF.PurgeStarTime = SELF.CalcStarDate(0, PurgeTime)
  END

UltimateDebug.IgnoreEvent     PROCEDURE(SIGNED Event)
X                               LONG,AUTO
  CODE
  CLEAR(SELF.IgnoreEventQ)
  SELF.IgnoreEventQ.EventNo = Event
  ADD(SELF.IgnoreEventQ, SELF.IgnoreEventQ.EventNo)

  ! Purge existing logged events
  LOOP X = RECORDS(SELF.EventQ) TO 1 BY -1
    GET(SELF.EventQ, X)
    IF SELF.EventQ.EventNo = Event
      DELETE(SELF.EventQ)
    END
  END

UltimateDebug.TakeEvent       PROCEDURE
  CODE
!	? !UltimateDebug.Debug('UltimateDebug.TakeEvent: DebugEvent='& SELF.DebugEvent &'; Event='& EVENT() &'-'& SELF.GetEventName(EVENT()) &'; Keycode='& KEYCODE())
  CASE EVENT()
  OF 0
  OROF EVENT:Suspend
  OROF EVENT:Resume
!		?   !Self.Debug('...Ignore It')
    !Ignore it
  OF SELF.DebugEvent
!		?   !Self.Debug('...Debug Event  '& SELF.DebugEvent &'/'& EVENT:AlertKey &'  ' & KEYCODE() &'/'& SELF.HotKey)
    IF SELF.DebugEvent <> EVENT:AlertKey |
        OR KEYCODE() = SELF.HotKey
      SELF.Debug('')
    ELSE
      SELF.LogEvent
    END
  ELSE
!		?   !SELF.Debug('...Logger')
    IF SELF.DebugEvent <> EVENT:AlertKey     |
        OR EVENT()         <> EVENT:PreAlertKey  |
        OR KEYCODE()       <> SELF.HotKey
      SELF.LogEvent
    END
  END

UltimateDebug.LogEvent        PROCEDURE
  CODE
  SELF.IgnoreEventQ.EventNo = EVENT()
  GET(SELF.IgnoreEventQ, SELF.IgnoreEventQ.EventNo)
  IF ERRORCODE() <> 0
    CLEAR(SELF.EventQ)
    SELF.EventQ.Date      = FORMAT(TODAY(), @D10)
    SELF.EventQ.Time      = FORMAT(CLOCK(), @T6)
    SELF.EventQ.StarDate  = SELF.CalcStarDate()
    SELF.EventQ.EventNo   = EVENT()
    SELF.EventQ.EventName = SELF.GetEventName(EVENT())
    SELF.EventQ.FieldFeq  = FIELD()
!		SELF.EventQ.FieldName = SELF.GetControlName(FIELD()) TODO
    SELF.EventQ.Keycode   = KEYCODE()
    ADD(SELF.EventQ, SELF.EventQ.StarDate)
  END
  ! Purge old events
  LOOP WHILE SELF.PurgeStarTime <> 0 AND RECORDS(SELF.EventQ)
    GET(SELF.EventQ, 1)
    IF SELF.EventQ.StarDate > SELF.CalcStarDate() - SELF.PurgeStarTime THEN BREAK.
    DELETE(SELF.EventQ)
  END

UltimateDebug.CalcStarDate    PROCEDURE(<LONG D>,<LONG T>)!,REAL
  CODE
  IF OMITTED(D) THEN D = TODAY().
  IF OMITTED(T) THEN T = CLOCK().
  RETURN D + (T-1)/8640000

UltimateDebug.GetEventName    PROCEDURE(SIGNED Event)!,STRING
  CODE
  CASE Event

    ! Field-dependent events

  OF 01H;  RETURN 'Accepted'
  OF 02H;  RETURN 'NewSelection'
  OF 02H;  RETURN 'ScrollUp'
  OF 04H;  RETURN 'ScrollDown'
  OF 05H;  RETURN 'PageUp'
  OF 06H;  RETURN 'PageDown'
  OF 07H;  RETURN 'ScrollTop'
  OF 08H;  RETURN 'ScrollBottom'
  OF 09H;  RETURN 'Locate'

  OF 01H;  RETURN 'MouseDown'
  OF 0aH;  RETURN 'MouseUp'
  OF 0bH;  RETURN 'MouseIn'
  OF 0cH;  RETURN 'MouseOut'
  OF 0dH;  RETURN 'MouseMove'
  OF 0eH;  RETURN 'VBXevent'
  OF 0fH;  RETURN 'AlertKey'
  OF 10H;  RETURN 'PreAlertKey'
  OF 11H;  RETURN 'Dragging'
  OF 12H;  RETURN 'Drag'
  OF 13H;  RETURN 'Drop'
  OF 14H;  RETURN 'ScrollDrag'
  OF 15H;  RETURN 'TabChanging'
  OF 16H;  RETURN 'Expanding'
  OF 17H;  RETURN 'Contracting'
  OF 18H;  RETURN 'Expanded'
  OF 19H;  RETURN 'Contracted'
  OF 1AH;  RETURN 'Rejected'
  OF 1BH;  RETURN 'DroppingDown'
  OF 1CH;  RETURN 'DroppedDown'
  OF 1DH;  RETURN 'ScrollTrack'
  OF 1EH;  RETURN 'ColumnResize'

  OF 101H;  RETURN 'Selected'
  OF 102H;  RETURN 'Selecting'

    ! Field-independent events (FIELD() returns 0)

  OF 201H;  RETURN 'CloseWindow'
  OF 202H;  RETURN 'CloseDown'
  OF 203H;  RETURN 'OpenWindow'
  OF 204H;  RETURN 'OpenFailed'
  OF 205H;  RETURN 'LoseFocus'
  OF 206H;  RETURN 'GainFocus'

  OF 208H;  RETURN 'Suspend'
  OF 209H;  RETURN 'Resume'
  OF 20AH;  RETURN 'Notify'

  OF 20BH;  RETURN 'Timer'
  OF 20CH;  RETURN 'DDErequest'
  OF 20DH;  RETURN 'DDEadvise'
  OF 20EH;  RETURN 'DDEdata'
  OF 20FH;  RETURN 'DDEexecute'
  OF 210H;  RETURN 'DDEpoke'
  OF 211H;  RETURN 'DDEclosed'

  OF 220H;  RETURN 'Move'
  OF 221H;  RETURN 'Size'
  OF 222H;  RETURN 'Restore'
  OF 223H;  RETURN 'Maximize'
  OF 224H;  RETURN 'Iconize'
  OF 225H;  RETURN 'Completed'
  OF 230H;  RETURN 'Moved'
  OF 231H;  RETURN 'Sized'
  OF 232H;  RETURN 'Restored'
  OF 233H;  RETURN 'Maximized'
  OF 234H;  RETURN 'Iconized'
  OF 235H;  RETURN 'Docked'
  OF 236H;  RETURN 'Undocked'

  OF 240H;  RETURN 'BuildFile'
  OF 241H;  RETURN 'BuildKey'
  OF 242H;  RETURN 'BuildDone'

    ! User-definable events

  OF 3FFH;  RETURN 'DoResize'
  OF 400H;  RETURN 'User'
  END
  RETURN '???'
!==============================================================================
!-----------------------------------------------------------------------
! NOTES:
! Construct procedure executes automatically at the beginning of each procedure
! Destruct procedure executes automatically at the end of each procedure
! Construct/Destruct Procedures are implicit under the hood but don't have to be declared in the class as such if there is no need.
! It's ok to have them there for good measure, although some programmers only include them as needed.
! Normally some prefer Init() and Kill(),  but Destruct() can be handy to DISPOSE of stuff (to avoid mem leak)
!-----------------------------------------------------------------------
UltimateDebug.AddUserEvent    PROCEDURE(STRING argEventName,LONG argEventEquate)
  CODE
  IF ~SELF.UserEventNameQ &= NULL
    IF SELF.GetUserEvent(argEventEquate)
      SELF.UserEventNameQ.EventName    = argEventName
      PUT(SELF.UserEventNameQ)
    ELSE
      SELF.UserEventNameQ.EventEquate  = argEventEquate
      SELF.UserEventNameQ.EventName    = argEventName
      ADD(SELF.UserEventNameQ)
    END
  END

!-----------------------------------------------------------------------------------------!
UltimateDebug.GetUserEvent    PROCEDURE(LONG argEventEquate)!string
  CODE
  IF ~SELF.UserEventNameQ &= NULL
    SELF.UserEventNameQ.EventEquate  = argEventEquate
    GET(SELF.UserEventNameQ, SELF.UserEventNameQ.EventEquate)
    RETURN CHOOSE( ERRORCODE()=0, SELF.UserEventNameQ.EventName, '')
  ELSE
    RETURN ''
  END
!-----------------------------------------------------------------------------------------!
UltimateDebug.GetEventDescr   PROCEDURE(LONG argEvent)!,string  !prototype set to default to -1
lcl:Retval                      LIKE(qtUserEventName.EventName)
lcl:EventNum                    UNSIGNED
lcl:Position                    LONG

  CODE
  IF argEvent = -1
    argEvent = EVENT()
  END
  lcl:RetVal = SELF.GetUserEvent( argEvent )
  IF ~lcl:RetVal
    CASE argEvent
    OF Event:User                      ; lcl:RetVal = 'EVENT:User'
    OF Event:User + 1 TO Event:Last    ; lcl:RetVal = 'EVENT:User + '& argEvent - Event:User
    OF Event:APP                       ; lcl:RetVal = 'EVENT:App'
    OF Event:APP  + 1 TO Event:APP_LAST; lcl:RetVal = 'EVENT:App + ' & argEvent - Event:APP

    ELSE
      IF SELF.EventOffset = -2   !indicates could not find a valid offset
        lcl:RetVal = 'EVENT['& argEvent &']'
      ELSE
        lcl:EventNum = argEvent + SELF.EventOffset  ! 1400h (pre c6) or A000h (c6) !EVENT:FIRST equate(01400h)/(0A000h)
        debugerNameMessage(lcl:RetVal, lcl:EventNum)
      END
    END
  END

  RETURN lcl:RetVal   ![7:LEN(CLIP(lcl:RetVal))]

!-----------------------------------------------------------------------------------------!
UltimateDebug.GetFEQDescr     PROCEDURE(SIGNED argFEQ)!,string  !prototype set to default to -1

lcl:Retval                      CSTRING(40) !<--- some arbitrary length
lcl:FEQ                         SIGNED
szRef                           &CSTRING

  CODE
  lcl:FEQ     = CHOOSE(argFEQ = -1, FIELD(), argFEQ)
  COMPILE('** C55+ **',_C55_)
  lcl:RetVal  = debugerGetFieldName(lcl:FEQ)
  !END-COMPILE('** C55+ **',_C55_)
  OMIT('** C55+ **',_C55_)
  szRef      &= debugerGetFieldName(lcl:FEQ)
  lcl:RetVal  = szRef
  !END-OMIT('** C55+ **',_C55_)

  RETURN lcl:RetVal !CLIP(lcl:RetVal)

!-----------------------------------------------------------------------------------------!
!UltimateDebug.DebugEvent
!Used to show Events as they are processed.
!Code by Mark Goldbert
!-----------------------------------------------------------------------------------------!

UltimateDebug.DebugEvent      PROCEDURE(<STRING pDebugProcedure>)

cs_DebugString                  string(600)
cl_Offset                       LONG
cb_DebugNoCR                    BYTE(0)
cs_Event                        STRING(4)
cs_Procedure                    STRING(20)
cl_ProcedureOffset              LONG

  CODE

  cl_Offset = 24
  cs_Procedure = pDebugProcedure
!  cs_DebugString = FORMAT(SELF.GetEventDescr(),@s30) & EVENT()
  cs_Event = EVENT()
  cs_DebugString =  cs_Event & ' ' & SUB(SELF.GetEventDescr(),7,100)
  IF cs_Procedure

    cl_ProcedureOffset = LEN(CLIP(cs_DebugString)) + 2
    cl_Offset = 24 + cl_ProcedureOffset
    cs_DebugString = cs_Procedure[1:cl_ProcedureOffset] & cs_DebugString

  END

  if self.ShowField or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'Field(' & SELF.GetFEQDescr() & ' = ' & FIELD()  &')'
    cl_Offset += 34
  end

  if self.ShowFocus or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'Focus(' & SELF.GetFEQDescr(FOCUS()) & ' =' & FOCUS() & ')'
    cl_Offset += 34
  end

  if self.ShowSelected or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'Selected(' & SELF.GetFEQDescr(SELECTED()) & ' =' & SELECTED() & ')'
    cl_Offset += 34
  end

  if self.ShowSelStart or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'SelStart(' & FOCUS(){prop:SelStart} & ')'
    cl_Offset += 14
  end

  if self.ShowSelEnd or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'SelEnd(' & FOCUS(){prop:SelEnd} & ')'
    cl_Offset += 14
  end

  if self.ShowKeyCode or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'KeyCode(' & KEYCODE() & ')'
    cl_Offset += 14
  end

  if self.ShowError or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'Error('& ERRORCODE() & ': ' & CLIP(ERROR()) & ')'
    cl_Offset += 24
  end

  if self.ShowThread or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'Thread('& THREAD() & ')'
    cl_Offset += 14
  end

  if self.ShowAcceptAll or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'AcceptAll('& 0{prop:AcceptAll} & ')'
    cl_Offset += 14
  end

  if self.ShowContents or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'Contents('& CONTENTS(FOCUS()) & ')'
    cl_Offset += 24
  end

  if self.ShowScreenText or self.ShowAll
    cs_DebugString = cs_DebugString[1:cl_Offset] & 'ScreenText('& FOCUS(){prop:ScreenText} & ')'
    cl_Offset += 50
  end
  cs_DebugString = cs_DebugString[1:cl_Offset]
  cb_DebugNoCR = SELF.DebugNoCR
  SELF.DebugNoCR = TRUE
  SELF.DEBUG(clip(cs_DebugString),'',TRUE)
  SELF.DebugNoCR = cb_DebugNoCR

UltimateDebug.GPF             PROCEDURE()

  CODE
  DebugBreak()


no message

no message

git-svn-id: 41bd7e47c31e4d43f97241d7529f6785d233c6d8@1090 23f926e6-80f1-49ca-85a0-60d4a27bb3ac

; CLW file contains information for the MFC ClassWizard

[General Info]
Version=1
LastClass=RPChildFrame
LastTemplate=CDialog
NewFileInclude1=#include "stdafx.h"
NewFileInclude2=#include "rdo_process.h"
LastPage=0

ClassCount=13
Class1=RPDockWnd
Class2=RPPageCtrl
Class3=RPPageCtrlItemLabel
Class4=RPPageCtrlItem
Class5=RPProjectBar
Class6=CSizingControlBarG
Class7=CSizingControlBar
Class8=CSCBMiniDockFrameWnd
Class9=RPApp
Class10=RPAboutDlg
Class11=RPChildFrame
Class12=RPFlowChart
Class13=RPMainFrame

ResourceCount=3
Resource1=IDR_MAINFRAME (English (U.S.))
Resource2=IDR_RDO_PRTYPE (English (U.S.))
Resource3=IDD_ABOUTBOX (English (U.S.))

[CLS:RPDockWnd]
Type=0
BaseClass=CSizingControlBarG
HeaderFile=ctrl\rdoprocess_dockwnd.h
ImplementationFile=ctrl\rdoprocess_dockwnd.cpp

[CLS:RPPageCtrl]
Type=0
BaseClass=CWnd
HeaderFile=ctrl\rdoprocess_pagectrl.h
ImplementationFile=ctrl\rdoprocess_pagectrl.cpp

[CLS:RPPageCtrlItemLabel]
Type=0
BaseClass=CWnd
HeaderFile=ctrl\rdoprocess_pagectrl.h
ImplementationFile=ctrl\rdoprocess_pagectrl.cpp

[CLS:RPPageCtrlItem]
Type=0
BaseClass=CWnd
HeaderFile=ctrl\rdoprocess_pagectrl.h
ImplementationFile=ctrl\rdoprocess_pagectrl.cpp

[CLS:RPProjectBar]
Type=0
BaseClass=RPDockWnd
HeaderFile=ctrl\rdoprocess_projectbar.h
ImplementationFile=ctrl\rdoprocess_projectbar.cpp

[CLS:CSizingControlBarG]
Type=0
BaseClass=baseCSizingControlBarG
HeaderFile=ctrl\sizecbar\scbarg.h
ImplementationFile=ctrl\sizecbar\scbarg.cpp

[CLS:CSizingControlBar]
Type=0
BaseClass=baseCSizingControlBar
HeaderFile=ctrl\sizecbar\sizecbar.h
ImplementationFile=ctrl\sizecbar\sizecbar.cpp

[CLS:CSCBMiniDockFrameWnd]
Type=0
BaseClass=baseCSCBMiniDockFrameWnd
HeaderFile=ctrl\sizecbar\sizecbar.h
ImplementationFile=ctrl\sizecbar\sizecbar.cpp
Filter=N
LastObject=CSCBMiniDockFrameWnd

[CLS:RPApp]
Type=0
BaseClass=CWinApp
HeaderFile=rdoprocess_app.h
ImplementationFile=rdoprocess_app.cpp

[CLS:RPAboutDlg]
Type=0
BaseClass=CDialog
HeaderFile=rdoprocess_app.cpp
ImplementationFile=rdoprocess_app.cpp

[CLS:RPChildFrame]
Type=0
BaseClass=CMDIChildWnd
HeaderFile=rdoprocess_childfrm.h
ImplementationFile=rdoprocess_childfrm.cpp
Filter=M
LastObject=ID_APP_ABOUT

[CLS:RPFlowChart]
Type=0
BaseClass=CWnd
HeaderFile=rdoprocess_flowchart.h
ImplementationFile=rdoprocess_flowchart.cpp

[CLS:RPMainFrame]
Type=0
BaseClass=CMDIFrameWnd
HeaderFile=rdoprocess_mainfrm.h
ImplementationFile=rdoprocess_mainfrm.cpp

[DLG:IDD_ABOUTBOX]
Type=1
Class=RPAboutDlg

[TB:IDR_MAINFRAME (English (U.S.))]
Type=1
Class=?
Command1=ID_FILE_NEW
Command2=ID_EDIT_CUT
Command3=ID_EDIT_COPY
Command4=ID_EDIT_PASTE
Command5=ID_FLOW_SELECT
Command6=ID_FLOW_CONNECTOR
Command7=ID_FLOW_ROTATE
CommandCount=7

[MNU:IDR_MAINFRAME (English (U.S.))]
Type=1
Class=?
Command1=ID_FILE_NEW
Command2=ID_APP_EXIT
Command3=ID_VIEW_TOOLBAR
Command4=ID_VIEW_STATUS_BAR
Command5=ID_APP_ABOUT
CommandCount=5

[MNU:IDR_RDO_PRTYPE (English (U.S.))]
Type=1
Class=?
Command1=ID_FILE_NEW
Command2=ID_FILE_CLOSE
Command3=ID_APP_EXIT
Command4=ID_EDIT_UNDO
Command5=ID_EDIT_CUT
Command6=ID_EDIT_COPY
Command7=ID_EDIT_PASTE
Command8=ID_VIEW_TOOLBAR
Command9=ID_VIEW_STATUS_BAR
Command10=ID_WINDOW_CASCADE
Command11=ID_WINDOW_TILE_HORZ
Command12=ID_WINDOW_ARRANGE
Command13=ID_APP_ABOUT
CommandCount=13

[ACL:IDR_MAINFRAME (English (U.S.))]
Type=1
Class=?
Command1=ID_EDIT_COPY
Command2=ID_FILE_NEW
Command3=ID_EDIT_PASTE
Command4=ID_EDIT_UNDO
Command5=ID_EDIT_CUT
Command6=ID_NEXT_PANE
Command7=ID_PREV_PANE
Command8=ID_EDIT_COPY
Command9=ID_EDIT_PASTE
Command10=ID_EDIT_CUT
Command11=ID_EDIT_UNDO
CommandCount=11

[DLG:IDD_ABOUTBOX (English (U.S.))]
Type=1
Class=?
ControlCount=4
Control1=IDC_STATIC,static,1342177283
Control2=IDC_STATIC,static,1342308480
Control3=IDC_STATIC,static,1342308352
Control4=IDOK,button,1342373889

error: pathspec 'trunk/rdo_process.clw' did not match any file(s) known to git


Added missing MSVC class wizard file

Added missing MSVC class wizard file

fatal: unable to access 'https://github.com/nolith/olsrd.git/': The requested URL returned error: 403


Added missing MSVC class wizard file

Added missing MSVC class wizard file

; CLW file contains information for the MFC ClassWizard

[General Info]
Version=1
LastClass=MyDialog2
LastTemplate=CDialog
NewFileInclude1=#include "stdafx.h"
NewFileInclude2=#include "frontend.h"
LastPage=0

ClassCount=8
Class1=CFrontendApp
Class2=CFrontendDlg
Class3=MyDialog1
Class4=MyDialog2
Class5=MyDialog3
Class6=MyDialog4
Class7=MyEdit
Class8=MyTabCtrl

ResourceCount=6
Resource1=IDD_DIALOG1 (Englisch (USA))
Resource2=IDD_DIALOG3 (Englisch (USA))
Resource3=IDD_DIALOG4 (Englisch (USA))
Resource4=IDD_DIALOG2 (Englisch (USA))
Resource5=IDD_FRONTEND_DIALOG (Englisch (USA))
Resource6=IDR_TRAYMENU (Englisch (USA))

[CLS:CFrontendApp]
Type=0
BaseClass=CWinApp
HeaderFile=Frontend.h
ImplementationFile=Frontend.cpp
LastObject=CFrontendApp

[CLS:CFrontendDlg]
Type=0
BaseClass=CDialog
HeaderFile=FrontendDlg.h
ImplementationFile=FrontendDlg.cpp
LastObject=IDC_TAB1

[CLS:MyDialog1]
Type=0
BaseClass=CDialog
HeaderFile=MyDialog1.h
ImplementationFile=MyDialog1.cpp
LastObject=IDC_BUTTON1

[CLS:MyDialog2]
Type=0
BaseClass=CDialog
HeaderFile=MyDialog2.h
ImplementationFile=MyDialog2.cpp
LastObject=IDC_COMBO3
Filter=D
VirtualFilter=dWC

[CLS:MyDialog3]
Type=0
BaseClass=CDialog
HeaderFile=MyDialog3.h
ImplementationFile=MyDialog3.cpp
LastObject=IDC_LIST1

[CLS:MyDialog4]
Type=0
BaseClass=CDialog
HeaderFile=MyDialog4.h
ImplementationFile=MyDialog4.cpp
LastObject=IDC_LIST1

[CLS:MyEdit]
Type=0
BaseClass=CEdit
HeaderFile=MyEdit.h
ImplementationFile=MyEdit.cpp

[CLS:MyTabCtrl]
Type=0
BaseClass=CTabCtrl
HeaderFile=MyTabCtrl.h
ImplementationFile=MyTabCtrl.cpp

[DLG:IDD_FRONTEND_DIALOG]
Type=1
Class=CFrontendDlg

[DLG:IDD_DIALOG1]
Type=1
Class=MyDialog1

[DLG:IDD_DIALOG2]
Type=1
Class=MyDialog2

[DLG:IDD_DIALOG3]
Type=1
Class=MyDialog3

[DLG:IDD_DIALOG4]
Type=1
Class=MyDialog4

[DLG:IDD_FRONTEND_DIALOG (Englisch (USA))]
Type=1
Class=CFrontendDlg
ControlCount=4
Control1=IDC_TAB1,SysTabControl32,1342177280
Control2=IDC_BUTTON1,button,1342242816
Control3=IDC_BUTTON2,button,1342242816
Control4=IDC_BUTTON3,button,1342242816

[DLG:IDD_DIALOG4 (Englisch (USA))]
Type=1
Class=MyDialog4
ControlCount=2
Control1=IDC_LIST1,SysListView32,1350631425
Control2=IDC_STATIC,static,1342308352

[DLG:IDD_DIALOG3 (Englisch (USA))]
Type=1
Class=MyDialog3
ControlCount=6
Control1=IDC_LIST1,SysListView32,1350631429
Control2=IDC_LIST4,SysListView32,1350631429
Control3=IDC_LIST5,SysListView32,1350631429
Control4=IDC_LIST6,SysListView32,1350631429
Control5=IDC_STATIC,static,1342308352
Control6=IDC_STATIC,static,1342308352

[DLG:IDD_DIALOG2 (Englisch (USA))]
Type=1
Class=MyDialog2
ControlCount=54
Control1=IDC_LIST1,SysListView32,1350631427
Control2=IDC_SLIDER2,msctls_trackbar32,1342242825
Control3=IDC_EDIT7,edit,1350631426
Control4=IDC_CHECK3,button,1476460547
Control5=IDC_CHECK2,button,1342242819
Control6=IDC_EDIT1,edit,1350631426
Control7=IDC_EDIT2,edit,1350631426
Control8=IDC_EDIT3,edit,1350631426
Control9=IDC_EDIT9,edit,1350631426
Control10=IDC_EDIT4,edit,1350631426
Control11=IDC_EDIT10,edit,1350631426
Control12=IDC_EDIT5,edit,1350631426
Control13=IDC_EDIT6,edit,1350631426
Control14=IDC_COMBO1,combobox,1344340227
Control15=IDC_EDIT15,edit,1350639618
Control16=IDC_CHECK1,button,1342242819
Control17=IDC_EDIT12,edit,1350631426
Control18=IDC_EDIT13,edit,1350631426
Control19=IDC_EDIT11,edit,1350631426
Control20=IDC_CHECK4,button,1342242819
Control21=IDC_RADIO1,button,1342373897
Control22=IDC_RADIO2,button,1342373897
Control23=IDC_BUTTON4,button,1342242816
Control24=IDC_BUTTON5,button,1342242816
Control25=IDC_BUTTON1,button,1342242816
Control26=IDC_STATIC,static,1342308352
Control27=IDC_STATIC,static,1342308352
Control28=IDC_STATIC,static,1342308354
Control29=IDC_STATIC,static,1342308354
Control30=IDC_STATIC,static,1342308354
Control31=IDC_STATIC,static,1342308354
Control32=IDC_STATIC,static,1342308354
Control33=IDC_STATIC,static,1342308354
Control34=IDC_STATIC,static,1342308354
Control35=IDC_STATIC,static,1342308354
Control36=IDC_STATIC,static,1342308354
Control37=IDC_STATIC,static,1342308354
Control38=IDC_STATIC,static,1342308352
Control39=IDC_STATIC,static,1342308352
Control40=IDC_STATIC,static,1342308352
Control41=IDC_STATIC,static,1342308352
Control42=IDC_STATIC,static,1342308352
Control43=IDC_STATIC,static,1342308352
Control44=IDC_STATIC,static,1342308352
Control45=IDC_STATIC,static,1342308352
Control46=IDC_STATIC,static,1342308354
Control47=IDC_STATIC,static,1342308352
Control48=IDC_TEXT1,static,1342308353
Control49=IDC_STATIC,static,1342308354
Control50=IDC_STATIC,static,1342308354
Control51=IDC_STATIC,static,1342308354
Control52=IDC_STATIC,static,1342308354
Control53=IDC_CHECK5,button,1342242819
Control54=IDC_COMBO3,combobox,1344340227

[DLG:IDD_DIALOG1 (Englisch (USA))]
Type=1
Class=MyDialog1
ControlCount=5
Control1=IDC_EDIT1,edit,1353783300
Control2=IDC_BUTTON3,button,1342242816
Control3=IDC_BUTTON2,button,1342242816
Control4=IDC_BUTTON4,button,1342242816
Control5=IDC_BUTTON1,button,1342242816

[MNU:IDR_TRAYMENU (Englisch (USA))]
Type=1
Class=?
Command1=IDM_START
Command2=IDM_STOP
Command3=IDM_WINDOW
Command4=IDM_SETTINGS
Command5=IDM_OUTPUT
Command6=IDM_EXIT
CommandCount=6

error: pathspec 'gui/win32/Main/Frontend.clw' did not match any file(s) known to git


Hello world sample

Hello world sample

  PROGRAM

  MAP
  END

  CODE

  MESSAGE('Hello World!')

  RETURN

error: pathspec 'samples/Clarion/hello.clw' did not match any file(s) known to git