
.data
ListboxClass   db      'LISTBOX',0
szUserKey      db      'User Defined Names',0
szBuildKey     db      'Build Menu Items',0
szAddinKey     db      'User Addin Items',0
szToolsKey     db      'Tools Menu Items',0
szHelpKey      db      'Help Menu Items',0
KeyArrayM      dd      szBuildKey,szAddinKey,szToolsKey,szHelpKey

FontNameAR     db      'Arial',0
FontNameMS     db      'MS Sans Serif',0
FontNameQT     db      'Quick Type',0

szPtrs         db      '*.ptr',0
ExtPtr         db      '.ptr',0

szSelectGrp    db      'Select A Group',0
szGroup00      db      'Group00   (Default)',0
szGroup01      db      'Group01',0
szGroup02      db      'Group02',0
szGroup03      db      'Group03',0
szGroup04      db      'Group04',0
szGroup05      db      'Group05',0

szSelect       db      'Select A Submenu',0
szMIName       db      'Menu Item Name:',0
szSIName       db      'Submenu Item Name:',0
szSMName       db      'Submenu Name:',0
szTxtExe       db      'Command Line - hlp, txt, rtf, or exe Type Files:',0
szDllName      db      'Command Line: (Name or full Path, dll or exe)',0
szCmdLine      db      'Command Line: (Executable Only)',0

szBuildM       db      '&Build',0
szAddinsM      db      '&Addins',0
szToolsM       db      '&Tools',0
szHelpM        db      '&Help',0
MenuArray      dd      szBuildM,szAddinsM,szToolsM,szHelpM

szNone         db      '(None)',0
szAccel01      db      'Ctrl+ ',0
szAccel02      db      'Ctrl+F',0
szAccel03      db      'Shift+F',0
szAccel04      db      'Shift+Ctrl+F',0
szAccel05      db      'Alt+F',0
szAccel06      db      'Alt+Ctrl+F',0
szAccel07      db      'Alt+Shift+F',0
szAccel08      db      'Alt+ ',0
AccelArray     dd      szAccel02,szAccel03,szAccel04,szAccel05,szAccel06,szAccel07
ValueArray     dd      00000009h,00000005h,00000013h,00000011h,00000019h,00000015h

szState01      db      'ENABLED',0    ;    0
szState02      db      'GRAYED',0     ;    1
StateArray     dd      szState01,szState02

szMenuCnt      db      'Menu Cnt',0
szNameM        db      'Menu '
szIndexM       db      10 dup(?),0
fmat1          db      '%01u',0
fmat4          db      '%04u',0
szNull         db      0
szCar          db      '^',0
szSCol         db      ';',0
szSColZ        db      ';0',0
szColNS        db      ':',0
szColSp        db      ': ',0
szSpace4       db      '    ',0
szSpaces       db      '      ',0
;Patn           db      '*.*',0
szUserK        db      '1c01',0
szUserK31      db      '1c31',0
szUserCodeM    db      'User Defined Code 1u01',0
szSep          db      '**** Separator ****',0
szSepN         db      '---- (Separator) ----',0
szSub          db      'SUBMENU: ',0

szAddinPath    db      'Addins\Utility\Utility.dll:DllProc:',0
szAddin01a     db      'SUBMENU: Addin Projects',0
szAddin02a     db      'SUBMENU: Utility',0
szAddin03a     db      'NewProject:',0
szAddin04a     db      'ProjTest:',0
szAddin05a     db      'New Tab:',0
szAddin06a     db      'Open File:',0
szAddin07a     db      'Close Tab:',0
szAddin08a     db      'Save As:',0
szAddin09a     db      'Print:',0
szAddin10a     db      'Get a Reg Path:',0
szAddin11a     db      'InvertCase	Alt+I:',0
szAddin12a     db      'LowerCase	Alt+L:',0
szAddin13a     db      'UpperCase	Alt+U:',0
AddinAArray    dd      szAddin05a,szAddin06a,szAddin07a,szAddin08a,
                       szAddin09a,szAddin10a,szAddin11a,szAddin12a,szAddin13a

szAddin03b     db      '22,0;0^',0
szAddin04b     db      'Addins\ProjTest\ProjTest.dll:DllProc:1,0;0^',0
szAddin05b     db      '1,0;0^',0
szAddin06b     db      '2,0;0^',0
szAddin07b     db      '2,1;0^',0
szAddin08b     db      '3,0;0^',0
szAddin09b     db      '4,0;0^',0
szAddin10b     db      '5,0;0^',0
szAddin11b     db      '41,0;0^',0
szAddin12b     db      '42,0;0^',0
szAddin13b     db      '43,0;0^',0
AddinBArray    dd      szAddin05b,szAddin06b,szAddin07b,szAddin08b,
                       szAddin09b,szAddin10b,szAddin11b,szAddin12b,szAddin13b

szHelp01a      db      'Error Codes:',0
szHelp02a      db      'Lang - Page Code:',0
HelpAArray     dd      szHelp01a,szHelp02a

szHelp01b      db      'HelpFiles\WinErrorCodes.txt',0
szHelp02b      db      'HelpFiles\LangCode.txt',0
HelpBArray     dd      szHelp01b,szHelp02b

szAddM         db      'Add A Menu Item',0
szEditM        db      'Edit The Menu Item',0
szGetHelp      db      'Get Help File',0
szSetupM       db      'Missing entries!',0
szNoSelM       db      'No item was selected.',0
szInUse        db      'The Accelerator you selected is already in use.',0
szBuildT       db      'C U S T O M I Z E   T H E   B U I L D   M E N U',0
szAddInT       db      'C U S T O M I Z E   T H E   A D D I N S   M E N U',0
szToolsT       db      'C U S T O M I Z E   T H E   T O O L S   M E N U',0
szHelpT        db      'C U S T O M I Z E   T H E   H E L P   M E N U',0
szOpenFiles    db      '&Opened Files',0

.data?
szReditM       db      256 dup(?)
szNameR        db      64  dup(?)
szBuffN        db      64  dup(?)
szBuffF        db      64  dup(?)
szBuffW        db      64  dup(?)
szBuffS        db      10  dup(?)
szBuildTxt     db      64  dup(?)
szToolsTxt     db      64  dup(?)
szPathM        db      256 dup(?)
szMenuItems    db      256 dup(?)
sz38           db      256 dup(?)

hList          dd      ?
hKeyM          dd      ?
hBuildM        dd      ?
hAddins        dd      ?
hTools         dd      ?
hHelp          dd      ?
BuildCnt       dd      ?
ToolsCnt       dd      ?
hFontD         dd      ?
hFontLST       dd      ?
hList45        dd      ?
h1912          dd      ?
h1915          dd      ?
h34            dd      ?
h38            dd      ?
h39            dd      ?
hSMenuH        dd      ?
hSubMenuM      dd      ?
hSubMenuT      dd      ?
hWndMenu       dd      ?
hSubMenuW      dd      ?
hMenuCnt       dd      ?
hMenuArray     dd      32  dup(?)
hAccelArray    dd      ?
mItem          dd      ?
uItem          dd      ?
hDlgSav        dd      ?
hBmpU          dd      ?
hBmpD          dd      ?
hButtU         dd      ?
hButtD         dd      ?
hEdit01        dd      ?
hEdit02        dd      ?
hEdit03        dd      ?
hEdit04        dd      ?
hEdit05        dd      ?
hComb01        dd      ?
hComb02        dd      ?
hComb03        dd      ?
hCheck01       dd      ?
SelList        dd      ?
hData          dd      ?
SaveSel        dd      ?
SaveSelC       dd      ?
SaveSelL       dd      ?
TypeCmd        dd      ?
SubmenuOn      dd      ?
UpdateOn       dd      ?
CloseOn        dd      ?
AccelOn        dd      ?
exeOn          dd      ?
Opt            dd      ?
sw4            dd      ?
NotAvail       dd      ?
AccelCnt       dd      ?
AccelOff       dd      ?
RegPath        dd      ?

accel          ACCEL             <?>

.code

;=========================================================================
; Get menu path PROCEDURE
;=========================================================================
GetMenuPath  PROC  uses ebx esi edi RegKey:DWORD, wParam, Code
LOCAL    Cnt:DWORD, Incr
LOCAL    szWork[256]:BYTE

        call     GetSubHandles
         mov     eax, Code
         dec     eax
         mov     ecx, hBuildM[eax*4]
         mov     hSMenuH, ecx

        INVOKE     lstrcpy, addr szMenuItems, RegKey
      .if Code == 1       ; Build
         INVOKE     lstrcat, addr szMenuItems, addr szBuildKey
      .elseif Code == 2   ; AddIns
         INVOKE     lstrcat, addr szMenuItems, addr szAddinKey
      .elseif Code == 3   ; Tools
         INVOKE     lstrcat, addr szMenuItems, addr szToolsKey
      .elseif Code == 4   ; Help
         INVOKE     lstrcat, addr szMenuItems, addr szHelpKey
      .else
            jmp     GetOut
      .endif

;--------------- [Open or create the menu registry] --------------- 
      INVOKE     RegCreateKeyEx, HKEY_CURRENT_USER, offset szMenuItems, 0, offset szREGSZ, 0,\
                 KEY_WRITE or KEY_READ, 0, addr hKeyM, addr lpdwDisp

      INVOKE     wsprintf, addr szIndexM, addr fmat4, wParam
      INVOKE     lstrlen, addr szPathM
         mov     lpcbData, 250
      INVOKE     RegQueryValueEx, hKeyM, addr szNameM, 0, addr lpType, addr szPathM, addr lpcbData
      .if eax == 0
         INVOKE     lstrlen, addr szPathM
         .if byte ptr szPathM[eax-1] == '^'
               mov     byte ptr szPathM[eax-1], 0
         .endif
            mov     ecx, eax
            xor     esi, esi
            xor     edi, edi
            lea     edx, szBuffN
            and     Incr, 0
         .while (ecx)
               mov     al, byte ptr szPathM[esi]
            .if al == ':' && byte ptr szPathM[esi+1] != '\' || al == ';'
                  mov     byte ptr [edx+edi], 0
                  xor     edi, edi
                  inc     Incr
               .if Incr == 1
                     lea     edx, szBuffP
               .elseif Incr == 2
                     lea     edx, szBuffF
               .elseif Incr == 3
                     lea     edx, szBuffW
               .elseif Incr == 4
                     lea     edx, szBuffS
               .else
                  .break
               .endif
            .else
                  mov     byte ptr [edx+edi], al
                  inc     edi
            .endif
               inc     esi
               dec     ecx
         .endw
            mov     byte ptr [edx+edi], 0
      .endif

GetOut:
      INVOKE     RegCloseKey, hKeyM

         ret
GetMenuPath  ENDP

;===================================================
; Sets the specified value in the registry
;===================================================
RegSetVal PROC  ValueName:DWORD, Value

         inc     mItem
      INVOKE     wsprintf, addr szIndexM, addr fmat4, mItem
      INVOKE     lstrlen, Value
         mov     lpcbData, eax
         mov     ecx, ValueName
         mov     edx, Value
      INVOKE     RegSetValueEx, hKeyM, ecx, 0, REG_SZ, edx, lpcbData

         ret
RegSetVal ENDP

;=========================================================================
; Load menu items PROCEDURE
;=========================================================================
LoadMenuItems PROC  uses ebx esi edi RegKey:DWORD, SubMenu
LOCAL    Cnt:DWORD, Incr, Cnt1, Incr1, Cnt2, Incr2, PopupM, Code, Len, Pos
LOCAL    MenuCnt1:DWORD, hSavMenu, SavCnt, AccelPos, hTemp, FirstTime
LOCAL    szWork[256]:BYTE, szWork1[64]:BYTE

         and     hTemp, 0
         and     hSubMenuM, 0
         and     FirstTime, 0
      .if !RegPath
          MOVmd     RegPath, RegKey
            mov     mii.cbSize, sizeof mii

         INVOKE     lstrcpy, addr szMenuItems, RegPath

         INVOKE     RegCreateKeyEx, HKEY_CURRENT_USER, offset szMenuItems, 0, offset szREGSZ, 0,\
                    KEY_WRITE or KEY_READ, 0, addr hKeyM, addr lpdwDisp
            mov     lpcbData, 250
         INVOKE     RegQueryValueEx, hKeyM, addr rDEFr, 0, addr lpType, addr szAsmRoot, addr lpcbData
         INVOKE     RegCloseKey, hKeyM

         INVOKE     CreateWindowEx, 0, addr ListboxClass, 0,\
                    WS_CHILD or WS_BORDER or WS_VSCROLL or\
                    LBS_HASSTRINGS or LBS_SORT or LBS_NOTIFY or\
                    LBS_NOINTEGRALHEIGHT,\
                    100, 50, 250, 200, hWnd, 44, hInst, 0
            mov     hTemp, eax
            mov     FirstTime, 1
            mov     CloseOn, 1
      .endif

      .if SubMenu == 4
            jmp     ClearMenus
      .endif

      INVOKE     lstrcpy, addr szMenuItems, RegPath
      INVOKE     lstrcat, addr szMenuItems, addr szUserKey

;--------------- [Open or create the user name registry] --------------- 
      INVOKE     RegCreateKeyEx, HKEY_CURRENT_USER, offset szMenuItems, 0, offset szREGSZ, 0,\
                 KEY_WRITE or KEY_READ, 0, addr hKeyM, addr lpdwDisp
         mov     Cnt, 0
         mov     lpcbData, 63
      INVOKE     RegQueryValueEx, hKeyM, addr szUserK, 0, addr lpType, addr szNameR, addr lpcbData
      .if eax == ERROR_SUCCESS
            mov     lpcbData, 63
         INVOKE     RegQueryValueEx, hKeyM, addr szUserK31, 0, addr lpType, addr szNameR, addr lpcbData
         .if eax != ERROR_SUCCESS
               mov     Cnt, 10
               mov     Incr, 31
         .endif
      .else
           mov     Cnt, 40
           mov     Incr, 1
      .endif

;--------------- [Fill the user code name registry if empty] --------------- 
      .if Cnt
         .while (Cnt)
            INVOKE     BaseAscii, Incr, addr szWork1, 2, 10, 0, 1, 0
               mov     al, byte ptr szWork1
               mov     byte ptr szUserK+2, al
               mov     byte ptr szUserCodeM+20, al
               mov     al, byte ptr szWork1+1
               mov     byte ptr szUserK+3, al
               mov     byte ptr szUserCodeM+21, al
            INVOKE     lstrlen, addr szUserCodeM
               mov     lpcbData, eax
            INVOKE     RegSetValueEx, hKeyM, addr szUserK, 0, REG_SZ, addr szUserCodeM, lpcbData
               inc     Incr
               dec     Cnt
         .endw
      .endif
      INVOKE     RegCloseKey, hKeyM

;---------- [Load menu items] ----------
         mov     mii.fMask, MIIM_DATA or MIIM_ID or MIIM_STATE or MIIM_SUBMENU or MIIM_TYPE
        call     GetSubHandles

         and     MenuCnt1, 0
         mov     Opt, 1

Loop1:
      .if Opt == 1 || Opt == 3
            mov     eax, Opt
            dec     eax
            mov     ecx, hBuildM[eax*4]
            mov     hSubMenuT, ecx

         INVOKE     GetMenuItemCount, hSubMenuT
            mov     Cnt, eax
            and     Incr, 0

;---------- [Get last menu item name] ----------
            dec     eax
            mov     ecx, eax
            mov     mii.cch, lengthof szWork
         .if Opt == 1
               lea     eax, szBuildTxt
         .else
               lea     eax, szToolsTxt
         .endif
            mov     mii.dwTypeData, eax
         INVOKE     GetMenuItemInfo, hSubMenuT, ecx, TRUE, addr mii

;---------- [Get menu items count] ----------
         .while (Cnt)
               mov     mii.cch, lengthof szWork
               lea     eax, szWork
               mov     mii.dwTypeData, eax
            INVOKE     GetMenuItemInfo, hSubMenuT, Incr, TRUE, addr mii
               inc     MenuCnt1
            .if mii.hSubMenu
                 push     mii.hSubMenu
                  pop     hSavMenu
               INVOKE     GetMenuItemCount, hSavMenu
                  mov     Cnt1, eax
                  and     Incr1, 0
               .while (Cnt1)
                     mov     mii.cch, lengthof szWork
                     lea     eax, szWork
                     mov     mii.dwTypeData, eax
                  INVOKE     GetMenuItemInfo, hSavMenu, Incr1, TRUE, addr mii
                     inc     MenuCnt1
                     inc     Incr1
                     dec     Cnt1
               .endw
            .endif
               inc     Incr
               dec     Cnt
         .endw

         .if Opt == 1
             MOVmd     BuildCnt, MenuCnt1
               and     MenuCnt1, 0
               mov     Opt, 3
               jmp     Loop1
         .elseif Opt == 3
             MOVmd     ToolsCnt, MenuCnt1
         .endif
      .endif

LoadMenus:
         and     Incr, 0
         mov     Cnt, 4
      .while (Cnt)
         INVOKE     lstrcpy, addr szMenuItems, RegPath
            mov     eax, Incr
            mov     ecx, hBuildM[eax*4]
            mov     hSMenuH, ecx
            mov     ecx, KeyArrayM[eax*4]
         INVOKE     lstrcat, addr szMenuItems, ecx

;--------------- [Open or create the menu registry] --------------- 
         INVOKE     RegCreateKeyEx, HKEY_CURRENT_USER, offset szMenuItems, 0, offset szREGSZ, 0,\
                    KEY_WRITE or KEY_READ, 0, addr hKeyM, addr lpdwDisp
            mov     lpcbData, 4
         INVOKE     RegQueryValueEx, hKeyM, addr szMenuCnt, 0, addr lpType, addr mItem, addr lpcbData

            mov     eax, lpdwDisp
         .if eax == REG_CREATED_NEW_KEY || Incr == 1 && mItem < 3102 || Incr == 3 && mItem < 7102
            .if Incr == 0
                  mov     mItem, 2100   ; Build
            .elseif Incr == 1
                  mov     mItem, 3100   ; Addins
            .elseif Incr == 2
                  mov     mItem, 4100   ; Tools
            .elseif Incr == 3
                  mov     mItem, 7100   ; Help
            .endif
            INVOKE     RegSetVal, addr szNameM, addr szSepN

;---------- [Add some user menu items] ----------
            .if Incr == 1
               INVOKE     RegSetVal, addr szNameM, addr szAddin01a

               INVOKE     lstrcpy, addr szWork, addr szAddin03a
               INVOKE     lstrcat, addr szWork, addr szAsmRoot
               INVOKE     lstrcat, addr szWork, addr szAddinPath
               INVOKE     lstrcat, addr szWork, addr szAddin03b
               INVOKE     RegSetVal, addr szNameM, addr szWork

               INVOKE     lstrcpy, addr szWork, addr szAddin04a
               INVOKE     lstrcat, addr szWork, addr szAsmRoot
               INVOKE     lstrcat, addr szWork, addr szAddin04b
               INVOKE     RegSetVal, addr szNameM, addr szWork

               INVOKE     RegSetVal, addr szNameM, addr szSepN

               INVOKE     RegSetVal, addr szNameM, addr szAddin02a

                  and     Incr1, 0
                  mov     Cnt1, 9
               .while (Cnt1)
                     mov     eax, Incr1
                     mov     ecx, AddinAArray[eax*4]
                  INVOKE     lstrcpy, addr szWork, ecx
                  INVOKE     lstrcat, addr szWork, addr szAsmRoot
                  INVOKE     lstrcat, addr szWork, addr szAddinPath
                     mov     eax, Incr1
                     mov     ecx, AddinBArray[eax*4]
                  INVOKE     lstrcat, addr szWork, ecx
                  .if Incr1 == 5 || Incr1 == 6
                     INVOKE     lstrcpy, addr szWork1, addr szSepN
                     INVOKE     lstrcat, addr szWork1, addr szCar
                     INVOKE     RegSetVal, addr szNameM, addr szWork1
                  .endif
                  INVOKE     RegSetVal, addr szNameM, addr szWork
                     inc     Incr1
                     dec     Cnt1
               .endw

            .elseif Incr == 3
                  and     Incr1, 0
                  mov     Cnt1, 2
               .while (Cnt1)
                     mov     eax, Incr1
                     mov     ecx, HelpAArray[eax*4]
                  INVOKE     lstrcpy, addr szWork, ecx
                  INVOKE     lstrcat, addr szWork, addr szAsmRoot
                     mov     eax, Incr1
                     mov     ecx, HelpBArray[eax*4]
                  INVOKE     lstrcat, addr szWork, ecx
                  INVOKE     RegSetVal, addr szNameM, addr szWork
                     inc     Incr1
                     dec     Cnt1
               .endw
            .endif
            INVOKE     RegSetValueEx, hKeyM, addr szMenuCnt, 0, REG_DWORD, addr mItem, 4
         .endif

            mov     lpcbData, 4
         INVOKE     RegQueryValueEx, hKeyM, addr szMenuCnt, 0, addr lpType, addr mItem, addr lpcbData
         .if eax != 0 || mItem == 2100 || mItem == 3100 || mItem == 4100 || mItem == 7100
               jmp     GetOut
         .endif
            jmp     Pass

ClearMenus:
            and     PopupM, 0
            and     Incr1, 0
         INVOKE     GetMenuItemCount, hSMenuH
            mov     Cnt1, eax
           push     mItem
         .if mItem > 2099 && mItem < 2501
               dec     Cnt1
               mov     mItem, 2101
               mov     Opt, 1      ; = Build
         .elseif mItem > 3099 && mItem < 3501
               dec     Cnt1
               mov     mItem, 3101
               mov     Opt, 2      ; = Addins
         .elseif mItem > 4099 && mItem < 4501
               dec     Cnt1
               mov     mItem, 4101
               mov     Opt, 3      ; = Tools
         .elseif mItem > 7099 && mItem < 7501
               dec     Cnt1
               mov     mItem, 7101
               mov     Opt, 4      ; = Help
         .else
               jmp     GetOut
         .endif

;---------- [Find first user menu item] ----------
            and     Incr1, 0
         .while (Cnt1)
            INVOKE     GetMenuItemID, hSMenuH, Incr1
            .if eax == mItem
               .break
            .endif
               inc     Incr1
               dec     Cnt1
         .endw
         .if !Cnt1
               jmp     GetOut
         .endif
         INVOKE     SendMessage, hList45, LB_GETCOUNT, 0, 0
         .if TypeCmd != 305   ; 305 = Delete
               dec     eax
         .endif
            mov     Cnt1, eax

         .if Opt == 4
            INVOKE     GetMenuItemCount, hSMenuH
               mov     Cnt2, eax
               and     Cnt1, 0
               and     Incr2, 0
            .while (Cnt2)
               INVOKE     GetMenuItemID, hSMenuH, Incr2
               .if eax > 7100 && eax < 7500
                     inc     Cnt1
               .endif
                  inc     Incr2
                  dec     Cnt2
            .endw
         .endif

         .while (Cnt1)
            INVOKE     DeleteMenu, hSMenuH, Incr1, MF_BYPOSITION
               dec     Cnt1
         .endw
            pop     mItem

Pass:
          MOVmd     Cnt1, mItem
         .if Cnt1 > 2099 && Cnt1 < 2501
               sub     Cnt1, 2100
               mov     mItem, 2101
               mov     Opt, 1      ; = Build
         .elseif Cnt1 > 3099 && Cnt1 < 3501
               sub     Cnt1, 3100
               mov     mItem, 3101
               mov     Opt, 2      ; = Addins
         .elseif Cnt1 > 4099 && Cnt1 < 4501
               sub     Cnt1, 4100
               mov     mItem, 4101
               mov     Opt, 3      ; = Tools
         .elseif Cnt1 > 7099 && Cnt1 < 7501
               sub     Cnt1, 7100
               mov     mItem, 7101
               mov     Opt, 4      ; = Help
         .endif
          MOVmd     SavCnt, Cnt1

         .while (Cnt1)
            INVOKE     wsprintf, addr szIndexM, addr fmat4, mItem
            INVOKE     lstrlen, addr szPathM
               mov     lpcbData, 250
            INVOKE     RegQueryValueEx, hKeyM, addr szNameM, 0, addr lpType, addr szPathM, addr lpcbData
            .if eax == 0
               INVOKE     lstrlen, addr szPathM
                  mov     Len, eax
               .if byte ptr szPathM == '*' && byte ptr szPathM+3 == 'S' ||\
                   byte ptr szPathM == '*' && byte ptr szPathM+5 == 'S' ; To convert old
                     mov     eax, Len
                  .if byte ptr szPathM[eax-1] == '^'
                     INVOKE     lstrcpy, addr szPathM, addr szSepN
                     INVOKE     lstrcat, addr szPathM, addr szCar
                  .else
                     INVOKE     lstrcpy, addr szPathM, addr szSepN
                  .endif
               .endif
               .if SavCnt == 1 && byte ptr szPathM == '-' && byte ptr szPathM+6 == 'S'
                     jmp     GetOut  ; The first seperator
               .endif
                  and     AccelPos, 0
                  xor     eax, eax
                  mov     ecx, Len
               .while (ecx)

;---------- [Check for accelerator on close] ----------
                  .if CloseOn && hTemp && byte ptr szPathM[eax] == 9
                        mov     AccelPos, eax
                        inc     AccelPos
                  .endif

                  .if byte ptr szPathM[eax] == ':' || byte ptr szPathM[eax] == '-' &&\
                      byte ptr szPathM[eax+6] == 'S' || byte ptr szPathM[eax] == 'S' &&\
                      byte ptr szPathM[eax+2] == 'B' && byte ptr szPathM[eax+7] == ':'
                     .if byte ptr szPathM[eax] == ':'
                          push     eax
                           inc     eax
                        INVOKE     lstrcpyn, addr szBuffN, addr szPathM, eax

;---------- [If acceletor, load in a listbox] ----------
                        .if CloseOn && hTemp && AccelPos
                              pop     edx
                             push     edx
                              mov     ecx, AccelPos
                              sub     edx, ecx
                              inc     edx
                           INVOKE     lstrcpyn, addr szBuffA, addr szPathM[ecx], edx
                           INVOKE     SendMessage, hTemp, LB_ADDSTRING, 0, addr szBuffA
                              mov     ecx, eax
                           INVOKE     SendMessage, hTemp, LB_SETITEMDATA, ecx, mItem
                        .endif

                           pop     eax
                           inc     eax
                        INVOKE     lstrcpy, addr szBuffP, addr szPathM[eax]
                     .elseif byte ptr szPathM[eax+2] == 'B' && byte ptr szPathM[eax+7] == ':'
                        INVOKE     lstrcpy, addr szBuffN, addr szPathM+9
                        INVOKE     CreatePopupMenu
                           mov     hSubMenuM, eax
                           mov     PopupM, 1
                           mov     ebx, hMenuCnt
                           mov     hMenuArray[ebx*4], eax
                           inc     hMenuCnt

                     .else
                        INVOKE     lstrcpy, addr szBuffN, addr szPathM
                     .endif

                      push     hSMenuH
                     INVOKE     lstrlen, addr szPathM
                        mov     Len, eax
                     .if byte ptr szPathM[eax-1] == '^'
                          push     hSubMenuM
                           pop     hSMenuH
                     .endif

                     INVOKE     GetMenuItemCount, hSMenuH  ; Get count of items in the sub menu
                     .if eax == -1
                           mov     eax, 0
                     .endif
                     .if Opt == 4
                           sub     eax, 4                  ; 4 up from bottom for help menu
;DSPValue hWnd, eax, 1, 'm'
                     .endif
                        mov     Pos, eax

                           mov     ecx, MF_BYPOSITION or MF_STRING 
                           mov     eax, Len
                        .if byte ptr szPathM[eax-1] == '^' && byte ptr szPathM[eax-3] == ';'
                           .if byte ptr szPathM[eax-2] == '1'     ; GRAYED
                                  or     ecx, MFS_GRAYED
                           .endif

                        .elseif byte ptr szPathM[eax-1] != '^' && byte ptr szPathM[eax-2] == ';'
                           .if byte ptr szPathM[eax-1] == '1'     ; GRAYED
                                  or     ecx, MFS_GRAYED
                           .endif
                        .endif

                     .if byte ptr szPathM == '-' && !hTemp || byte ptr szPathM == '-' && FirstTime
                        INVOKE     InsertMenu, hSMenuH, Pos, MF_BYPOSITION or MF_SEPARATOR, mItem, addr szBuffN
                     .elseif PopupM && !hTemp || PopupM && FirstTime
                        INVOKE     InsertMenu, hSMenuH, Pos, MF_BYPOSITION or\
                                   MF_STRING or MF_POPUP, hSubMenuM, addr szBuffN
                     .elseif !hTemp || FirstTime
                        INVOKE     InsertMenu, hSMenuH, Pos, ecx, mItem, addr szBuffN
                     .endif
                        and     PopupM, 0
                        pop     hSMenuH
                     .break
                  .endif
                     dec     ecx
                     inc     eax
               .endw
            .endif
               inc     mItem
               dec     Cnt1
         .endw

GetOut:
         .if SubMenu == 4
            .if hKeyM
               INVOKE     RegCloseKey, hKeyM
                  and     hKeyM, 0
            .endif

            .if CloseOn
               INVOKE     CreateWindowEx, 0, addr ListboxClass, 0,\
                          WS_CHILD or WS_BORDER or WS_VSCROLL or\
                          LBS_HASSTRINGS or LBS_SORT or LBS_NOTIFY or\
                          LBS_NOINTEGRALHEIGHT,\
                          100, 50, 250, 200, hWnd, 44, hInst, 0
                  mov     hTemp, eax
                  mov     SubMenu, 1
                  jmp     LoadMenus
            .endif

               ret
         .endif

         .if SubMenu == 1
            .if hKeyM
               INVOKE     RegCloseKey, hKeyM
                  and     hKeyM, 0
            .endif
               inc     Incr
               dec     Cnt
         .endif
      .endw

      .if CloseOn
         .if hAccel
            INVOKE     DestroyAcceleratorTable, hAccel
         .endif
         INVOKE     LoadAccelerators, hInst, IDR_ACCEL
            mov     hAccel, eax

         INVOKE     CopyAcceleratorTable, hAccel, 0, 0
         INVOKE     CopyAcceleratorTable, hAccel, hAccelArray, eax
            mov     AccelCnt, eax
;DSPValue hWnd, eax, 1, 'm'
           imul     eax, 6
            mov     AccelOff, eax

         INVOKE     SendMessage, hTemp, LB_GETCOUNT, 0, 0
            add     AccelCnt, eax
            mov     Cnt, eax
            and     Incr, 0
         .while (Cnt)
            INVOKE     SendMessage, hTemp, LB_GETTEXT, Incr, addr szBuffA
               mov     Cnt1, eax
            INVOKE     SendMessage, hTemp, LB_GETITEMDATA, Incr, 0
               mov     accel.cmd, ax
               mov     accel.fVirt, 1
               xor     eax, eax
            .while (Cnt1)
               .if word ptr szBuffA[eax] == 'hS'
                     add     accel.fVirt, 4
               .elseif word ptr szBuffA[eax] == 'tC'
                     add     accel.fVirt, 8
               .elseif word ptr szBuffA[eax] == 'lA'
                     add     accel.fVirt, 10h
               .elseif byte ptr szBuffA[eax] == '+' && byte ptr szBuffA[eax+2] == 0
                     xor     ecx, ecx
                     mov     cl, byte ptr szBuffA[eax+1]
                     mov     accel.key, cx
                  .break
               .elseif byte ptr szBuffA[eax] == '+' && byte ptr szBuffA[eax+1] == 'F' &&\
                       byte ptr szBuffA[eax+3] == 0 ||\
                       byte ptr szBuffA[eax] == 'F' && byte ptr szBuffA[eax+2] == 0
                  .if byte ptr szBuffA[eax] == '+'
                        mov     cl, byte ptr szBuffA[eax+2]
                  .else
                        mov     cl, byte ptr szBuffA[eax+1]
                  .endif
                     mov     byte ptr szWork1, cl
                     mov     byte ptr szWork1+1, 0
                  INVOKE     AsciiBase, addr szWork1, addr Code, 10
                     dec     Code
                     add     Code, 70h  ; F1 = 70, F2 = 71, etc.
                     mov     ecx, Code
                     mov     accel.key, cx
                  .break
               .elseif byte ptr szBuffA[eax] == '+' && byte ptr szBuffA[eax+1] == 'F' &&\
                       byte ptr szBuffA[eax+4] == 0 ||\
                       byte ptr szBuffA[eax] == 'F' && byte ptr szBuffA[eax+3] == 0
                  .if byte ptr szBuffA[eax] == '+'
                     mov     cx, word ptr szBuffA[eax+2]
                  .else
                     mov     cx, word ptr szBuffA[eax+1]
                  .endif
                     mov     word ptr szWork1, cx
                     mov     byte ptr szWork1+2, 0
                  INVOKE     AsciiBase, addr szWork1, addr Code, 10
                     dec     Code
                     add     Code, 70h  ; F1 = 70, F2 = 71, etc.
                     mov     ecx, Code
                     mov     accel.key, cx
                  .break
               .endif
                  inc     eax
                  dec     Cnt1
            .endw
               mov     ebx, hAccelArray
               mov     ecx, AccelOff
               mov     al, accel.fVirt
               mov     byte ptr[ebx+ecx], al
               mov     ax, accel.key
               mov     word ptr[ebx+ecx+2], ax
               mov     ax, accel.cmd
               mov     word ptr[ebx+ecx+4], ax

               add     AccelOff, 6
               inc     Incr
               dec     Cnt
         .endw
         INVOKE     DestroyWindow, hTemp

         INVOKE     DestroyAcceleratorTable, hAccel
         INVOKE     CreateAcceleratorTable, hAccelArray, AccelCnt
            mov     hAccel, eax

;0900 4E00 7117 0900 4F00 7217

;FVIRTKEY   equ 1h
;FNOINVERT  equ 2h
;FSHIFT     equ 4h
;FCONTROL   equ 8h
;FALT       equ 10h

      .endif

         mov     mii.fMask, MIIM_DATA or MIIM_ID or MIIM_STATE or\
                            MIIM_SUBMENU or MIIM_CHECKMARKS or MIIM_BITMAP or MIIM_FTYPE
      INVOKE     SetFocus, hREdit
      .if hKeyM
         INVOKE     RegCloseKey, hKeyM
            and     hKeyM, 0
      .endif

         ret
LoadMenuItems  ENDP

;=========================================================================
; Load open file items PROCEDURE
;=========================================================================
LoadOpenItems PROC  uses ebx esi edi
LOCAL    Cnt:DWORD, ID
LOCAL    szBuff[64]:BYTE

      INVOKE     GetMenuItemCount, hSubMenuW
      .if eax == -1
            ret
      .endif
         mov     esi, 9401
         mov     ebx, eax
      .while (ebx)
         INVOKE     DeleteMenu, hSubMenuW, 0, MF_BYPOSITION
            inc     esi
            dec     ebx
      .endw
         lea     eax, szBuff
         mov     tci.pszText, eax                ; Pointer to string containing tab text
         mov     tci.cchTextMax, sizeof szBuff
      INVOKE     SendMessage,  hWndTab, TCM_GETITEMCOUNT, 0, 0
         dec     eax
         mov     ebx, eax
         mov     esi, 1                          ; Bypass Line tab
         mov     ID, 9401
      .while (ebx)
         INVOKE     SendMessage,  hWndTab, TCM_GETITEM, esi, addr tci
            mov     ecx, esi
            dec     ecx
         INVOKE     InsertMenu, hSubMenuW, ecx, MF_BYCOMMAND or\
                    MF_STRING, ID, addr szBuff
            inc     ID
            inc     esi
            dec     ebx
      .endw

         ret
LoadOpenItems  ENDP

;=========================================================================
; Customize menu PROCEDURE
;=========================================================================
MenuDlg  PROC  uses ebx esi edi  hdlg:DWORD, wMsg, wParam, lParam
;LOCAL    lf:LOGFONT
LOCAL    rect:RECT
LOCAL    ofn:OPENFILENAME
LOCAL    dItem:DWORD, Cnt, Incr, Len, Array
LOCAL    szWork[256]:BYTE, szWork1[64]:BYTE, szSetUp[256]:BYTE, szCurDir[256]:BYTE

      .if wMsg == WM_INITDIALOG
          MOVmd     hDlgSav, hdlg
            and     CloseOn, 0
            mov     szBuffA, 0
;            mov     eax, sizeof accel
;DSPValue hWnd, eax, 1, 'm'

         INVOKE     RtlZeroMemory, addr lf, sizeof lf
         INVOKE     lstrcpy, addr lf.lfFaceName, addr FontNameMS ;FontNameQT
            mov     lf.lfHeight, -8 ;-9
            mov     lf.lfWeight, 400
         INVOKE     CreateFontIndirect, addr lf
            mov     hFontD, eax     ; Dialog font

            mov     lf.lfHeight, -9
            mov     lf.lfWeight, 400
         INVOKE     CreateFontIndirect, addr lf
            mov     hFontLST, eax   ; List font

         INVOKE     GetDlgItem, hdlg, 445      ; Get the handle of the Listbox
            mov     hList45, eax               ; Save it
         INVOKE     GetDlgItem, hdlg, 34       ; Get the handle of the Static ctl
            mov     h34, eax
         INVOKE     SetFocus, h34

         .if Opt == 20 ; User code names
            INVOKE     SendDlgItemMessage, hdlg, 301, WM_SETFONT, hFontD, TRUE
            INVOKE     SendDlgItemMessage, hdlg, 302, WM_SETFONT, hFontD, TRUE
            INVOKE     SendDlgItemMessage, hdlg, 310, WM_SETFONT, hFontD, TRUE

            INVOKE     lstrcpy, addr szMenuItems, lParam
            INVOKE     lstrcat, addr szMenuItems, addr szUserKey

;--------------- [Open or create the user name registry] --------------- 
            INVOKE     RegCreateKeyEx, HKEY_CURRENT_USER, offset szMenuItems, 0, offset szREGSZ, 0,\
                       KEY_WRITE or KEY_READ, 0, addr hKeyM, addr lpdwDisp

;--------------- [Fill the Listbox with user code names] --------------- 
               mov     Cnt, 40
               mov     Incr, 1
            .while (Cnt)
               INVOKE     BaseAscii, Incr, addr szWork1, 2, 10, 0, 1, 0
                  mov     al, byte ptr szWork1
                  mov     byte ptr szUserK+2, al
                  mov     al, byte ptr szWork1+1
                  mov     byte ptr szUserK+3, al
                  mov     lpcbData, 63
               INVOKE     RegQueryValueEx, hKeyM, addr szUserK, 0, addr lpType, addr szNameR, addr lpcbData
               INVOKE     lstrcpy, addr szBuffP, addr szUserK
               INVOKE     lstrcat, addr szBuffP, addr szColSp
               INVOKE     lstrcat, addr szBuffP, addr szNameR
mov     byte ptr szBuffP+1, 'u'
               INVOKE     SendMessage, hList45, LB_ADDSTRING, 0, addr szBuffP
                  inc     Incr
                  dec     Cnt
            .endw
               jmp     MenuDone
         .endif

            mov     Incr, 301
            mov     Cnt, 10
         .while (Cnt)
            INVOKE     GetDlgItem, hdlg, Incr
               mov     ecx, eax
            .if Incr != 304 && Incr != 308
               INVOKE     SendMessage, ecx, WM_SETFONT, hFontD, TRUE
            .endif
               inc     Incr
               dec     Cnt
         .endw

            and     Len, 0
            mov     Incr, 1801
            mov     Cnt, 5
         .while (Cnt)
            INVOKE     GetDlgItem, hdlg, Incr
               mov     ecx, Len
               mov     hEdit01[ecx*4], eax
               inc     Len
               inc     Incr
               dec     Cnt
         .endw

         INVOKE     GetDlgItem, hdlg, 202
            mov     hComb01, eax
         INVOKE     GetDlgItem, hdlg, 203
            mov     hComb02, eax
         INVOKE     GetDlgItem, hdlg, 204
            mov     hComb03, eax
         INVOKE     SendMessage, hComb01, CB_SETITEMHEIGHT, -1, 13       ; Selection field
         INVOKE     SendMessage, hComb01, CB_SETITEMHEIGHT, 0, 13        ; List items
         INVOKE     SendMessage, hComb02, CB_SETITEMHEIGHT, -1, 13       ; Selection field
         INVOKE     SendMessage, hComb02, CB_SETITEMHEIGHT, 0, 12        ; List items
         INVOKE     SendMessage, hComb03, CB_SETITEMHEIGHT, -1, 13       ; Selection field
         INVOKE     SendMessage, hComb03, CB_SETITEMHEIGHT, 0, 13        ; List items
         INVOKE     SendMessage, hList45, LB_SETITEMHEIGHT, 0, 13        ; List items
         INVOKE     SendMessage, hList45, WM_SETFONT, hFontLST, TRUE

         INVOKE     LoadImage, hInst, 801, IMAGE_BITMAP, 14, 15, LR_LOADMAP3DCOLORS
            mov     hBmpU, eax
         INVOKE     LoadImage, hInst, 802, IMAGE_BITMAP, 14, 15, LR_LOADMAP3DCOLORS
            mov     hBmpD, eax
         INVOKE     GetDlgItem, hdlg, 446
            mov     hButtU, eax
         INVOKE     GetDlgItem, hdlg, 447
            mov     hButtD, eax
         INVOKE     SendMessage, hButtU, BM_SETIMAGE, IMAGE_BITMAP, hBmpU
         INVOKE     SendMessage, hButtD, BM_SETIMAGE, IMAGE_BITMAP, hBmpD

         INVOKE     GetDlgItem, hdlg, 1912
            mov     h1912, eax
         INVOKE     GetDlgItem, hdlg, 1915
            mov     h1915, eax

         INVOKE     GetDlgItem, hdlg, 201      ; Get the handle of the Checkbox
            mov     hCheck01, eax
;         INVOKE     GetDlgItem, hdlg, cb5      ; Get the handle of the Checkbox
;            mov     hCheck02, eax
         INVOKE     GetDlgItem, hdlg, 38       ; Get the handle of the Static ctl
            mov     h38, eax
         INVOKE     GetDlgItem, hdlg, 39       ; Get the handle of the Static ctl
            mov     h39, eax
         INVOKE     SendMessage, h38, WM_SETFONT, hFontD, TRUE
         INVOKE     SendMessage, h39, WM_SETFONT, hFontD, TRUE
         INVOKE     SendMessage, h38, WM_GETTEXT, 255, addr sz38

;---------- [Load Main menu names] ----------
         INVOKE     SendMessage, hComb01, CB_ADDSTRING, 0, addr szSelect
         INVOKE     SendMessage, hComb01, CB_SETITEMDATA, eax, 1234
           call     GetSubHandles

            and     Incr, 0
            mov     Cnt, 4
         .while (Cnt)
               mov     eax, Incr
               mov     ecx, MenuArray[eax*4]
            INVOKE     SendMessage, hComb01, CB_ADDSTRING, 0, ecx
               mov     ecx, eax
               mov     eax, Incr
               mov     edx, hBuildM[eax*4]
            INVOKE     SendMessage, hComb01, CB_SETITEMDATA, ecx, edx
               inc     Incr
               dec     Cnt
         .endw

            and     Opt, 0
         INVOKE     SendMessage, hComb01, CB_SETCURSEL, 0, 0 ;ecx, 0

;         INVOKE     GetMenuItemCount, hBuildM

;---------- [Load accelerators] ----------
         INVOKE     SendMessage, hComb02, CB_ADDSTRING, 0, addr szNone
            mov     Cnt, 26
         INVOKE     lstrcpy, addr szWork, addr szAccel01
            mov     byte ptr szWork+5, 'A'
         .while (Cnt)
            INVOKE     SendMessage, hComb02, CB_ADDSTRING, 0, addr szWork
               mov     ecx, eax
               mov     edx, 9
               shl     edx, 16
               mov     dl, byte ptr szWork+5
            INVOKE     SendMessage, hComb02, CB_SETITEMDATA, ecx, edx
               inc     byte ptr szWork+5
               dec     Cnt
         .endw

            and     Incr, 0
            mov     Cnt, 12
         .while (Cnt)
               mov     byte ptr szWork, 'F'
               mov     byte ptr szWork+1, 0
               inc     Incr
            INVOKE     wsprintf, addr szWork1, addr fmat1, Incr
            INVOKE     lstrcat, addr szWork, addr szWork1
            INVOKE     SendMessage, hComb02, CB_ADDSTRING, 0, addr szWork
               mov     ecx, eax
               mov     edx, 1
               shl     edx, 16
               mov     dl, 70h
               mov     ebx, Incr
               dec     ebx
               add     dl, bl
            INVOKE     SendMessage, hComb02, CB_SETITEMDATA, ecx, edx
               dec     Cnt
         .endw

            and     Len, 0
            mov     Array, 6
         .while (Array)
               and     Incr, 0
               mov     Cnt, 12
            .while (Cnt)
                  mov     eax, Len
                  mov     ecx, AccelArray[eax*4]
               INVOKE     lstrcpy, addr szWork, ecx ;addr szAccel02
                  inc     Incr
               INVOKE     wsprintf, addr szWork1, addr fmat1, Incr
               INVOKE     lstrcat, addr szWork, addr szWork1
               INVOKE     SendMessage, hComb02, CB_ADDSTRING, 0, addr szWork
                  mov     ecx, eax
                  mov     eax, Len
                  mov     edx, ValueArray[eax*4]
                  shl     edx, 16
                  mov     dl, 70h
                  mov     ebx, Incr
                  dec     ebx
                  add     dl, bl
               INVOKE     SendMessage, hComb02, CB_SETITEMDATA, ecx, edx
                  dec     Cnt
            .endw
               inc     Len
               dec     Array
         .endw

            mov     Cnt, 26
         INVOKE     lstrcpy, addr szWork, addr szAccel08
            mov     byte ptr szWork+4, 'A'
            mov     byte ptr szWork+5, 0
         .while (Cnt)
            INVOKE     SendMessage, hComb02, CB_ADDSTRING, 0, addr szWork
               mov     ecx, eax
               mov     edx, 11h
               shl     edx, 16
               mov     dl, byte ptr szWork+4
            INVOKE     SendMessage, hComb02, CB_SETITEMDATA, ecx, edx
               inc     byte ptr szWork+4
               dec     Cnt
         .endw
         INVOKE     SendMessage, hComb02, CB_SETCURSEL, 0, 0
         INVOKE     lstrcpy, addr szReditM, lParam

            and     Len, 0
            mov     Array, 2
         .while (Array)
               mov     eax, Len
               mov     ecx, StateArray[eax*4]
            INVOKE     lstrcpy, addr szWork, ecx
            INVOKE     SendMessage, hComb03, CB_ADDSTRING, 0, addr szWork
               mov     ecx, eax
            INVOKE     SendMessage, hComb03, CB_SETITEMDATA, ecx, Len
               inc     Len
               dec     Array
         .endw
         INVOKE     SendMessage, hComb03, CB_SETCURSEL, 0, 0

; WS_VISIBLE or
;---------- [Create a hidden work Listbox] ----------
         INVOKE     CreateWindowEx, WS_EX_TOPMOST, addr ListboxClass, 0, WS_CHILD or\
                    WS_VSCROLL or LBS_HASSTRINGS,\
                    522, 29, 400, 400, hWnd, 85, hInst, 0
            mov     hList, eax

            mov     mii.cbSize, sizeof mii
            mov     mii.fMask, MIIM_DATA or MIIM_ID or MIIM_STATE or MIIM_SUBMENU or MIIM_TYPE
            jmp     MenuDone

      .elseif wMsg == WM_CTLCOLORDLG 
         .if hBR
            INVOKE     DeleteObject, hBR
         .endif
         INVOKE     CreateSolidBrush, 00ffffe0h
            mov     hBR, eax
            ret

      .elseif wMsg == WM_CTLCOLORSTATIC
            mov     eax, lParam
         .if eax == h34 || eax == h38 || eax == h39
            INVOKE     SetBkColor, wParam, 00000000h   ; Background color is black
            INVOKE     SetTextColor, wParam, 00ffff00h ; Text color of edit box is lt blue
            INVOKE     GetStockObject, BLACK_BRUSH     ; Select the black brush for background

         .else
            INVOKE     SetBkColor, wParam, 00ffffe0h
            INVOKE     SetTextColor, wParam, 00000000h
            .if hBR
               INVOKE     DeleteObject, hBR
            .endif
            INVOKE     CreateSolidBrush, 00ffffe0h
               mov     hBR, eax
         .endif
            ret

      .elseif wMsg == WM_CTLCOLORLISTBOX || wMsg == WM_CTLCOLOREDIT
         INVOKE     SetBkColor, wParam, 00000000h   ; Background color is black
         INVOKE     SetTextColor, wParam, 00ffff00h ; Text color of edit box is lt blue
         INVOKE     GetStockObject, BLACK_BRUSH     ; Select the black brush for background
            ret

      .elseif wMsg == WM_CLOSE

EndIt:
;---------- [Delete and rewrite the menu registry] ----------
         .if Opt != 20 && wParam != 301              ; User code names or Cancel
               mov     CloseOn, 1
              call     ReWrite
         .endif
            and     hWndDlg, 0
            and     Opt, 0
         .if hKeyM
            INVOKE     RegCloseKey, hKeyM
         .endif
         .if hBR
            INVOKE     DeleteObject, hBR
         .endif
         INVOKE     DeleteObject, hFontD
         INVOKE     DeleteObject, hFontLST
         INVOKE     DeleteObject, hBmpU
         INVOKE     DeleteObject, hBmpD
         INVOKE     SetFocus, hREdit
         INVOKE     EndDialog, hdlg, 0
            and     hDlgSav, 0
            mov     eax, TRUE
            jmp     MenuRet

      .elseif wMsg == WM_DRAWITEM
         .if wParam == 445
            INVOKE     DrawList, lParam
         .endif
            jmp     MenuDone

      .elseif wMsg != WM_COMMAND
            jmp     MenuDone
      .endif

         mov     ecx, wParam
         shr     ecx, 16
         mov     edx, lParam

;---------- [Check for menu selection] ----------
      .if ecx == LBN_SELCHANGE && edx == hList45 && Opt
            and     NotAvail, 0
         INVOKE     SendMessage, hList45, LB_GETCURSEL, 0, 0
         .if eax == LB_ERR
               jmp     MenuDone
         .endif
            mov     SaveSel, eax
         .if Opt != 20
            INVOKE     SendMessage, hList, LB_GETTEXT, SaveSel, addr szWork
            .if byte ptr szWork+9 == 'S' && byte ptr szWork+11 == 'B' &&\
                byte ptr szWork+16 == ':' || byte ptr szWork[eax-1] == '^' ||\
                byte ptr szWork == 'S' && byte ptr szWork+2 == 'B' &&\
                byte ptr szWork+7 == ':'
                  mov     ecx, BST_CHECKED
            .else
                  mov     ecx, BST_UNCHECKED
            .endif
            INVOKE     SendMessage, hCheck01, BM_SETCHECK, ecx, 0   ; Sets SubMenu to checked/unchecked
         .else
            INVOKE     SendMessage, hList45, LB_GETTEXT, SaveSel, addr szPathM
            INVOKE     lstrcpyn, addr szBuffN, addr szPathM, 5
            INVOKE     lstrcpy, addr szBuffP, addr szPathM+6
            INVOKE     SetDlgItemText, hdlg, 401, addr szBuffP
            INVOKE     SetDlgItemText, hdlg, 402, addr szBuffN
               mov     UpdateOn, 1
               jmp     MenuDone
         .endif
            mov     wParam, 304

      .elseif ecx == CBN_SELCHANGE && edx == hComb01
            and     NotAvail, 0
         INVOKE     SendMessage, hComb01, CB_GETCURSEL, 0, 0
         .if eax != CB_ERR && eax
;            inc     eax
               mov     Opt, eax
              call     LoadMenus
         .else
               and     Opt, 0
            INVOKE     SendMessage, hList45, LB_RESETCONTENT, 0, 0
            INVOKE     SendMessage, hList, LB_RESETCONTENT, 0, 0
         .endif
         INVOKE     SendMessage, h1912, WM_SETTEXT, 0, addr szMIName
         INVOKE     SendMessage, h1915, WM_SETTEXT, 0, addr szTxtExe
         INVOKE     SendMessage, hComb02, CB_SETCURSEL, 0, 0
         INVOKE     SetDlgItemText, hdlg, 401, addr szNull
         INVOKE     SetDlgItemText, hdlg, 402, addr szNull
         INVOKE     SetDlgItemText, hdlg, 403, addr szNull
         INVOKE     SetDlgItemText, hdlg, 404, addr szNull
         INVOKE     SetDlgItemText, hdlg, 405, addr szNull
         INVOKE     EnableWindow, hEdit04, 0
         INVOKE     EnableWindow, hEdit05, 0
         INVOKE     EnableWindow, h38, 0
         INVOKE     SendMessage, h38, WM_SETTEXT, 0, addr szNull
         .if Opt == 2
            INVOKE     SendMessage, h1915, WM_SETTEXT, 0, addr szDllName
            INVOKE     EnableWindow, hEdit04, 1
            INVOKE     EnableWindow, hEdit05, 1
            INVOKE     EnableWindow, h38, 1
            INVOKE     SendMessage, h38, WM_SETTEXT, 0, addr sz38
         .elseif Opt == 1 || Opt == 3
            INVOKE     SendMessage, h1915, WM_SETTEXT, 0, addr szCmdLine
         .endif
            jmp     MenuDone

      .elseif ecx == CBN_SELCHANGE && edx == hComb02
            and     NotAvail, 0
         INVOKE     SendMessage, hComb02, CB_GETCURSEL, 0, 0
         .if eax != CB_ERR && eax

;---------- [Check if accelerator is already in use] ----------
            INVOKE     SendMessage, hComb02, CB_GETITEMDATA, eax, 0
               mov     ebx, eax
               xor     ecx, ecx
               mov     esi, hAccelArray
               mov     edx, AccelCnt
            .while (edx)
                  mov     eax, dword ptr[esi+ecx]
                  shl     eax, 16
                  mov     ax, word ptr[esi+ecx+2]
               .if eax == ebx
                  INVOKE     MessageBox, NULL, addr szInUse, addr AppName, MB_OK or\
                             MB_ICONWARNING or MB_TASKMODAL or MB_TOPMOST
                     mov     NotAvail, 1
                  .break
               .endif
                  add     ecx, 6
                  dec     edx
            .endw

         .endif
            jmp     MenuDone

      .endif

         mov     eax, wParam
        cwde
;DSPValue hWnd, eax, 1, 't'

      .if eax == 301 || eax == 302
            jmp     EndIt

;---------- [Setup the display for Add or Update] ----------
; 303 = Add A Menu Item  304 = Edit The Menu Item  307 = Add A SubMenu
      .elseif eax == 303 || eax == 304 || eax == 307
mov     TypeCmd, eax
            mov     UpdateOn, 1
         INVOKE     SetFocus, h34
         INVOKE     SendMessage, hList45, LB_GETCURSEL, 0, 0
         .if wParam == 304 && Opt != 20
            .if eax == LB_ERR
                  and     UpdateOn, 0
                  jmp     MenuDone
            .endif
         .endif

         .if wParam == 307 && Opt == 20 ; 307 = Add A SubMenu
               jmp     MenuDone
         .endif
         .if eax == LB_ERR
            INVOKE     MessageBox, NULL, addr szNoSelM, addr AppName, MB_OK or\
                       MB_ICONWARNING or MB_TASKMODAL or MB_TOPMOST
            INVOKE     SetFocus, h34
               and     UpdateOn, 0
               jmp     MenuDone
         .endif
            mov     SaveSel, eax
         INVOKE     SendMessage, h1912, WM_SETTEXT, 0, addr szMIName
         INVOKE     SendMessage, hCheck01, BM_SETCHECK, BST_UNCHECKED, 0   ; Sets SubMenu to unchecked
         INVOKE     SendMessage, hList, LB_GETTEXT, SaveSel, addr szPathM
         .if byte ptr szPathM[eax-1] == '^' ||\
             byte ptr szPathM+9 == 'S' && byte ptr szPathM+11 == 'B' &&\
             byte ptr szPathM+16 == ':'   ; = SUBMENU:
            .if byte ptr szPathM[eax-1] == '^'
               INVOKE     SendMessage, h1912, WM_SETTEXT, 0, addr szSIName
            .endif
            INVOKE     SendMessage, hCheck01, BM_SETCHECK, BST_CHECKED, 0   ; Sets SubMenu to checked
         .endif

         INVOKE     SendMessage, hComb02, CB_SETCURSEL, 0, 0
         INVOKE     SendMessage, hComb03, CB_SETCURSEL, 0, 0
         INVOKE     SetDlgItemText, hdlg, 401, addr szNull
         INVOKE     SetDlgItemText, hdlg, 402, addr szNull
         INVOKE     SetDlgItemText, hdlg, 403, addr szNull
         INVOKE     SetDlgItemText, hdlg, 404, addr szNull
         INVOKE     SetDlgItemText, hdlg, 405, addr szNull
            mov     byte ptr szBuffN, 0
            mov     byte ptr szBuffP, 0
            mov     byte ptr szBuffF, 0
            mov     byte ptr szBuffW, 0
;         INVOKE     SendMessage, h1912, WM_SETTEXT, 0, addr szMIName
         INVOKE     SendMessage, h1915, WM_SETTEXT, 0, addr szTxtExe
         INVOKE     EnableWindow, hComb02, 1
         INVOKE     EnableWindow, hComb03, 1
         INVOKE     EnableWindow, hEdit03, 1
         .if Opt == 2
            INVOKE     SendMessage, h1915, WM_SETTEXT, 0, addr szDllName
            INVOKE     EnableWindow, hEdit04, 1
            INVOKE     EnableWindow, hEdit05, 1
            INVOKE     EnableWindow, h38, 1
            INVOKE     SendMessage, h38, WM_SETTEXT, 0, addr sz38
         .elseif Opt == 1 || Opt == 3
            INVOKE     SendMessage, h1915, WM_SETTEXT, 0, addr szCmdLine
         .endif

         .if wParam == 304 || wParam == 307 ; 304 = Edit The Menu Item - 307 = Add A SubMenu
            .if !SaveSel
                  and     UpdateOn, 0
                  jmp     MenuDone
            .endif
            INVOKE     SendMessage, hList, LB_GETTEXT, SaveSel, addr szPathM
            .if byte ptr szPathM+9 == '-' && byte ptr szPathM+15 == 'S' && wParam == 304 ||\
                byte ptr szPathM == '-' && byte ptr szPathM+6 == 'S' && wParam == 304
                  and     UpdateOn, 0
                  jmp     MenuDone
            .endif

            .if wParam == 307 ||\            ; 307 = Add A SubMenu
                byte ptr szPathM+9 == 'S' && byte ptr szPathM+11 == 'B' &&\
                byte ptr szPathM+16 == ':'   ; = SUBMENU: Edit
               INVOKE     SendMessage, hCheck01, BM_SETCHECK, BST_CHECKED, 0   ; Sets SubMenu to checked
               INVOKE     SendMessage, h1912, WM_SETTEXT, 0, addr szSMName
               INVOKE     SendMessage, hComb02, CB_SETCURSEL, -1, 0
               INVOKE     SendMessage, hComb03, CB_SETCURSEL, -1, 0
               INVOKE     EnableWindow, hComb02, 0
               INVOKE     EnableWindow, hComb03, 0
               INVOKE     EnableWindow, hEdit03, 0
               INVOKE     EnableWindow, hEdit04, 0
               INVOKE     EnableWindow, hEdit05, 0
               INVOKE     EnableWindow, h38, 0
               INVOKE     SendMessage, h38, WM_SETTEXT, 0, addr szNull
               .if wParam == 307
                     jmp     MenuDone
               .endif
            .endif

            .if byte ptr szPathM+9 == 'S' && byte ptr szPathM+11 == 'B' &&\
                byte ptr szPathM+16 == ':'
         INVOKE     SendMessage, h1912, WM_SETTEXT, 0, addr szSMName
               INVOKE     lstrcpy, addr szBuffN, addr szPathM+18
                  mov     wParam, 315 ; 315 = SUBMENU:
MOVmd     TypeCmd, 315
                  jmp     GetOut
            .else
               INVOKE     lstrcpyn, addr szNameR, addr szPathM, 10
               INVOKE     lstrcpy, addr szPathM, addr szPathM+9
            .endif

            INVOKE     lstrlen, addr szPathM
               mov     Cnt, eax
               mov     ecx, eax
               xor     esi, esi
               xor     edi, edi
               lea     edx, szBuffN
               and     Incr, 0
            .while (ecx)
                  mov     al, byte ptr szPathM[esi]
               .if al == ':' && byte ptr szPathM[esi+1] != '\'
                     mov     byte ptr [edx+edi], 0
                     xor     edi, edi
                     inc     Incr
                  .if Incr == 1
                        lea     edx, szBuffP
                  .elseif Incr == 2
                        lea     edx, szBuffF
                  .elseif Incr == 3
                        lea     edx, szBuffW
                  .else
                     .break
                  .endif
               .else
                     mov     byte ptr [edx+edi], al
                     inc     edi
               .endif
                  inc     esi
                  dec     ecx
            .endw
               mov     byte ptr [edx+edi], 0

;---------- [Check for accelerators] ----------
               and     AccelOn, 0
               mov     ecx, Cnt
               xor     eax, eax
            .while (ecx)
               .if byte ptr szPathM[eax] == 9
                     inc     eax
                     mov     Len, eax
                    push     ecx
                  INVOKE     lstrcpyn, addr szBuffN, addr szPathM, eax
                     pop     ecx
                     mov     eax, Len
                  .while (ecx)
                     .if byte ptr szPathM[eax] == ':'
                           inc     eax
                           mov     ecx, eax
                           mov     eax, Len
                           sub     ecx, eax
                        INVOKE     lstrcpyn, addr szWork1, addr szPathM[eax], ecx
                        INVOKE     SendMessage, hComb02, CB_FINDSTRINGEXACT, -1, addr szWork1
                        .if eax != CB_ERR
                           INVOKE     SendMessage, hComb02, CB_SETCURSEL, eax, 0
                           INVOKE     SendMessage, hComb02, CB_GETITEMDATA, eax, 0
                              mov     AccelOn, eax
                        .endif
                        .break
                     .endif
                        inc     eax
                        dec     ecx
                  .endw
                  .break
               .endif
                  inc     eax
                  dec     ecx
            .endw

;---------- [Check for menu state] ----------
            INVOKE     lstrlen, addr szPathM
            .if byte ptr szPathM[eax-2] == ';' && byte ptr szPathM[eax-1] == '1' ||\
                byte ptr szPathM[eax-3] == ';' && byte ptr szPathM[eax-2] == '1'
               INVOKE     SendMessage, hComb03, CB_SETCURSEL, 1, 0
            .endif
         .endif

GetOut:
;         INVOKE     SendMessage, hCheck02, BM_SETCHECK, BST_UNCHECKED, 0   ; Sets ID Only to unchecked
;         .if !szBuffP
;            INVOKE     SendMessage, hCheck02, BM_SETCHECK, BST_CHECKED, 0  ; Sets ID Only to checked
;         .endif
            and     exeOn, 0
         .if wParam == 304 && Opt == 2
            INVOKE     lstrlen, addr szBuffP
            .if byte ptr szBuffP[eax-3] == 'e' || byte ptr szBuffP[eax-3] == 'E'
                  mov     exeOn, 1
            .endif
         .endif

         .if Opt == 2
            INVOKE     lstrlen, addr szBuffW
            .if byte ptr szBuffW[eax-3] == ';'
                  mov     byte ptr szBuffW[eax-3], 0
            .elseif byte ptr szBuffP[eax-2] == ';'
                  mov     byte ptr szBuffW[eax-2], 0
            .elseif byte ptr szBuffP[eax-1] == '^'
                  mov     byte ptr szBuffW[eax-1], 0
            .endif
         .endif
         INVOKE     lstrlen, addr szBuffP
         .if byte ptr szBuffP[eax-3] == ';'
               mov     byte ptr szBuffP[eax-3], 0
         .elseif byte ptr szBuffP[eax-2] == ';'
               mov     byte ptr szBuffP[eax-2], 0
         .elseif byte ptr szBuffP[eax-1] == '^'
               mov     byte ptr szBuffP[eax-1], 0
         .endif

         INVOKE     SendMessage, hList45, LB_GETITEMDATA, SaveSel, 0
         INVOKE     wsprintf, addr szWork1, addr fmat1, eax
         INVOKE     SetDlgItemText, hdlg, 401, addr szBuffN
         INVOKE     SetDlgItemText, hdlg, 402, addr szWork1
         INVOKE     SetDlgItemText, hdlg, 403, addr szBuffP
         INVOKE     SetDlgItemText, hdlg, 404, addr szNull
         INVOKE     SetDlgItemText, hdlg, 405, addr szNull
         .if Opt == 2 && !exeOn
            INVOKE     SetDlgItemText, hdlg, 404, addr szBuffF
            INVOKE     SetDlgItemText, hdlg, 405, addr szBuffW
         .endif
         INVOKE     lstrlen, addr szBuffP
            dec     eax
         INVOKE     SendMessage, hEdit03, EM_SETSEL, eax, eax
            and     SubmenuOn, 0
         INVOKE     IsDlgButtonChecked, hDlgSav, 201
         .if eax && TypeCmd == 304 ;304 = Edit The Menu Item
               mov     SubmenuOn, 1
         .endif
            jmp     MenuDone

;---------- [Browse] ----------
      .elseif eax == 308
         INVOKE     RtlZeroMemory, addr ofn, sizeof ofn
            mov     ofn.lStructSize, sizeof ofn
         INVOKE     lstrcpy, addr szSetUp, addr szAll
         INVOKE     GetCurrentDirectory, lengthof szCurDir, addr szCurDir
            lea     eax, szSetUp
            mov     ofn.lpstrFile, eax
            mov     ofn.nMaxFile, lengthof szSetUp
            lea     eax, szCurDir
            mov     ofn.lpstrInitialDir, eax
            mov     ofn.lpstrFilter, 0
            mov     ofn.lpstrTitle, offset szGetHelp
            mov     ofn.Flags, OFN_NOVALIDATE
         INVOKE     GetOpenFileName, addr ofn
         .if !eax                         ; Cancel'ed or error occurred
            INVOKE     SetFocus, h34
               jmp     MenuDone
         .endif
         INVOKE     SetDlgItemText, hdlg, 403, ofn.lpstrFile
         INVOKE     lstrlen, ofn.lpstrFile
            dec     eax
         INVOKE     SendMessage, hEdit03, EM_SETSEL, eax, eax
            jmp     MenuDone

;---------- [Preview menu] ----------
      .elseif eax == 309
         INVOKE     SetFocus, h34
         .if !Opt
               jmp     MenuDone
         .endif
         INVOKE     SendMessage, hComb01, CB_GETITEMDATA, Opt, 0
            mov     hSubMenuM, eax
         INVOKE     GetWindowRect, hList45, addr rect
           push     rect.left
           push     rect.top
         INVOKE     GetWindowRect, hWnd, addr rect
            pop     edx
            pop     ecx
         INVOKE     TrackPopupMenu, hSubMenuM, TPM_LEFTALIGN,\
                    ecx, edx, 0, hDlgSav, addr rect

      .elseif eax > 3100 && eax < 3500
;DSPValue hWnd, eax, 1, 'm'
mov     eax, 1
ret

;---------- [Up Down buttons] ----------
      .elseif eax == 446 || eax == 447
         .if !Opt
               jmp     MenuDone
         .endif
         INVOKE     SetFocus, h34
         INVOKE     SendMessage, hList45, LB_GETCURSEL, 0, 0
         .if eax == LB_ERR || !eax
               jmp     MenuDone
         .endif
            mov     SelList, eax
         INVOKE     SendMessage, hList45, LB_GETCOUNT, 0, 0
            dec     eax
            mov     Cnt, eax
            mov     eax, SelList
         .if wParam == 446 && eax < 2 || wParam == 447 && eax >= Cnt
               jmp     MenuDone
         .endif

         INVOKE     SendMessage, hList, LB_GETTEXT, SelList, addr szWork
         INVOKE     SendMessage, hList45, LB_GETTEXT, SelList, addr szWork1
         INVOKE     SendMessage, hList45, LB_GETITEMDATA, SelList, 0
            mov     hData, eax
         INVOKE     SendMessage, hList, LB_DELETESTRING, SelList, 0
         INVOKE     SendMessage, hList45, LB_DELETESTRING, SelList, 0
         .if wParam == 446
               dec     SelList
         .else
               inc     SelList
         .endif
         INVOKE     SendMessage, hList, LB_INSERTSTRING, SelList, addr szWork
         INVOKE     SendMessage, hList45, LB_INSERTSTRING, SelList, addr szWork1
         INVOKE     SendMessage, hList45, LB_SETITEMDATA, SelList, hData
         INVOKE     SendMessage, hList45, LB_SETCURSEL, SelList, 0
           call     ReWrite
            jmp     MenuDone

;---------- [Delate a menu item] ----------
      .elseif eax == 305                ; Remove
mov     TypeCmd, eax
         INVOKE     SetFocus, h34
         INVOKE     SendMessage, hList45, LB_GETCURSEL, 0, 0
            cmp     eax, 0
             je     MenuDone
         .if eax == LB_ERR
            INVOKE     MessageBox, NULL, addr szNoSelM, addr AppName, MB_OK or\
                       MB_ICONWARNING or MB_TASKMODAL or MB_TOPMOST
            INVOKE     SetFocus, h34
               jmp     MenuDone
         .endif
            mov     dItem, eax

;---------- [Free up the accelerator] ----------
         INVOKE     SendMessage, hComb02, CB_GETCURSEL, 0, 0
         .if eax != CB_ERR && eax
            INVOKE     SendMessage, hComb02, CB_GETITEMDATA, eax, 0
               mov     ebx, eax
               xor     ecx, ecx
               mov     esi, hAccelArray
               mov     edx, AccelCnt
            .while (edx)
                  mov     eax, dword ptr[esi+ecx]
                  shl     eax, 16
                  mov     ax, word ptr[esi+ecx+2]
               .if eax == ebx
                     mov     dword ptr[esi+ecx], 1234
                     mov     word ptr[esi+ecx+4], 5678
                  .break
               .endif
                  add     ecx, 6
                  dec     edx
            .endw
         .endif

         INVOKE     SendMessage, hList45, LB_DELETESTRING, dItem, 0
         INVOKE     SendMessage, hList, LB_DELETESTRING, dItem, 0
           push     mItem
           call     ReWrite
            pop     mItem
         INVOKE     DrawMenuBar, hWnd

         INVOKE     SendMessage, hCheck01, BM_SETCHECK, BST_UNCHECKED, 0   ; Sets SubMenu to unchecked
         INVOKE     SendMessage, hComb02, CB_SETCURSEL, 0, 0
         INVOKE     SetDlgItemText, hdlg, 401, addr szNull
         INVOKE     SetDlgItemText, hdlg, 402, addr szNull
         INVOKE     SetDlgItemText, hdlg, 403, addr szNull
         INVOKE     SetDlgItemText, hdlg, 404, addr szNull
         INVOKE     SetDlgItemText, hdlg, 405, addr szNull

;---------- [Insert a Separator] ----------
      .elseif eax == 306                ; 306 = Add A Separator
mov     TypeCmd, eax
         INVOKE     SetFocus, h34
         INVOKE     SendMessage, hList45, LB_GETCURSEL, 0, 0
         .if eax == LB_ERR
            INVOKE     MessageBox, NULL, addr szNoSelM, addr AppName, MB_OK or\
                       MB_ICONWARNING or MB_TASKMODAL or MB_TOPMOST
            INVOKE     SetFocus, h34
               jmp     MenuDone
         .endif
           push     eax
         INVOKE     lstrcpy, addr szBuffN, addr szSepN
         INVOKE     wsprintf, addr szIndexM, addr fmat4, mItem
         INVOKE     lstrcpy, addr szPathM, addr szNameM
         INVOKE     lstrcat, addr szPathM, addr szSepN
            pop     ecx
            inc     ecx
;         INVOKE     SendMessage, hList, LB_GETTEXT, ecx, addr szWork
;         .if byte ptr szWork[eax-1] == '^'
;            INVOKE     lstrcat, addr szPathM, addr szCar
;         .endif
            mov     lParam, 306
            jmp     Separator


;---------- [Update the menu item] ----------
      .elseif wParam == 310
;DSPValue hWnd, Opt, 1, 'm'
            and     CloseOn, 0
            and     sw4, 0
         INVOKE     SetFocus, h34
;         .if !Opt || !UpdateOn || !TypeCmd
         .if !Opt && !UpdateOn && !TypeCmd
               jmp     MenuDone
         .endif
         INVOKE     GetDlgItemText, hdlg, 401, addr szBuffN, 250
         .if !eax
               jmp     ErrMsg
         .endif
         .if Opt == 20
            INVOKE     GetDlgItemText, hdlg, 402, addr szBuffP, 250
             MOVmd     TypeCmd, 304
               jmp     AllDone
         .endif
         .if TypeCmd == 307 || TypeCmd == 315 ; 307 = Add A SubMenu - 315 = SUBMENU:
            INVOKE     lstrcpy, addr szWork, addr szSub
            INVOKE     lstrcat,addr szWork, addr szBuffN
         .endif
         .if TypeCmd != 307 && TypeCmd != 315 ; 307 = Add A SubMenu - 315 = SUBMENU:
            INVOKE     GetDlgItemText, hdlg, 403, addr szBuffP, 250
            .if !eax
                  jmp     ErrMsg
            .endif

               and     exeOn, 0
            INVOKE     lstrlen, addr szBuffP
            .if byte ptr szBuffP[eax-3] == 'e' || byte ptr szBuffP[eax-3] == 'E'
                  mov     exeOn, 1
            .endif

            .if SubmenuOn
               .if Opt == 4 || exeOn || Opt == 1 || Opt == 3
                  INVOKE     lstrcat, addr szBuffP, addr szCar
               .endif
            .endif
            .if Opt == 2 && !exeOn
               INVOKE     GetDlgItemText, hdlg, 404, addr szBuffF, 63
               .if !eax
                     jmp     ErrMsg
               .endif
               INVOKE     GetDlgItemText, hdlg, 405, addr szBuffW, 63
               .if !eax
                     jmp     ErrMsg
               .endif
               .if SubmenuOn
                  INVOKE     lstrcat, addr szBuffW, addr szCar
               .endif
            .endif
         .endif

AllDone:
;            mov     sw4, 15
;         INVOKE     SendMessage, hDlgSav, WM_COMMAND, B0, TypeCmd


         .if Opt == 20 ;UserOn
            INVOKE     lstrcpy, addr szPathM, addr szBuffP
            INVOKE     lstrcat, addr szPathM, addr szColSp
            INVOKE     lstrcat, addr szPathM, addr szBuffN
         .else
               mov     byte ptr szBuffA, 0
            .if TypeCmd == 304 || TypeCmd == 315 ; 304 = Edit The Menu Item - 315 = SUBMENU:
               INVOKE     GetDlgItemText, hdlg, 402, addr szWork1, 63
               INVOKE     lstrcpy, addr szIndexM, addr szWork1
            .else
               INVOKE     wsprintf, addr szIndexM, addr fmat4, mItem
            .endif
            .if TypeCmd == 304
               INVOKE     lstrcpy, addr szPathM, addr szNameR
            .else       ; 303 = Add A Menu Item - 307 = Add A SubMenu - 315 = SUBMENU:
               INVOKE     lstrcpy, addr szPathM, addr szNameM
            .endif
            .if TypeCmd == 307 || TypeCmd == 315
               INVOKE     lstrcat, addr szPathM, addr szSub
            .endif
            INVOKE     lstrcat, addr szPathM, addr szBuffN
            .if TypeCmd != 307 && TypeCmd != 315 ; 307 = Add A SubMenu - 315 = SUBMENU:

;---------- [Check for accelerator] ----------
               INVOKE     SendMessage, hComb02, CB_GETCURSEL, 0, 0
               .if eax != CB_ERR && eax && !NotAvail
                     mov     ecx, eax
                    push     ecx
                  INVOKE     SendMessage, hComb02, CB_GETLBTEXT, ecx, addr szBuffA
                  INVOKE     lstrcat, addr szPathM, addr szHT
                  INVOKE     lstrcat, addr szPathM, addr szBuffA
                     pop     ecx
                  INVOKE     SendMessage, hComb02, CB_GETITEMDATA, ecx, 0
                  .if !AccelOn
                        mov     AccelOn, eax
                  .endif
                  .if AccelOn && AccelOn != eax
                        mov     ebx, AccelOn
                        mov     AccelOn, eax
                        jmp     FreeUp
                  .endif

;---------- [Free up the accelerator] ----------
               .elseif AccelOn
                     mov     ebx, AccelOn
FreeUp:
                     xor     ecx, ecx
                     mov     esi, hAccelArray
                     mov     edx, AccelCnt
                  .while (edx)
                        mov     eax, dword ptr[esi+ecx]
                        shl     eax, 16
                        mov     ax, word ptr[esi+ecx+2]
                     .if eax == ebx
                           mov     dword ptr[esi+ecx], 1234
                           mov     word ptr[esi+ecx+4], 5678
                        .break
                     .endif
                        add     ecx, 6
                        dec     edx
                  .endw
               .endif

               INVOKE     lstrcat, addr szPathM, addr szColNS
               INVOKE     lstrcat, addr szPathM, addr szBuffP
               .if Opt == 2  ; Addins
                  INVOKE     lstrcat, addr szPathM, addr szColNS
                  INVOKE     lstrcat, addr szPathM, addr szBuffF
                  INVOKE     lstrcat, addr szPathM, addr szColNS
                  INVOKE     lstrcat, addr szPathM, addr szBuffW
               .endif

;---------- [Check for menu state] ----------
               INVOKE     SendMessage, hComb03, CB_GETCURSEL, 0, 0
               .if eax != CB_ERR
                     mov     ecx, eax
                     add     cl, 30h
                     mov     byte ptr szSColZ+1, cl
                  INVOKE     lstrlen, addr szPathM
                  .if byte ptr szPathM[eax-1] == '^' && byte ptr szPathM[eax-3] != ';'
                     INVOKE     lstrcpyn, addr szPathM, addr szPathM, eax
                     INVOKE     lstrcat, addr szPathM, addr szSColZ
                     INVOKE     lstrcat, addr szPathM, addr szCar
                  .elseif byte ptr szPathM[eax-1] != '^' && byte ptr szPathM[eax-2] != ';'
                     INVOKE     lstrcat, addr szPathM, addr szSColZ
                  .elseif byte ptr szPathM[eax-2] == ';'
                     mov     byte ptr szPathM[eax-1], cl
                  .elseif byte ptr szPathM[eax-3] == ';'
                     mov     byte ptr szPathM[eax-2], cl
                  .endif
               .endif

            .endif
         .endif

;---------- [Update a menu item] ----------
         .if TypeCmd == 304 || TypeCmd == 315 ; 304 = Edit The Menu Item - 315 = SUBMENU:
            INVOKE     SendMessage, hList45, LB_GETCURSEL, 0, 0
               mov     dItem, eax
            .if Opt == 20 ;UserOn
               INVOKE     SendMessage, hList45, LB_DELETESTRING, dItem, 0
               INVOKE     SendMessage, hList45, LB_INSERTSTRING, dItem, addr szPathM
                  mov     byte ptr szBuffP+1, 'c'
               INVOKE     RegSetValueEx, hKeyM, addr szBuffP, 0, REG_SZ, addr szBuffN, lpcbData
            .else

               INVOKE     lstrlen, addr szPathM
               .if byte ptr szPathM[eax-1] == '^'
                  INVOKE     lstrcpy, addr szWork, addr szSpaces
                  INVOKE     lstrcat, addr szWork, addr szBuffN
                  INVOKE     lstrcpy, addr szBuffN, addr szWork
               .endif

               .if szBuffA       ; Accelerator
                  INVOKE     lstrcat, addr szBuffN, addr szSpace4
                  INVOKE     lstrcat, addr szBuffN, addr szBuffA
                  INVOKE     SendMessage, hComb02, CB_GETCURSEL, 0, 0
                  .if eax != CB_ERR && eax
                     INVOKE     SendMessage, hComb02, CB_GETITEMDATA, eax, 0
                        mov     ecx, AccelCnt
                       imul     ecx, 6
                        inc     AccelCnt
                        mov     ebx, hAccelArray
                        mov     edx, eax
                        shl     edx, 16
                        shr     eax, 16
                        mov     dx, ax
                        mov     dword ptr[ebx+ecx], edx
                        mov     ax, word ptr mItem
                        mov     word ptr[ebx+ecx+4], ax
                  .endif
               .endif

               INVOKE     SendMessage, hList45, LB_GETITEMDATA, dItem, 0
                 push     eax
               INVOKE     SendMessage, hList45, LB_DELETESTRING, dItem, 0
               INVOKE     SendMessage, hList45, LB_INSERTSTRING, dItem, addr szBuffN
                  pop     ecx
               INVOKE     SendMessage, hList45, LB_SETITEMDATA, dItem, ecx
               INVOKE     SendMessage, hList, LB_DELETESTRING, dItem, 0
               INVOKE     SendMessage, hList, LB_INSERTSTRING, dItem, addr szPathM
                 push     mItem
                 call     ReWrite
                  pop     mItem
               INVOKE     SendMessage, hList45, LB_SETCURSEL, dItem, 0
            .endif
               and     sw4, 0
;               and     TypeCmd, 0
               jmp     MenuDone

;---------- [Insert a menu item] ----------
         .elseif TypeCmd == 303                 ; Add menu item

Separator:
            INVOKE     SendMessage, hList45, LB_GETCURSEL, 0, 0
               mov     ecx, eax
               inc     eax
               mov     dItem, eax

            .if byte ptr szPathM+9 != '-'       ; Added + 9 09-28-2003

;---------- [Check for menu state] ----------
               INVOKE     SendMessage, hComb03, CB_GETCURSEL, 0, 0
               .if eax != CB_ERR
                     mov     ecx, eax
                     add     cl, 30h
                     mov     byte ptr szSColZ+1, cl
                    push     ecx
                  INVOKE     lstrlen, addr szPathM
                     pop     ecx
                  .if byte ptr szPathM[eax-1] == '^' && byte ptr szPathM[eax-3] != ';'
                     INVOKE     lstrcpyn, addr szPathM, addr szPathM, eax
                     INVOKE     lstrcat, addr szPathM, addr szSColZ
                     INVOKE     lstrcat, addr szPathM, addr szCar
                  .elseif byte ptr szPathM[eax-1] != '^' && byte ptr szPathM[eax-2] != ';'
                     INVOKE     lstrcat, addr szPathM, addr szSColZ
                  .elseif byte ptr szPathM[eax-2] == ';'
                     mov     byte ptr szPathM[eax-1], cl
                  .elseif byte ptr szPathM[eax-3] == ';'
                     mov     byte ptr szPathM[eax-2], cl
                  .endif
               .endif
            .endif

            INVOKE     IsDlgButtonChecked, hdlg, 201
            .if eax && TypeCmd != 307 && TypeCmd != 315 ; 307 = Add A SubMenu - 315 = SUBMENU:
               INVOKE     lstrcat, addr szPathM, addr szCar
            .endif

            INVOKE     SendMessage, hList, LB_GETTEXT, dItem, addr szWork
            .if byte ptr szWork+11 == 'B' && byte ptr szWork+16 == ':'
               INVOKE     lstrlen, addr szPathM
               .if byte ptr szPathM[eax-1] == '^'
                  INVOKE     lstrcpyn, addr szPathM, addr szPathM, eax
               .endif

            .else
               INVOKE     lstrlen, addr szPathM
               .if byte ptr szPathM[eax-1] == '^'
                  INVOKE     lstrcpy, addr szWork, addr szSpaces
                  INVOKE     lstrcat, addr szWork, addr szBuffN
                  INVOKE     lstrcpy, addr szBuffN, addr szWork
               .endif
            .endif

            .if szBuffA       ; Accelerator
               INVOKE     lstrcat, addr szBuffN, addr szSpace4
               INVOKE     lstrcat, addr szBuffN, addr szBuffA
               INVOKE     SendMessage, hComb02, CB_GETCURSEL, 0, 0
               .if eax != CB_ERR && eax
                  INVOKE     SendMessage, hComb02, CB_GETITEMDATA, eax, 0
                     mov     ecx, AccelCnt
                    imul     ecx, 6
                     inc     AccelCnt
                     mov     ebx, hAccelArray
                     mov     edx, eax
                     shl     edx, 16
                     shr     eax, 16
                     mov     dx, ax
                     mov     dword ptr[ebx+ecx], edx
                     mov     ax, word ptr mItem
                     mov     word ptr[ebx+ecx+4], ax
               .endif
            .endif

            .if byte ptr szBuffN+2 == 'B' && byte ptr szBuffN+7 == ':'
               INVOKE     lstrcpy, addr szBuffN, addr szBuffN+9  ;NOTE !!!!!!!!
            .endif

            INVOKE     wsprintf, addr szWork1, addr fmat1, mItem
            INVOKE     SetDlgItemText, hdlg, 402, addr szWork1

            INVOKE     SendMessage, hList45, LB_INSERTSTRING, dItem, addr szBuffN
               mov     ecx, eax
            INVOKE     SendMessage, hList45, LB_SETITEMDATA, ecx, mItem
            INVOKE     SendMessage, hList, LB_INSERTSTRING, dItem, addr szPathM
              push     mItem
              call     ReWrite
               pop     mItem
               inc     mItem
         .endif
         INVOKE     DrawMenuBar, hWnd
         INVOKE     SendMessage, hList45, LB_SETCURSEL, dItem, 0
            and     sw4, 0
            and     TypeCmd, 0
            jmp     MenuDone

ErrMsg:
         INVOKE     MessageBox, NULL, addr szSetupM, addr AppName, MB_OK or\
                    MB_ICONWARNING or MB_TASKMODAL or MB_TOPMOST

      .endif

MenuDone:
         mov     eax, FALSE

MenuRet:
         ret
MenuDlg ENDP

;=========================================================================
; Load menu PROCEDURE
;=========================================================================
LoadMenus PROC  uses ebx esi edi
LOCAL    hSavMenu:DWORD, Cnt, Cnt1, Incr, Incr1
LOCAL    szWork[256]:BYTE,szBuff1[256]:BYTE, szBuff2[64]:BYTE, szBuff3[20]:BYTE

      INVOKE     lstrcpy, addr szMenuItems, addr szReditM
      .if Opt == 1       ; Build
         INVOKE     SendMessage, hDlgSav, WM_SETTEXT, 0, addr szBuildT
         INVOKE     lstrcat, addr szMenuItems, addr szBuildKey
      .elseif Opt == 2   ; AddIns
         INVOKE     SendMessage, hDlgSav, WM_SETTEXT, 0, addr szAddInT
         INVOKE     lstrcat, addr szMenuItems, addr szAddinKey
      .elseif Opt == 3   ; Tools
         INVOKE     SendMessage, hDlgSav, WM_SETTEXT, 0, addr szToolsT
         INVOKE     lstrcat, addr szMenuItems, addr szToolsKey
      .elseif Opt == 4   ; Help
         INVOKE     SendMessage, hDlgSav, WM_SETTEXT, 0, addr szHelpT
         INVOKE     lstrcat, addr szMenuItems, addr szHelpKey
      .else
            jmp     LoadDone
      .endif
      INVOKE     SendMessage, hList45, LB_RESETCONTENT, 0, 0
      INVOKE     SendMessage, hList, LB_RESETCONTENT, 0, 0

      .if hKeyM
         INVOKE     RegCloseKey, hKeyM
      .endif

;--------------- [Open or create the menu and work registry] --------------- 
      INVOKE     RegCreateKeyEx, HKEY_CURRENT_USER, offset szMenuItems, 0, offset szREGSZ, 0,\
                 KEY_WRITE or KEY_READ, 0, addr hKeyM, addr lpdwDisp

         mov     ecx, Opt
      INVOKE     SendMessage, hComb01, CB_GETITEMDATA, ecx, 0
         mov     hSMenuH, eax

      .if Opt == 1
         INVOKE     lstrcpy, addr szWork, addr szBuildTxt
      .elseif Opt == 2
         INVOKE     GetMenuString, hSMenuH, IDM_ADDIN, addr szWork, 255, MF_BYCOMMAND
      .elseif Opt == 3
         INVOKE     lstrcpy, addr szWork, addr szToolsTxt
      .elseif Opt == 4
         INVOKE     GetMenuString, hSMenuH, IDM_WHELP, addr szWork, 255, MF_BYCOMMAND
      .endif

;---------- [Check for accelerators] ----------
      INVOKE     lstrcpy, addr szBuffN, addr szWork
      INVOKE     lstrlen, addr szWork
         mov     ecx, eax
         xor     eax, eax
      .while (ecx)
         .if byte ptr szWork[eax] == 9
               inc     eax
              push     eax
            INVOKE     lstrcpyn, addr szBuffN, addr szWork, eax
               pop     eax
            INVOKE     lstrcpy, addr szBuff2, addr szWork[eax]
            INVOKE     lstrcat, addr szBuffN, addr szSpace4
            INVOKE     lstrcat, addr szBuffN, addr szBuff2
            .break
         .endif
            inc     eax
            dec     ecx
      .endw

      INVOKE     SendMessage, hList45, LB_ADDSTRING, 0, addr szBuffN
      INVOKE     SendMessage, hList, LB_ADDSTRING, 0, addr szWork
         mov     lpcbData, 4
      INVOKE     RegQueryValueEx, hKeyM, addr szMenuCnt, 0, addr lpType, addr mItem, addr lpcbData
      .if eax != 0 || mItem == 2100 || mItem == 3100 || mItem == 4100 || mItem == 7100
         .if Opt == 1
               mov     mItem, 2101
         .elseif Opt == 2
               mov     mItem, 3101
         .elseif Opt == 3
               mov     mItem, 4101
         .elseif Opt == 4
               mov     mItem, 7101
         .endif
            jmp     LoadDone
      .endif

       MOVmd     Cnt, mItem
      .if Cnt > 2099 && Cnt < 2501
            sub     Cnt, 2100
            mov     mItem, 2101
      .elseif Cnt > 3099 && Cnt < 3501
            sub     Cnt, 3100
            mov     mItem, 3101
      .elseif Cnt > 4099 && Cnt < 4501
            sub     Cnt, 4100
            mov     mItem, 4101
      .elseif Cnt > 7099 && Cnt < 7501
            sub     Cnt, 7100
            mov     mItem, 7101
      .endif

      .while (Cnt)
         INVOKE     wsprintf, addr szIndexM, addr fmat4, mItem
         INVOKE     lstrlen, addr szPathM
            mov     lpcbData, 250
         INVOKE     RegQueryValueEx, hKeyM, addr szNameM, 0, addr lpType, addr szPathM, addr lpcbData
         .if eax == 0
            .if byte ptr szPathM == '*' && byte ptr szPathM+3 == 'S' ||\
                byte ptr szPathM == '*' && byte ptr szPathM+5 == 'S' ; To convert old
               INVOKE     lstrlen, addr szPathM
               .if byte ptr szPathM[eax-1] == '^'
                  INVOKE     lstrcpy, addr szPathM, addr szSepN
                  INVOKE     lstrcat, addr szPathM, addr szCar
               .else
                  INVOKE     lstrcpy, addr szPathM, addr szSepN
               .endif
            .endif
               xor     eax, eax
               mov     ecx, 150
            .while (ecx)
               .if byte ptr szPathM[eax] == ':' || byte ptr szPathM[eax] == '-' &&\
                   byte ptr szPathM[eax+6] == 'S' || byte ptr szPathM[eax] == 'S' &&\
                   byte ptr szPathM[eax+2] == 'B' && byte ptr szPathM[eax+7] == ':'
                  .if byte ptr szPathM[eax] == ':'

                       push     eax
                        inc     eax
                     INVOKE     lstrcpyn, addr szBuffN, addr szPathM, eax
                        pop     eax
                        inc     eax
                     INVOKE     lstrcpy, addr szBuffP, addr szPathM[eax]
                  .elseif byte ptr szPathM[eax+2] == 'B' && byte ptr szPathM[eax+7] == ':'
                     INVOKE     lstrcpy, addr szBuffN, addr szPathM+9  ;NOTE !!!!!!!!
                  .else
                     INVOKE     lstrcpy, addr szBuffN, addr szPathM
                  .endif
                  INVOKE     lstrlen, addr szPathM
                  .if byte ptr szPathM[eax-1] == '^'
                     INVOKE     lstrcpy, addr szWork, addr szSpaces
                     INVOKE     lstrcat, addr szWork, addr szBuffN
                     .if byte ptr szBuffN == '-'
                        INVOKE     lstrlen, addr szWork
                        INVOKE     lstrcpyn, addr szWork, addr szWork, eax
                     .endif
                     INVOKE     lstrcpy, addr szBuffN, addr szWork
                  .endif

;---------- [Check for accelerators] ----------
                  INVOKE     lstrcpy, addr szWork, addr szBuffN
                  INVOKE     lstrlen, addr szWork
                     mov     ecx, eax
                     xor     eax, eax
                  .while (ecx)
                     .if byte ptr szWork[eax] == 9
                           inc     eax
                          push     eax
                        INVOKE     lstrcpyn, addr szBuffN, addr szWork, eax
                           pop     eax
                        INVOKE     lstrcpy, addr szBuff2, addr szWork[eax]
                        INVOKE     lstrcat, addr szBuffN, addr szSpace4
                        INVOKE     lstrcat, addr szBuffN, addr szBuff2
                        .break
                     .endif
                        inc     eax
                        dec     ecx
                  .endw

                  INVOKE     SendMessage, hList45, LB_ADDSTRING, 0, addr szBuffN
                     mov     ecx, eax
                  INVOKE     SendMessage, hList45, LB_SETITEMDATA, ecx, mItem

                  INVOKE     lstrcpy, addr szWork, addr szNameM
                  INVOKE     lstrcat, addr szWork, addr szPathM
                  INVOKE     SendMessage, hList, LB_ADDSTRING, 0, addr szWork
                  .break
               .endif
                  dec     ecx
                  inc     eax
            .endw
         .endif
            inc     mItem
            dec     Cnt
      .endw

LoadDone:
         mov     eax, FALSE

LoadRet:
         ret
LoadMenus ENDP

;=========================================================================
; Delete and rewrite the menu registry PROCEDURE
;=========================================================================
ReWrite PROC
LOCAL    dItem:DWORD, Cnt
LOCAL    szWork[256]:BYTE

         .if !Opt ;|| Opt == 1 || Opt == 3
               ret
         .endif
         INVOKE     RegCloseKey, hKeyM
         INVOKE     RegDeleteKey, HKEY_CURRENT_USER, offset szMenuItems
         INVOKE     RegCreateKeyEx, HKEY_CURRENT_USER, offset szMenuItems, 0, offset szREGSZ, 0,\
                    KEY_WRITE or KEY_READ, 0, addr hKeyM, addr lpdwDisp

         INVOKE     SendMessage, hList, LB_GETCOUNT, 0, 0
            mov     Cnt, eax
            mov     dItem, 1
         .if Opt == 1
               mov     mItem, 2101
         .elseif Opt == 2
               mov     mItem, 3101
         .elseif Opt == 3
               mov     mItem, 4101
         .elseif Opt == 4
               mov     mItem, 7101
         .else
               ret
         .endif
         .if Cnt
               dec     Cnt
         .endif

            mov     byte ptr szSColZ+1, '0'
         .while (Cnt)
            INVOKE     SendMessage, hList, LB_GETTEXT, dItem, addr szPathM
            .if eax != LB_ERR
               INVOKE     wsprintf, addr szIndexM, addr fmat4, mItem
               INVOKE     lstrcpy, addr szPathM, addr szPathM+9
               INVOKE     lstrlen, addr szPathM
               .if byte ptr szPathM == '-' || byte ptr szPathM == 'S' && byte ptr szPathM+2 == 'B' &&\
                   byte ptr szPathM+7 == ':'
               .else
                  .if byte ptr szPathM[eax-1] == '^' && byte ptr szPathM[eax-3] != ';'
                     INVOKE     lstrcpyn, addr szPathM, addr szPathM, eax
                     INVOKE     lstrcat, addr szPathM, addr szSColZ
                     INVOKE     lstrcat, addr szPathM, addr szCar
                  .elseif byte ptr szPathM[eax-1] != '^' && byte ptr szPathM[eax-2] != ';'
                     INVOKE     lstrcat, addr szPathM, addr szSColZ
                  .endif
                  INVOKE     lstrlen, addr szPathM
               .endif
                  mov     lpcbData, eax
               INVOKE     RegSetValueEx, hKeyM, addr szNameM, 0, REG_SZ, addr szPathM, lpcbData
            .endif
               inc     dItem
               inc     mItem
               dec     Cnt
         .endw
            dec     mItem
         INVOKE     RegSetValueEx, hKeyM, addr szMenuCnt, 0, REG_DWORD, addr mItem, 4
            inc     mItem
         INVOKE     LoadMenuItems, 0, 4

         ret
ReWrite ENDP

;=========================================================================
; Get submenu hahdles PROCEDURE
;=========================================================================
GetSubHandles PROC
LOCAL    Hit:DWORD, Cnt, Incr, IncrH
LOCAL    szWork[64]:BYTE

         and     Hit, 0
         and     Incr, 0
         and     IncrH, 0
      INVOKE     GetMenuItemCount, hMenu
         mov     Cnt, eax
      .while (Cnt)
         INVOKE     GetMenuString, hMenu, Incr, addr szWork, 63, MF_BYPOSITION
         INVOKE     lstrcmpi, addr szWork, addr szBuildM
         .if eax == 0
               mov     Hit, 1
         .endif
         .if Hit && Hit < 5
            INVOKE     GetSubMenu, hMenu, Incr
               mov     ecx, IncrH
               mov     hBuildM[ecx*4], eax
               inc     IncrH
               inc     Hit
         .endif
            inc     Incr
            dec     Cnt
      .endw

         ret
GetSubHandles ENDP

;=========================================================================
; Draw Listbox PROCEDURE
;=========================================================================
DrawList PROC uses esi edi lParam:DWORD
LOCAL    tm:TEXTMETRIC
LOCAL    Len:DWORD, LenW, yPos, IncrH
LOCAL    szWork[256]:BYTE, szBuff[64]:BYTE

            mov     esi, lParam
            lea     edi, dis
            mov     ecx, sizeof dis
            rep     movsb
         .if dis.itemID != -1
            INVOKE     SendMessage, hList, LB_GETTEXT, dis.itemID, addr szWork
               mov     LenW, eax
            INVOKE     SendMessage, hList45, LB_GETTEXT, dis.itemID, addr szBuff
               mov     Len, eax
            INVOKE     GetTextMetrics, dis.hdc, addr tm
               mov     eax, dis.rcItem.bottom
               add     eax, dis.rcItem.top
               sub     eax, tm.tmHeight
               shr     eax, 1
               mov     yPos, eax
            .if (dis.itemState & ODS_SELECTED)
               .if hBR
                  INVOKE     DeleteObject, hBR
               .endif
               INVOKE     CreateSolidBrush, 00800000h         ; Highlight background color
                  mov     hBR, eax
               INVOKE     FillRect, dis.hdc, addr dis.rcItem, eax
               INVOKE     SetTextColor, dis.hdc, 00ffffffh    ; Highlight text color
               INVOKE     SetBkColor, dis.hdc, 00800000h      ; Highlight text background color
            .else
               INVOKE     CreateSolidBrush, 0                 ; Background color BackGC
                  mov     hBR, eax
               INVOKE     FillRect, dis.hdc, addr dis.rcItem, eax
                  mov     eax, LenW
               .if dis.itemID == 0
                     mov     ecx, 000000ffh
               .elseif byte ptr szWork+9 == 'S' && byte ptr szWork+11 == 'B' &&\
                       byte ptr szWork+16 == ':'
                     mov     ecx, 0000ff00h
               .elseif byte ptr szWork[eax-1] == '^'
                  .if byte ptr szWork+9 == '-' && byte ptr szWork+15 == 'S'
                        mov     ecx, 004080ffh
                  .else
                        mov     ecx, 00bfbf00h
                  .endif
               .elseif byte ptr szWork+9 == '-' && byte ptr szWork+15 == 'S'
                     mov     ecx, 0080ffffh
               .else
                     mov     ecx, 00ffff00h
               .endif
               .if byte ptr szWork[eax-2] == ';' && byte ptr szWork[eax-1] == '1' ||\
                    byte ptr szWork[eax-3] == ';' && byte ptr szWork[eax-2] == '1'
                     mov     ecx, 00c9c9c9h
                  .if szWork[eax-1] == '^'
                     mov     ecx, 00929292h
                  .endif
               .endif
               INVOKE     SetTextColor, dis.hdc, ecx          ; Text color - dis.itemData
               INVOKE     SetBkColor, dis.hdc, 0h             ; Text background color
            .endif        
               add     dis.rcItem.left, 3
            INVOKE     TextOut, dis.hdc, dis.rcItem.left, yPos, addr szBuff, Len
            INVOKE     DeleteObject, hBR
               and     hBR, 0
         .endif
            mov     dis.itemState, ODS_DEFAULT
            mov     dis.hdc, 0

         ret
DrawList ENDP

;=========================================================================
; Customize project files PROCEDURE
;=========================================================================
ProjectMaint PROC uses ebx esi edi  hdlg:DWORD, wMsg, wParam, lParam
LOCAL    rect:RECT
LOCAL    FindData:WIN32_FIND_DATA
LOCAL    ofn:OPENFILENAME
LOCAL    hFind:DWORD, Incr, Cnt
LOCAL    szBuff1[256]:BYTE, szBuff2[256]:BYTE, szCurDir[256]:BYTE
LOCAL    PtrBuild[1024*2]:BYTE, szWork[256]:BYTE

      .if wMsg == WM_INITDIALOG
          MOVmd     hProjMaint, hdlg
            and     SaveSelC, 0
            and     SaveSelL, 0
         INVOKE     lstrcpy, addr szBuff1, addr AsmRootDir
         INVOKE     lstrcat, addr szBuff1, addr szPointUser
         INVOKE     CreateDirectory, addr szBuff1, NULL
         INVOKE     RtlZeroMemory, addr lf, sizeof lf
         INVOKE     lstrcpy, addr lf.lfFaceName, addr FontNameMS
            mov     lf.lfHeight, -8
            mov     lf.lfWeight, 400
         INVOKE     CreateFontIndirect, addr lf
            mov     hFontD, eax     ; Dialog font

            mov     lf.lfHeight, -9
            mov     lf.lfWeight, 400
         INVOKE     CreateFontIndirect, addr lf
            mov     hFontLST, eax   ; List font

         INVOKE     GetDlgItem, hdlg, 445      ; Get the handle of the Listbox
            mov     hList45, eax               ; Save it


         INVOKE     GetDlgItem, hdlg, 34       ; Get the handle of the Static ctl
            mov     h34, eax
         INVOKE     SetFocus, h34

            mov     Incr, 302
            mov     Cnt, 6
         .while (Cnt)
            INVOKE     GetDlgItem, hdlg, Incr
               mov     ecx, eax
            INVOKE     SendMessage, ecx, WM_SETFONT, hFontD, TRUE
               inc     Incr
               dec     Cnt
         .endw

         INVOKE     GetDlgItem, hdlg, 201
            mov     hComb01, eax
         INVOKE     SendMessage, hList45, WM_SETFONT, hFontLST, TRUE
         INVOKE     SendMessage, hComb01, WM_SETFONT, hFontLST, TRUE
         INVOKE     SendMessage, hComb01, CB_SETITEMHEIGHT, -1, 13       ; Selection field
         INVOKE     SendMessage, hComb01, CB_SETITEMHEIGHT, 0, 13        ; List items

;---------- [Load Group names] ----------
         INVOKE     SendMessage, hComb01, CB_ADDSTRING, 0, addr szSelectGrp
         INVOKE     SendMessage, hComb01, CB_ADDSTRING, 0, addr szGroup00
         INVOKE     SendMessage, hComb01, CB_ADDSTRING, 0, addr szGroup01
         INVOKE     SendMessage, hComb01, CB_ADDSTRING, 0, addr szGroup02
         INVOKE     SendMessage, hComb01, CB_ADDSTRING, 0, addr szGroup03
         INVOKE     SendMessage, hComb01, CB_ADDSTRING, 0, addr szGroup04
         INVOKE     SendMessage, hComb01, CB_ADDSTRING, 0, addr szGroup05
         INVOKE     SendMessage, hComb01, CB_SETCURSEL, 0, 0

         .if lParam == 2
               mov     ecx, ProjGroup
               inc     ecx
               mov     SaveSelC, ecx
            INVOKE     SendMessage, hComb01, CB_SETCURSEL, ecx, 0
            .if eax && eax != CB_ERR
                 call     LoadProjects
            .else
            .endif
         .endif

         .if lParam == 4
            INVOKE     SetDlgItemText, hdlg, 401, addr WorkBuff
            INVOKE     SetDlgItemText, hdlg, 402, addr szLoadPathD
         .endif

      .elseif wMsg == WM_CTLCOLORDLG 
         .if hBR
            INVOKE     DeleteObject, hBR
         .endif
         INVOKE     CreateSolidBrush, 00ffffe0h
            mov     hBR, eax
            ret

      .elseif wMsg == WM_CTLCOLORSTATIC
            mov     eax, lParam
         .if eax == h34 || eax == h38 || eax == h39
            INVOKE     SetBkColor, wParam, 00000000h   ; Background color is black
            INVOKE     SetTextColor, wParam, 00ffff00h ; Text color of edit box is lt blue
            INVOKE     GetStockObject, BLACK_BRUSH     ; Select the black brush for background

         .else
            INVOKE     SetBkColor, wParam, 00ffffe0h
            INVOKE     SetTextColor, wParam, 00000000h
            .if hBR
               INVOKE     DeleteObject, hBR
            .endif
            INVOKE     CreateSolidBrush, 00ffffe0h
               mov     hBR, eax
         .endif
            ret

      .elseif wMsg == WM_CTLCOLORLISTBOX || wMsg == WM_CTLCOLOREDIT
         INVOKE     SetBkColor, wParam, 00000000h   ; Background color is black
         INVOKE     SetTextColor, wParam, 00ffff00h ; Text color of edit box it is blue
         INVOKE     GetStockObject, BLACK_BRUSH     ; Select the black brush for background
            ret

      .elseif wMsg == WM_CLOSE

EndIt:
            and     hWndDlg, 0
         .if hBR
            INVOKE     DeleteObject, hBR
         .endif
         INVOKE     DeleteObject, hFontD
         INVOKE     DeleteObject, hFontLST
         INVOKE     SetFocus, hREdit
         INVOKE     EndDialog, hdlg, 0
            and     hProjMaint, 0
            mov     eax, TRUE
            jmp     DlgRet

      .elseif wMsg != WM_COMMAND
            jmp     DlgDone
      .endif

         mov     ecx, wParam
         shr     ecx, 16
         mov     edx, lParam

;---------- [Check for group selection] ----------
      .if ecx == CBN_SELCHANGE && edx == hComb01
         INVOKE     SendMessage, hComb01, CB_GETCURSEL, 0, 0
            mov     SaveSelC, eax
         .if eax && eax != CB_ERR
              call     LoadProjects
         .else
            INVOKE     SendMessage, hList45, LB_RESETCONTENT, 0, 0
         .endif

;---------- [Check for project selection] ----------
      .elseif ecx == LBN_SELCHANGE && edx == hList45
         INVOKE     SendMessage, hList45, LB_GETCURSEL, 0, 0
            mov     SaveSelL, eax
         .if eax == LB_ERR
               jmp     DlgDone
         .endif
         INVOKE     SendMessage, hList45, LB_GETTEXT, SaveSelL, addr szBuff2
         INVOKE     lstrcat, addr szBuff2, addr ExtPtr
         INVOKE     lstrcpy, addr szBuff1, addr AsmRootDir
         .if SaveSelC > 1
            INVOKE     lstrcat, addr szBuff1, addr szPointUser
         .endif
            mov     ecx, SaveSelC
            dec     ecx
         INVOKE     lstrcat, addr szBuff1, PtrArray[ecx*4]
         INVOKE     lstrcat, addr szBuff1, addr szBuff2
           call     ReadProjects

      .endif

         mov     eax, wParam
        cwde
         mov     wParam, eax

      .if eax >= 301 && eax <= 305
            .if !SaveSelC
                  mov     ErrorCode, 15
                  jmp     DoError
            .endif
      .endif

      .if wParam >= 302 && wParam <= 304
         INVOKE     GetDlgItemText, hdlg, 401, addr szBuff1, sizeof szBuff1
         .if !eax
               mov     ErrorCode, 1
               jmp     DoError
         .endif
         .if wParam != 303
            INVOKE     GetDlgItemText, hdlg, 402, addr szBuff2, sizeof szBuff2
            .if !eax
                  mov     ErrorCode, 2
                  jmp     DoError
            .endif
         .endif
         .if wParam != 302
            INVOKE     SendMessage, hList45, LB_FINDSTRING, -1, addr szBuff1
            .if eax != SaveSelL
                  mov     ErrorCode, 18
                  jmp     DoError
            .endif
         .endif
      .endif
         mov     eax, wParam

;---------- [Browse] ----------
      .if eax == 301
         INVOKE     RtlZeroMemory, addr ofn, sizeof ofn
            mov     ofn.lStructSize, sizeof ofn
         INVOKE     lstrcpy, addr szBuff1, addr szAll
         INVOKE     GetCurrentDirectory, lengthof szCurDir, addr szCurDir
            lea     eax, szBuff1
            mov     ofn.lpstrFile, eax
            mov     ofn.nMaxFile, lengthof szBuff1
            lea     eax, szCurDir
            mov     ofn.lpstrInitialDir, eax
            mov     ofn.lpstrFilter, 0
            mov     ofn.lpstrTitle, offset szOpen
            mov     ofn.Flags, OFN_PATHMUSTEXIST
         INVOKE     GetOpenFileName, addr ofn
         .if !eax                         ; Cancel'ed or error occurred
            INVOKE     SetFocus, h34
               jmp     DlgDone
         .endif
            xor     ecx, ecx
            mov     cx, ofn.nFileOffset
            inc     ecx
         INVOKE     lstrcpyn, addr szBuff1, addr szBuff1, ecx
         INVOKE     SetDlgItemText, hdlg, 402, addr szBuff1

;---------- [Add] ----------
      .elseif eax == 302
         INVOKE     lstrcpy, addr PtrBuild, addr szBuff1
         INVOKE     lstrcat, addr PtrBuild, addr szCol
         INVOKE     lstrcat, addr PtrBuild, addr szBuff2
         INVOKE     lstrcat, addr PtrBuild, addr szCRLF
         INVOKE     lstrcat, addr PtrBuild, addr szCRLF
         INVOKE     lstrcpy, addr szBuffP, addr AsmRootDir
         .if SaveSelC > 1
            INVOKE     lstrcat, addr szBuffP, addr szPointUser
         .endif
            mov     ecx, SaveSelC
            dec     ecx
         INVOKE     lstrcat, addr szBuffP, PtrArray[ecx*4]
         INVOKE     lstrcat, addr szBuffP, addr szBuff1
         INVOKE     lstrcat, addr szBuffP, addr ExtPtr
         INVOKE     GetFileAttributes, addr szBuffP
         .if eax != -1
               mov     ErrorCode, 11
               jmp     DoError
         .endif
           call     WriteProjects
            mov     ProjOn, 1
           call     LoadProjectTree

;---------- [Delete] ----------
      .elseif eax == 303
         INVOKE     lstrcpy, addr szBuffP, addr AsmRootDir
         .if SaveSelC > 1
            INVOKE     lstrcat, addr szBuffP, addr szPointUser
         .endif
            mov     ecx, SaveSelC
            dec     ecx
         INVOKE     lstrcat, addr szBuffP, PtrArray[ecx*4]
         INVOKE     lstrcat, addr szBuffP, addr szBuff1
         INVOKE     lstrcat, addr szBuffP, addr ExtPtr
         INVOKE     DeleteFile, addr szBuffP
         .if !eax
               mov     ErrorCode, 9
               jmp     DoError
         .endif
         INVOKE     SendMessage, hList45, LB_DELETESTRING, SaveSelL, 0
         INVOKE     SetDlgItemText, hdlg, 401, addr szNull
         INVOKE     SetDlgItemText, hdlg, 402, addr szNull

;---------- [Change Path] ----------
      .elseif eax == 304
         INVOKE     lstrcpy, addr szBuffP, addr AsmRootDir
         .if SaveSelC > 1
            INVOKE     lstrcat, addr szBuffP, addr szPointUser
         .endif
            mov     ecx, SaveSelC
            dec     ecx
         INVOKE     lstrcat, addr szBuffP, PtrArray[ecx*4]
         INVOKE     lstrcat, addr szBuffP, addr szBuff1
         INVOKE     lstrcat, addr szBuffP, addr ExtPtr
         INVOKE     GetFileAttributes, addr szBuffP
         .if eax == -1
               mov     ErrorCode, 17
               jmp     DoError
         .endif
           call     ChangePath

;---------- [Clear] ----------
      .elseif eax == 305
         INVOKE     SetDlgItemText, hdlg, 401, addr szNull
         INVOKE     SetDlgItemText, hdlg, 402, addr szNull

;---------- [Close or Cancel] ----------
      .elseif eax == 306 || eax == 307
            jmp     EndIt
      .endif
         jmp     DlgDone

DoError:
      .if ErrorCode == 1
         INVOKE     MessageBox, NULL, addr szError6, addr AppName, MB_OK or MB_ICONSTOP
      .elseif ErrorCode == 2
         INVOKE     MessageBox, NULL, addr szError16, addr AppName, MB_OK or MB_ICONSTOP
      .elseif ErrorCode == 9
         INVOKE     MessageBox, NULL, addr szError9, addr AppName, MB_OK or MB_ICONSTOP
      .elseif ErrorCode == 11
         INVOKE     MessageBox, NULL, addr szError11, addr AppName, MB_OK or MB_ICONEXCLAMATION
      .elseif ErrorCode == 15
         INVOKE     MessageBox, NULL, addr szError15, addr AppName, MB_OK or MB_ICONEXCLAMATION
      .elseif ErrorCode == 17
         INVOKE     MessageBox, NULL, addr szError17, addr AppName, MB_OK or MB_ICONEXCLAMATION
      .elseif ErrorCode == 18
         INVOKE     MessageBox, NULL, addr szError18, addr AppName, MB_OK or MB_ICONSTOP
      .endif

DlgDone:
         mov     eax, FALSE

DlgRet:
         ret

LoadProjects:
         INVOKE     SendMessage, hList45, LB_RESETCONTENT, 0, 0
         INVOKE     lstrcpy, addr szBuff1, addr AsmRootDir
         .if SaveSelC > 1
            INVOKE     lstrcat, addr szBuff1, addr szPointUser
         .endif
            mov     ecx, SaveSelC
            dec     ecx
         INVOKE     lstrcat, addr szBuff1, PtrArray[ecx*4]
         INVOKE     lstrcpy, addr szBuff2, addr szBuff1
         INVOKE     lstrcat, addr szBuff1, addr szPtrs
         INVOKE     FindFirstFile, addr szBuff1, addr FindData
         .if eax == INVALID_HANDLE_VALUE
            INVOKE     CreateDirectory, addr szBuff2, NULL
               jmp     NoFileL
         .endif
            mov     hFind, eax
            jmp     AddemL

GetemL:
         INVOKE     FindNextFile, hFind, addr FindData
           test     eax, eax
             jz     AllDoneL

AddemL:
         INVOKE     lstrlen, addr FindData.cFileName
            sub     eax, 3
         INVOKE     lstrcpyn, addr szBuff2, addr FindData.cFileName, eax
         INVOKE     SendMessage, hList45, LB_ADDSTRING, 0, addr szBuff2
            jmp     GetemL

AllDoneL:
         INVOKE     FindClose, hFind

NoFileL:
        retn

ReadProjects:
         mov     ecx, hBuff
      INVOKE     lstrcpy, ecx, addr szBuff1
        call     ReadF
        test     eax, eax
          js     DlgDone
         mov     ecx, BytesR           ; Bytes left to analyze
         mov     esi, fpMem            ; Start address in input buffer
         lea     edi, szBuff1
         xor     eax, eax
      .while (ecx)
         .if word ptr [esi] == ' :'
               add     esi, 2
               sub     ecx, 2
            .break
         .endif
            dec     ecx
            inc     esi
      .endw
      .if !ecx
            jmp     FreeEm
      .endif
        push     ecx
         mov     ecx, esi
         sub     ecx, fpMem
         dec     ecx
      INVOKE     lstrcpyn, addr szBuff2, fpMem, ecx
         pop     ecx
      .while (ecx)
            mov     al, byte ptr[esi]
         .if al == 0dh
            .break
         .endif
            mov     byte ptr[edi], al
            dec     ecx
            inc     esi
            inc     edi
      .endw
         mov     byte ptr[edi], 0
      INVOKE     lstrcpy, addr szLoadPath, addr szBuff1
      INVOKE     SetDlgItemText, hdlg, 401, addr szBuff2
      INVOKE     SetDlgItemText, hdlg, 402, addr szBuff1

FreeEm:
      INVOKE     GlobalUnlock, fpMem
      INVOKE     GlobalFree, hpMem
         mov     hpMem, 0
        retn

WriteProjects:
         INVOKE     lstrlen, addr PtrBuild
            mov     BytesR, eax
         INVOKE     GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, 100000
            mov     hpMem, eax
         INVOKE     GlobalLock, hpMem
            mov     fpMem, eax
         INVOKE     lstrcpy, fpMem, addr PtrBuild
            mov     ecx, hBuff
         INVOKE     lstrcpy, ecx, addr szBuffP
           call     WriteF
         .if !eax || eax == INVALID_HANDLE_VALUE
            INVOKE     MessageBox, NULL, addr szError12, addr AppName,\
                       MB_OK or MB_ICONWARNING or MB_SYSTEMMODAL
         .else
            .if wParam == 302
               INVOKE     SendMessage, hList45, LB_ADDSTRING, 0, addr szBuff1
               INVOKE     SendMessage, hList45, LB_FINDSTRING, -1, addr szBuff1
                  mov     SaveSelL, eax
               INVOKE     SendMessage, hList45, LB_SETCURSEL, SaveSelL, 0
            .endif
         .endif
         .if hpMem
            INVOKE     GlobalUnlock, fpMem
            INVOKE     GlobalFree, hpMem
               mov     hpMem, 0
         .endif

        retn

ChangePath:
         INVOKE     lstrcpy, addr PtrBuild, addr szBuff1
         INVOKE     lstrcat, addr PtrBuild, addr szCol
         INVOKE     lstrcat, addr PtrBuild, addr szBuff2
         INVOKE     lstrcat, addr PtrBuild, addr szCRLF
         INVOKE     lstrcat, addr PtrBuild, addr szCRLF
         INVOKE     GetPrivateProfileString, addr szPtrS, addr szL1, addr szNULL, addr szWork, 255, addr szBuffP
         .if eax < 2
               jmp     NoData
         .endif
         INVOKE     lstrcat, addr PtrBuild, addr szSavBuild
         INVOKE     lstrcat, addr PtrBuild, addr szCRLF
         INVOKE     GetPrivateProfileString, addr szPtrS, addr szR1, addr szNULL, addr szWork, 255, addr szBuffP
         INVOKE     lstrcat, addr PtrBuild, addr szR1E
         INVOKE     lstrcat, addr PtrBuild, addr szWork
         INVOKE     lstrcat, addr PtrBuild, addr szCRLF
         INVOKE     GetPrivateProfileString, addr szPtrS, addr szA1, addr szNULL, addr szWork, 255, addr szBuffP
         INVOKE     lstrcat, addr PtrBuild, addr szA1E
         INVOKE     lstrcat, addr PtrBuild, addr szWork
         INVOKE     lstrcat, addr PtrBuild, addr szCRLF
         INVOKE     GetPrivateProfileString, addr szPtrS, addr szL1, addr szNULL, addr szWork, 255, addr szBuffP
         INVOKE     lstrcat, addr PtrBuild, addr szL1E
         INVOKE     lstrcat, addr PtrBuild, addr szWork
         INVOKE     lstrcat, addr PtrBuild, addr szCRLF
         INVOKE     GetPrivateProfileString, addr szPtrS, addr szL2, addr szNULL, addr szWork, 255, addr szBuffP
         INVOKE     lstrcat, addr PtrBuild, addr szL2E
         INVOKE     lstrcat, addr PtrBuild, addr szWork
         INVOKE     lstrcat, addr PtrBuild, addr szCRLF
         INVOKE     lstrcat, addr PtrBuild, addr szCRLF

NoData:
           call     WriteProjects

        retn

ProjectMaint ENDP
