
.data
szParent        db  'My Master',0
szDriveType     db  'a:\',0
szAllFiles      db  '\*.*',0
Parent          db  'Projects',0
PatnP           db  'Pointers\*.ptr',0
;szPointer       db  'Pointers\',0

szProjects00    db  'Projects',0
szProjects01    db  'Projects01',0
szProjects02    db  'Projects02',0
szProjects03    db  'Projects03',0
szProjects04    db  'Projects04',0
szProjects05    db  'Projects05',0
ProjArray       dd  szProjects00,szProjects01,szProjects02,szProjects03,szProjects04,szProjects05

szColName       db  'Filename',0
szExe           db  '.exe',0
DlgName4        db  'ChkDelProj',0

szMsg01         db  'Could not find an exe in this Folder.', 0dh,0ah,0dh,0ah
                db  'Or there is more then one exe in this Folder and could', 0dh,0ah
                db  'not find one that matches the Folder name', 0dh,0ah
                db  'or the displayed File name.',0
szDeleteF       db  'This will delete the seleted file', 0dh,0ah
                db  'Do you wish to continue?',0

;LibNameCP       db  'Create',0
;FuncNameDP      db  'DelProj',0
szDeleteP       db  'This will delete the complete seleted Project.',0dh,0ah
                db  'Or just the Project name from the list.',0dh,0ah,0dh,0ah
                db  'Do you wish to continue?',0
szCreateP       db  'This will create a Project from the selected item.',0dh,0ah
                db  'Do you wish to continue?',0

.data?
hImageListTL    dd  ?
hImageListTree  dd  ?
hDir            dd  32  dup(?)
hDirD           dd  32  dup(?)
hDrives         dd  32  dup(?)
hSubDir         dd  32  dup(?)
PathLen         dd  32  dup(?)

Texe            dd  ?
Tdll            dd  ?
Tlib            dd  ?
Tinc            dd  ?
DeleteSW        dd  ?
DeleteOn        dd  ?
CreateOn        dd  ?
hDrvExp         dd  ?
Lev             dd  ?
LevD            dd  ?
szDrvLet        db  32  dup(?)
szPathIn        db  256 dup(?)
szListPath      db  256 dup(?)
szSavePathD     db  256 dup(?)

.code

;===================================================
; Initialize the Tree and List views procedure
;===================================================
InitTreeList PROC uses ebx
LOCAL    cm:COLORMAP
LOCAL    sfi:SHFILEINFO
LOCAL    lvc:LV_COLUMN
LOCAL    tvis:TV_INSERTSTRUCT
LOCAL    FindData:WIN32_FIND_DATA
LOCAL    hBitmap:DWORD, hFind
LOCAL    szWork[256]:BYTE

;WS_EX_CLIENTEDGE
;---------- [Create the control windows] ----------
         mov     ebx, ProjDrive
      .if CreateOn == 55
            and     CreateOn, 0
            jmp     RefreshDrvTree
      .endif
         mov     ecx, 44
         add     ecx, ebx
      INVOKE     CreateWindowEx, WS_EX_STATICEDGE, addr TreeClass, NULL,\
                 WS_CHILD or WS_VISIBLE or TVS_HASLINES or TVS_HASBUTTONS or\ 
                 TVS_LINESATROOT or TVS_SHOWSELALWAYS or WS_CLIPSIBLINGS or WS_BORDER,\
                 0, 23, 143, 159, hWnd, ecx, hInst, NULL ;0, 23, 133, 160
        test     eax, eax     
          jz     Ret0
         mov     hWndTree[ebx*4], eax 
      INVOKE     SendMessage, hWndTree[ebx*4], TVM_SETTEXTCOLOR, 0, Color.TreeListTC
      INVOKE     SendMessage, hWndTree[ebx*4], TVM_SETBKCOLOR, 0, Color.TreeListBC

         mov     ecx, 46
         add     ecx, ebx
      INVOKE     CreateWindowEx, WS_EX_STATICEDGE, addr ListViewClass, NULL,\
                 WS_CHILD or WS_VISIBLE or LVS_REPORT or LVS_SHAREIMAGELISTS or\
                 LVS_SORTASCENDING or LVS_SHOWSELALWAYS or LVS_SINGLESEL or\
                 WS_CLIPSIBLINGS  or WS_CLIPCHILDREN or WS_BORDER,\
                 0, 183, 143, 208, hWnd, ecx, hInst, NULL ;0, 183, 133, 208
        test     eax, eax     
          jz     Ret0
         mov     hWndList[ebx*4], eax
      INVOKE     SendMessage, hWndList[ebx*4], LVM_SETTEXTCOLOR, 0, Color.TreeListTC
      INVOKE     SendMessage, hWndList[ebx*4], LVM_SETTEXTBKCOLOR, 0, Color.TreeListBC
      INVOKE     SendMessage, hWndList[ebx*4], LVM_SETBKCOLOR, 0, Color.TreeListBC

         mov     lvc.imask, LVCF_TEXT or LVCF_WIDTH
         mov     lvc.pszText, offset szColName
         mov     lvc.lx, 129
      INVOKE     SendMessage, hWndList[ebx*4], LVM_INSERTCOLUMN, 0, addr lvc

;      INVOKE     SetWindowLong, hWndTree, GWL_ID, 2244
;      INVOKE     ShowWindow, hWndTree, SW_HIDE

      INVOKE     ImageList_Create, 16, 16, ILC_COLOR16, 8, 2
         mov     hImageListTL, eax
      INVOKE     LoadBitmap, hInst, 800
         mov     hBitmap,eax
      INVOKE     ImageList_Add, hImageListTL, hBitmap, NULL
      INVOKE     DeleteObject, hBitmap
      INVOKE     SendMessage, hWndList[ebx*4], LVM_SETIMAGELIST, LVSIL_SMALL, hImageListTL

      .if !ProjDrive
            jmp     DoProject
      .endif

;---------- [Load the drive tree
      INVOKE     ImageList_Create, 16, 16, ILC_COLOR16, 7, 10
         mov     hImageListTree, eax
         mov     cm.From, 00ffffffh
         mov     eax, Color.TreeListBC
         mov     cm.To, eax
      INVOKE     CreateMappedBitmap, hInst, 900, 0, addr cm, 1
        push     eax
      INVOKE     ImageList_Add, hImageListTree, eax, NULL
         pop     eax
      INVOKE     DeleteObject, eax

      INVOKE     SendMessage, hWndTreeD, TVM_SETIMAGELIST, 0, hImageListTree
      INVOKE     lstrcpy, addr szSavePathD, addr szLoadPathD

RefreshDrvTree:
         and     LevD, 0
         mov     byte ptr szDriveType, 'A'
      INVOKE     SendMessage, hWndTreeD, TVM_DELETEITEM, 0, TVI_ROOT
         mov     tvis.hParent, NULL
         mov     tvis.hInsertAfter, TVI_ROOT
         mov     tvis.item.imask, TVIF_TEXT or TVIF_IMAGE or TVIF_SELECTEDIMAGE
         mov     tvis.item.pszText, offset szParent
         mov     tvis.item.iImage, 0
         mov     tvis.item.iSelectedImage, 0
      INVOKE     SendMessage, hWndTreeD, TVM_INSERTITEM, 0, addr tvis
         mov     ecx, LevD
         mov     hDrives[ecx*4], eax
         mov     hParentD, eax

;---------- [Find available drives] ----------
      INVOKE     GetLogicalDrives
         mov     ebx, eax
         xor     edx, edx
      .while (ebx > 0)
            shr     ebx, 1
           push     edx
           push     ebx
         INVOKE     GetDriveType, addr szDriveType  ; Get type of drive
            pop     ebx
            pop     edx

;---------- [If FIXED drive add the letter to the array] ----------
         .if eax == DRIVE_REMOVABLE || eax == DRIVE_FIXED || eax == DRIVE_CDROM ||\
             eax == DRIVE_REMOTE || eax == DRIVE_RAMDISK
               mov     ecx, eax
            .if ecx == DRIVE_REMOVABLE && byte ptr szDriveType > 'B'
                  mov     ecx, 4
            .endif
               dec     ecx
               inc     edx
              push     edx
              push     ebx
               mov     eax, hParentD
               mov     tvis.hParent, eax
               mov     tvis.hInsertAfter, TVI_LAST
              push     ecx
            INVOKE     SHGetFileInfo, addr szDriveType, 0, addr sfi, sizeof SHFILEINFO, SHGFI_DISPLAYNAME
               pop     ecx
               mov     tvis.item.imask, TVIF_TEXT or TVIF_IMAGE or TVIF_SELECTEDIMAGE or TVIF_CHILDREN
               lea     eax, sfi.szDisplayName
               mov     tvis.item.pszText, eax
               mov     tvis.item.iImage, ecx
               mov     tvis.item.iSelectedImage, ecx
               mov     tvis.item.cChildren, 1
            INVOKE     SendMessage, hWndTreeD, TVM_INSERTITEM, 0, addr tvis
               mov     hItemD, eax
               mov     dl, byte ptr szDriveType
               mov     ecx, LevD
               mov     szDrvLet[ecx], dl
               inc     LevD
               mov     ebx, LevD
               mov     hDrives[ebx*4], eax
                pop     ebx
                pop     edx
         .endif
            inc     szDriveType
      .endw
         mov     ecx, LevD
         mov     szDrvLet[ecx], 0

         mov     tvis.item.iImage, 5
         mov     tvis.item.iSelectedImage, 6
         mov     tvis.item.cChildren, 0
      INVOKE     SendMessage, hWndTreeD, TVM_EXPAND, TVE_EXPAND, hParentD
      INVOKE     SendMessage, hWndTreeD, TVM_SELECTITEM, TVGN_CARET, NULL
        call     TreeBranch
      INVOKE     ReadTheFile, addr szLoadPathD
         jmp     Ret0

;---------- [Load the project tree
DoProject:
      INVOKE     SendMessage, hWndTree, TVM_SETIMAGELIST, 0, hImageListTL
        call     LoadProjectTree
         jmp     Ret0

Ret0:
         xor     eax, eax
         ret

InitTreeList ENDP

;===================================================
; Load the project tree procedure
;===================================================
LoadProjectTree PROC uses ebx
LOCAL    tvis:TV_INSERTSTRUCT
LOCAL    FindData:WIN32_FIND_DATA
LOCAL    hFind:DWORD
LOCAL    szWork[256]:BYTE

;      INVOKE     LockWindowUpdate, hWnd          ; Lock Window to avoid flicker
         mov     ebx, ProjDrive
         and     Lev, 0
         and     hItem, 0
      INVOKE     SendMessage, hWndList, LVM_DELETEALLITEMS, 0, 0
      INVOKE     SendMessage, hWndTree[ebx*4], TVM_DELETEITEM, 0, TVI_ROOT
         mov     tvis.hParent, NULL
         mov     tvis.hInsertAfter, TVI_ROOT
         mov     tvis.item.imask, TVIF_TEXT or TVIF_IMAGE or TVIF_SELECTEDIMAGE
         mov     ecx, ProjGroup
       MOVmd     tvis.item.pszText, ProjArray[ecx*4] ;Parent
         mov     tvis.item.iImage, 0
         mov     tvis.item.iSelectedImage, 1
      INVOKE     SendMessage, hWndTree[ebx*4], TVM_INSERTITEM, 0, addr tvis
         mov     ecx, Lev
         mov     hDir[ecx*4], eax
         mov     hParent, eax

      INVOKE     lstrcpy, addr szWork, addr AsmRootDir
;      INVOKE     lstrcat, addr szWork, addr PatnP
      .if ProjGroup
         INVOKE     lstrcat, addr szWork, addr szPointUser
      .endif
         mov     ecx, ProjGroup
      INVOKE     lstrcat, addr szWork, PtrArray[ecx*4]
      INVOKE     lstrcat, addr szWork, addr szPtrs
;INVOKE     MessageBox, NULL, addr szWork, addr AppName, MB_OK

      INVOKE     FindFirstFile, addr szWork, addr FindData
      .if eax == -1
;         INVOKE     LockWindowUpdate, 0          ; Unock Window
            jmp     Ret0
      .endif
         mov     hFind, eax
         jmp     Addem

Getem:
      INVOKE     FindNextFile, hFind, addr FindData
        test     eax, eax
          jz     AllDone

Addem:
      INVOKE     lstrlen, addr FindData.cFileName
         sub     eax, 3
      INVOKE     lstrcpyn, addr szWork, addr FindData.cFileName, eax
      INVOKE     LoadTreeView, addr szWork, 0

      .if !hItem
           push     eax
;         INVOKE     lstrcmpi, addr szWork, addr szProject
            mov     eax, ProjGroup
         INVOKE     lstrcmpi, addr szWork, ProjNamArray[eax*4]
            pop     ecx
         .if !eax
               mov     hItem, ecx
         .endif
      .endif

         jmp     Getem

AllDone:
      INVOKE     FindClose, hFind
      INVOKE     LoadTreeView, addr szWork, 1

Ret0:
         xor     eax, eax
         ret

LoadProjectTree ENDP

;===================================================
; Treeview notify procedure
;===================================================
TreeViewNotify PROC uses ebx esi edi wParam:DWORD, lParam
LOCAL    pt:POINT
LOCAL    tvi:TV_ITEM
LOCAL    tvhti:TV_HITTESTINFO
LOCAL    FindData:WIN32_FIND_DATA
LOCAL    szWork[256]:BYTE, szBuff1[64]:BYTE

      .if wParam == 55555
         INVOKE     lstrcpy, addr szWork, addr szListPath
            jmp     FromFirst
      .endif
         mov     eax, lParam
         mov     ebx, (NM_TREEVIEW ptr [eax]).hdr.code
         mov     ecx, (NM_TREEVIEW ptr [eax]).itemNew.hItem
         mov     edx, (NMHDR ptr [eax]).code

      .if edx == NM_RCLICK
         .if ProjDrive
               jmp     Ret0
         .endif
            jmp     RightClk
      .endif

      .if ebx == TVN_SELCHANGED
         .if ecx == hParent
            INVOKE     SendMessage, hWndTree, TVM_SELECTITEM, TVGN_CARET, NULL
               jmp     Ret0
         .endif
            mov     hItem, ecx
            mov     tvi.hItem, ecx
            mov     tvi.imask, TVIF_TEXT or TVIF_SELECTEDIMAGE
;            lea     eax, szProject
            mov     ecx, ProjGroup
            mov     eax, ProjNamArray[ecx*4]
            mov     tvi.pszText, eax
            mov     tvi.cchTextMax, sizeof szProject
         INVOKE     SendMessage, hWndTree, TVM_GETITEM, NULL, addr tvi
           test     eax, eax
             jz     Ret0

FromFirst:
         INVOKE     lstrcpy, addr szWork, addr AsmRootDir
;         INVOKE     lstrcat, addr szWork, addr szPointer

         .if ProjGroup
            INVOKE     lstrcat, addr szWork, addr szPointUser
         .endif
            mov     ebx, ProjGroup
         INVOKE     lstrcat, addr szWork, PtrArray[ebx*4]
;         INVOKE     lstrcat, addr szWork, addr szProject
         INVOKE     lstrcat, addr szWork, ProjNamArray[ebx*4]
         INVOKE     lstrcat, addr szWork, addr PatnP+10  ; = .ptr
            mov     ecx, hBuff
         INVOKE     lstrcpy, ecx, addr szWork
           call     ReadF
         .if eax == 0 || sdword ptr eax < 0
               jmp     Ret0
         .endif
            mov     ecx, BytesR           ; Bytes left to analyze
            mov     esi, fpMem            ; Start address in input buffer
            lea     edi, szWork
            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
         .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 szWork

;         .if sw88   ; Refreash 
;            INVOKE     lstrcpy, addr PathName, addr szWork
;            INVOKE     lstrcat, addr PathName, addr szProjectP
;            INVOKE     lstrcat, addr PathName, addr szAsm
;         .endif

         INVOKE     ReadTheFile, addr szWork

FreeEm:
         INVOKE     GlobalUnlock, fpMem
         INVOKE     GlobalFree, hpMem
            mov     hpMem, 0
      .endif
         jmp     Ret0

;---------- [Delete Project] ----------
RightClk:
      INVOKE     GetCursorPos, addr pt
      INVOKE     ScreenToClient, hWndTree, addr pt
         mov     eax, pt.x
         mov     tvhti.pt.x, eax
         mov     eax, pt.y
         mov     tvhti.pt.y, eax
      INVOKE     SendMessage, hWndTree, TVM_HITTEST, 0, addr tvhti
      .if (tvhti.flags & TVHT_ONITEM)
         INVOKE     ClientToScreen, hWndTree, addr pt
            mov     tvi.imask, TVIF_HANDLE or TVIF_TEXT
            mov     eax, tvhti.hItem
            mov     tvi.hItem, eax
            lea     eax, szBuff1
            mov     tvi.pszText, eax
            mov     tvi.cchTextMax, sizeof szBuff1
         INVOKE     SendMessage, hWndTree, TVM_GETITEM, 0, addr tvi
           test     eax,eax
             jz     Ret0
         INVOKE     MessageBox, NULL, addr szDeleteP, addr szBuff1, MB_YESNO or MB_ICONQUESTION
         .if eax == IDNO
               jmp     Ret0
         .endif

         INVOKE     DelProj, addr szBuff1, 4444
         .if eax == 4444    ; Delete confirmed
               mov     DeleteSW, eax
               mov     eax, hItem
            .if eax == tvhti.hItem
               INVOKE     SendMessage, hWndList, LVM_DELETEALLITEMS, 0, 0
                  and     hItem, 0
;                  mov     byte ptr szProject, 0
                  mov     ecx, ProjGroup
                  mov     eax, ProjNamArray[ecx*4]
                  mov     dword ptr[eax], 0
            .endif
            INVOKE     SendMessage, hWndTree, TVM_DELETEITEM, 0, tvhti.hItem

;---------- [Updated the hProjArray for the deleted item] ----------
               mov     eax, tvhti.hItem
               mov     esi, hProjArray
               xor     edx, edx
               mov     ecx, ProjCnt
            .while (ecx)
               .if dword ptr[esi+edx+4] == eax
mov     dword ptr[esi+edx+4], 0
mov     byte ptr[esi+edx+8], 0
                  .break
               .endif
                  add     edx, 36
                  dec     ecx
            .endw

;---------- [Select the active Tree item] ----------
               mov     eax, hREdit
               mov     esi, hProjArray
               xor     edx, edx
               mov     ecx, ProjCnt
            .while (ecx)
               .if dword ptr[esi+edx] == eax
                     xor     ebx, ebx
                     mov     eax, dword ptr[esi+edx+4]
                     mov     bl, byte ptr[esi+edx+8]
                  .break
               .endif
                  add     edx, 36
                  dec     ecx
            .endw
            .if ecx && ebx == 1
                 push     eax
               INVOKE     LockWindowUpdate, hWnd
                  pop     eax
                  mov     FromTab, 1
               INVOKE     SendMessage, hWndTree, TVM_SELECTITEM, TVGN_CARET, eax
                  and     FromTab, 0
               INVOKE     LockWindowUpdate, 0
            .endif
         .endif

      .else
         .if !hProjMaint && !hWndDlg
            INVOKE     CreateDialogParam, hInst, IDD_GROUPS, hREdit, addr ProjectMaint, 2
               mov     hWndDlg, eax
            INVOKE     SendMessage, hProjMaint, WM_COMMAND, 301, 0
         .endif
      .endif
         jmp     Ret0

Ret0:
         xor     eax, eax
         ret

TreeViewNotify ENDP

;=========================================================================
; Load the ListView with the file data PROCEDURE
;=========================================================================
LoadTreeView PROC lpFileName:DWORD, FromCode
LOCAL    tvis:TV_INSERTSTRUCT
LOCAL    lvf:LV_FINDINFO
LOCAL    lvi:LV_ITEM

      .if FromCode
            jmp     SelItem
      .endif
         mov     eax, hParent
         mov     tvis.hParent, eax
         mov     tvis.hInsertAfter, TVI_LAST
         mov     tvis.item.imask, TVIF_TEXT or TVIF_IMAGE or TVIF_SELECTEDIMAGE
         mov     eax, lpFileName
         mov     tvis.item.pszText, eax
         mov     tvis.item.iImage, 0
         mov     tvis.item.iSelectedImage, 1
      INVOKE     SendMessage, hWndTree, TVM_INSERTITEM, 0, addr tvis
         ret

SelItem:
;---------- [Sort and select the item in the Treeview
      INVOKE     SendMessage, hWndTree, TVM_EXPAND, TVE_EXPAND, hParent
      INVOKE     SendMessage, hWndTree, TVM_SORTCHILDREN, 0, hParent
      INVOKE     SendMessage, hWndTree, TVM_SELECTITEM, TVGN_CARET, hItem
      INVOKE     SendMessage, hWndTree, TVM_ENSUREVISIBLE, 0, hItem

;---------- [Select the item in the Listview
      .if FileName
            mov     lvf.flags, LVFI_STRING
            mov     lvf.psz, offset FileName
         INVOKE     SendMessage, hWndList, LVM_FINDITEM, -1, addr lvf
         .if eax != -1
               mov     lvi.iItem, eax
               mov     lvi.imask, LVIF_STATE
               mov     lvi.state, LVIS_SELECTED or LVIS_FOCUSED
               mov     lvi.stateMask, -1
            INVOKE     SendMessage, hWndList, LVM_SETITEMSTATE, lvi.iItem, addr lvi
         .endif
      .endif

         ret

LoadTreeView ENDP

;===================================================
; Fill the Tree with Directories and Sub Directories
;===================================================
FillTree PROC uses ebx DirName:DWORD, Code
LOCAL    tvis:TV_INSERTSTRUCT

         mov     ebx, LevD
         mov     eax, hDirD[ebx*4]

      .if LevD == 0 && !Code
            mov     eax, hParentD
      .elseif LevD == 0 && Code
            mov     eax, ItemNew
      .endif
         mov     tvis.hParent, eax
         mov     tvis.hInsertAfter, TVI_LAST
         mov     tvis.item.imask, TVIF_TEXT or TVIF_IMAGE or TVIF_SELECTEDIMAGE or TVIF_CHILDREN
         mov     eax, DirName
         mov     tvis.item.pszText, eax
         mov     tvis.item.iImage, 5
         mov     tvis.item.iSelectedImage, 6
         mov     tvis.item.cChildren, 0
      INVOKE     SendMessage, hWndTreeD, TVM_INSERTITEM, 0, addr tvis
         mov     hItemD, eax
         mov     ebx, LevD
         inc     ebx
         mov     hDirD[ebx*4], eax

         xor     eax, eax
         ret

FillTree ENDP

;===========================================================
; Get the Directories and Sub Directories and build the Tree
;===========================================================
GetDirs PROC Code:DWORD, Input
LOCAL    FindData:WIN32_FIND_DATA
LOCAL    tvi:TV_ITEM
LOCAL    Dirs:DWORD, Cnt, hFind
LOCAL    szBuff0[256]:BYTE, szBuff1[256]:BYTE

      INVOKE     lstrcpy, addr szBuff0, Input
      INVOKE     FindFirstFile, addr szBuff0, addr FindData
        test     eax, eax
          js     NoFile
         mov     hFind, eax
         jmp     ChkDir

;_______________________________________________________________________
NextDir:
      INVOKE     FindNextFile, hFind, addr FindData
        test     eax, eax
          jz     AllDone ;GetDir

;_______________________________________________________________________
ChkDir:
      .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
         .if byte ptr FindData.cFileName == '.' || dword ptr FindData.cFileName == 'YCER' 
               jmp     NextDir
         .endif
         .if Code == 1
            INVOKE     lstrlen, addr szBuff0
               sub     eax, 3
            INVOKE     lstrcpyn, addr szBuff1, addr szBuff0, eax
            INVOKE     lstrcat, addr szBuff1, addr szSlashB
         .else
;            INVOKE     lstrcpyn, addr szBuff1, addr szDir, 4
         .endif
         INVOKE     lstrcat, addr szBuff1, addr FindData.cFileName
         INVOKE     lstrcat, addr szBuff1, addr szAllFiles
            mov     LevD, 0
         INVOKE     FillTree, addr FindData.cFileName, Code
            jmp     GetSubDir
      .endif
            jmp     NextDir

;_______________________________________________________________________
GetSubDir:
      .if byte ptr szBuff1+3 == 'S' && byte ptr szBuff1+10 == 'V' && byte ptr szBuff1+17 == 'I'
            mov     LevD, 0
            jmp     NextDir
      .endif
      INVOKE     FindFirstFile, addr szBuff1, addr FindData
      .if eax == -1
            mov     LevD, 0
            jmp     NextDir
      .endif
         mov     ecx, LevD
         mov     hSubDir[ecx*4], eax
         jmp     ChkSubDir

;_______________________________________________________________________
NextSubDir:
         mov     ecx, LevD
      INVOKE     FindNextFile, hSubDir[ecx*4], addr FindData
      .if !eax                       ; eax = 0 = failure
            mov     ecx, LevD
         INVOKE     FindClose, hSubDir[ecx*4]
            mov     LevD, 0
            jmp     NextDir
      .endif

;_______________________________________________________________________
ChkSubDir:
      .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
         .if byte ptr FindData.cFileName == '.'
               jmp     NextSubDir
         .endif
         INVOKE     lstrlen, addr szBuff1
            mov     ecx, LevD
            mov     PathLen[ecx*4], eax
            sub     eax, 2
         INVOKE     lstrcpyn, addr szBuff1, addr szBuff1, eax
         INVOKE     lstrcat, addr szBuff1, addr FindData.cFileName
         INVOKE     lstrcat, addr szBuff1, addr szAllFiles
            mov     ecx, LevD
         INVOKE     FindClose, hSubDir[ecx*4]
            inc     LevD
         .if LevD < 2
               mov     eax, hItemD
               mov     tvi.hItem, eax
               mov     tvi.imask, TVIF_CHILDREN
;         mov     tvi.iImage, 5
;         mov     tvi.iSelectedImage, 6
               mov     tvi.cChildren, 1
            INVOKE     SendMessage, hWndTreeD, TVM_SETITEM, 0, addr tvi
         .endif
            jmp     GetSubDir
      .endif
         jmp     NextSubDir

AllDone:
      INVOKE     FindClose, hFind

NoFile:
         xor     eax, eax
         ret

GetDirs ENDP

;==============================================================
; Get Drive if root
;==============================================================
GetDrive PROC uses esi DrvPath:DWORD
LOCAL    szBuff[256]:byte

      INVOKE     lstrcpy, addr szBuff, DrvPath
      INVOKE     lstrlen, addr szBuff
         dec     eax
         mov     ecx, eax
      .while (ecx)
         .if byte ptr szBuff[ecx] == '(' && byte ptr szBuff[ecx+2] == ':'
               inc     ecx
            INVOKE     lstrcpyn, DrvPath, addr szBuff[ecx], 3
            INVOKE     lstrcat, DrvPath, addr szSlashB  ;N O T E !!! 01-05-2004
            .break
         .endif
            dec     ecx
      .endw
         xor     eax, eax   
      .if !ecx
            mov     eax, -1
      .endif
         ret

GetDrive ENDP

;===================================================
; Notify for the Treeview
;===================================================
TreeViewNotifyD PROC uses ebx esi wParam:DWORD, lParam
LOCAL    pt:POINT
LOCAL    tvi:TV_ITEM
LOCAL    tvhti:TV_HITTESTINFO
LOCAL    Sedi:DWORD, TreeCode
LOCAL    szWork1[64]:BYTE, szWork2[64], szBuff0[256], szBuff1[256]

         mov     eax, lParam
         mov     ebx, (NM_TREEVIEW ptr [eax]).hdr.code
         mov     ecx, (NM_TREEVIEW ptr [eax]).itemNew.hItem
         mov     edx, (NM_TREEVIEW ptr [eax]).itemNew.state
         mov     esi, (NMHDR ptr [eax]).code

; States
; 01h = Focused
; 02h = Selected
; 20h = Edpanded
; 40h = ExpandedOnce

      .if esi == NM_RCLICK
            jmp     RightClk
      .endif

      .if ebx == TVN_ITEMEXPANDING || ebx == TVN_SELCHANGING
;DSPValue hWnd, edx, 1, 't'
;DSPValue hWnd, ebx
         .if ebx == TVN_SELCHANGING
           test     (NM_TREEVIEW ptr [eax]).action, TVIS_FOCUSED
             jz     Ret0
         .endif

;---------- [Retrive the path from the selected item] ----------
            and     TreeCode, 0
         .if edx && edx != TVIS_SELECTED || ebx == TVN_SELCHANGING
               mov     TreeCode, 14
         .endif

GetProjPath:
            mov     hItemD, ecx
            mov     ItemNew, ecx
            mov     tvi.hItem, ecx
            mov     tvi.imask, TVIF_TEXT
            lea     eax, szWork1
            mov     tvi.pszText, eax
            mov     tvi.cchTextMax, sizeof szWork1
           push     edx
         INVOKE     SendMessage, hWndTreeD, TVM_GETITEM, NULL, addr tvi
            pop     edx
            mov     eax, hItemD
         .if !edx && eax == hParentD
               jmp     Ret0
         .endif

         INVOKE     GetDrive, addr szWork1
         .if eax != -1
;            INVOKE     lstrcat, addr szWork1, addr szSlashB
         .endif
;.if CreateOn == 55
;INVOKE     MessageBox, NULL, addr szWork1, addr AppName, MB_OK
;.endif
            mov     eax, hItemD

         .if byte ptr szWork1+1 == ':'
               mov     hDrvExp, eax
            INVOKE     lstrcpy, addr szBuff0, addr szWork1
            INVOKE     lstrcat, addr szBuff0, addr szAll
               jmp     DriveHit
         .endif

            lea     edi, szBuff1
            add     edi, 250
            mov     byte ptr[edi], 0
            mov     byte ptr[edi-1], '\'
            sub     edi, 2
            mov     Sedi, edi
         .while (eax != hParentD)
            INVOKE     lstrlen, addr szWork1
               mov     ebx, eax
               mov     ecx, eax
               mov     edi, Sedi
            .while (ecx)
                  mov     al, byte ptr szWork1[ebx-1]
                  mov     byte ptr[edi], al
                  dec     edi
                  dec     ebx
                  dec     ecx
            .endw

               mov     Sedi, edi
            INVOKE     SendMessage, hWndTreeD, TVM_GETNEXTITEM, TVGN_PARENT, hItemD
               mov     hItemD, eax
               mov     tvi.hItem, eax
               mov     tvi.imask, TVIF_TEXT
               lea     eax, szWork1
               mov     tvi.pszText, eax
               mov     tvi.cchTextMax, sizeof szWork1
            INVOKE     SendMessage, hWndTreeD, TVM_GETITEM, NULL, addr tvi

            INVOKE     GetDrive, addr szWork1
            .if eax != -1
;               INVOKE     lstrcat, addr szWork1, addr szSlashB
            .endif

               mov     eax, hItemD
            .if byte ptr szWork1+1 != ':' && eax != hParentD
                  mov     edi, Sedi
                  mov     byte ptr[edi], '\'
                  dec     edi
                  mov     Sedi, edi
            .endif
               mov     eax, hItemD
         .endw
            mov     edi, Sedi
            lea     eax, szBuff1
            sub     edi, eax
            inc     edi
         INVOKE     lstrcpy, addr szBuff0, addr szBuff1[edi]
         INVOKE     lstrcpy, addr szLoadPathD, addr szBuff0
         INVOKE     lstrcat, addr szBuff0, addr szAll

DriveHit:
         .if TreeCode != 14
            INVOKE     GetDirs, 1, addr szBuff0
         .endif
            mov     eax, hItemD
         .if eax != hParentD
            INVOKE     SendMessage, hWndTreeD, TVM_SORTCHILDREN, 0, ItemNew
         .endif
         INVOKE     SendMessage, hWndTreeD, TVM_ENSUREVISIBLE, 0, ItemNew
          MOVmd     hItemD, ItemNew

;---------- [Create a project from the drive tree
         .if CreateOn == 55
            INVOKE     CreateDialogParam, hInst, IDD_GROUPS, hREdit, addr ProjectMaint, 4
               mov     hWndDlg, eax
            INVOKE     lstrcpy, addr szLoadPathD, addr szSavePathD
              call     InitTreeList
               and     CreateOn, 0
         .endif

      .elseif ebx == TVN_SELCHANGED
           test     (NM_TREEVIEW ptr [eax]).action, TVIS_FOCUSED
             jz     Ret0
            mov     tvi.hItem, ecx
            mov     tvi.imask, TVIF_TEXT
            lea     eax, szWork1
            mov     tvi.pszText, eax
            mov     tvi.cchTextMax, sizeof szWork1
         INVOKE     SendMessage, hWndTreeD, TVM_GETITEM, NULL, addr tvi

         INVOKE     GetDrive, addr szWork1

         INVOKE     lstrlen, addr szWork1
         .if eax > 3 || byte ptr szWork1+1 != ':'                      ; Not root dir
         .else
            INVOKE     lstrcpy, addr szLoadPathD, addr szWork1
         .endif
         INVOKE     SendMessage, hWnd, WM_SETTEXT, 0, addr szLoadPathD
         INVOKE     ReadTheFile, addr szLoadPathD
      .endif
         jmp     Ret0

;---------- [Create a Project] ----------
RightClk:
      INVOKE     GetCursorPos, addr pt
      INVOKE     ScreenToClient, hWndTreeD, addr pt
         mov     eax, pt.x
         mov     tvhti.pt.x, eax
         mov     eax, pt.y
         mov     tvhti.pt.y, eax
      INVOKE     SendMessage, hWndTreeD, TVM_HITTEST, 0, addr tvhti
      .if (tvhti.flags & TVHT_ONITEM)
         INVOKE     ClientToScreen, hWndTreeD, addr pt
            mov     tvi.imask, TVIF_HANDLE or TVIF_TEXT
            mov     eax, tvhti.hItem
            mov     tvi.hItem, eax
            lea     eax, WorkBuff
            mov     tvi.pszText, eax
            mov     tvi.cchTextMax, sizeof WorkBuff
         INVOKE     SendMessage, hWndTreeD, TVM_GETITEM, 0, addr tvi
           test     eax,eax
             jz     Ret0
         INVOKE     MessageBox, NULL, addr szCreateP, addr WorkBuff, MB_YESNO or MB_ICONQUESTION
         .if eax == IDNO
               jmp     Ret0
         .endif
            mov     ecx, tvi.hItem
            mov     CreateOn, 55
            mov     TreeCode, 55
            jmp     GetProjPath
      .endif

Ret0:
         xor     eax, eax   
         ret

TreeViewNotifyD ENDP

;=========================================================================
; Load the ListView with the file data PROCEDURE
;=========================================================================
LoadListView PROC uses ebx edi row:DWORD, lpFileName, TypeF
LOCAL    lvi:LV_ITEM
LOCAL    szBuff0[64]:BYTE

         mov     ebx, ProjDrive
         mov     edi, lpFileName

INVOKE     RtlZeroMemory, addr lvi, sizeof lvi

;---------- [Load the list items] ----------
         mov     lvi.imask, LVIF_TEXT or LVIF_IMAGE or LVIF_PARAM
        push     row
         pop     lvi.iItem
        push     row
         pop     lvi.lParam
         mov     lvi.iSubItem, 0
         mov     lvi.cchTextMax, 255
         lea     eax, [edi.WIN32_FIND_DATA].cFileName
         mov     lvi.pszText, eax
         mov     eax, TypeF
         mov     lvi.iImage, eax
;;;;      .if ProjOn
         INVOKE     SendMessage, hWndList[ebx*4], LVM_INSERTITEM, 0, addr lvi
;;;;      .endif
         ret
LoadListView ENDP

;=========================================================================
; Read the file PROCEDURE
;=========================================================================
ReadTheFile PROC uses ebx edi esi Input:DWORD
LOCAL    FindData:WIN32_FIND_DATA
LOCAL    lvf:LV_FINDINFO
LOCAL    lvi:LV_ITEM
LOCAL    hFind:DWORD, Pointer, Match, Len
LOCAL    szBuff[256]:BYTE, szBuff1[64]:BYTE, szFolderE[64]:BYTE, szFileNameE[64]:BYTE, szEXT[6]:BYTE

         and     Pointer, 0
         and     Match, 0
         and     Texe, 0
         and     Tdll, 0
         and     Tlib, 0
         and     Tinc, 0
         and     hList, 0
         and     hFind, 0
         mov     ebx, ProjDrive
         mov     byte ptr szFolderE, 0
         mov     byte ptr szFileNameE, 0

;---------- [Check if in a Root directory] ----------
      INVOKE     lstrcpy, addr szPathIn, Input
      INVOKE     lstrlen, addr szPathIn
         dec     eax
      .while (eax)
            dec     eax
         .if byte ptr szPathIn[eax] == '\'
            .if byte ptr szPathIn[eax-1] == ':'
;DSPValue hWnd, 1234, 1, 'm'
;INVOKE     MessageBox, NULL, addr szProjectP, addr AppName, MB_OK
            .endif
            .break
         .endif
      .endw

      .if !Run
         INVOKE     CreateWindowEx, WS_EX_TOPMOST, addr ListboxClass, 0,\
                    WS_CHILD or WS_VSCROLL or LBS_HASSTRINGS,\
                    200, 50, 150, 400, hWnd, 85, hInst, 0
            mov     hList, eax

         .if !FilterGroup
               lea     esi, offset FilterDef
         .elseif FilterGroup == 1
               lea     esi, offset UserFilt01
         .elseif FilterGroup == 2
               lea     esi, offset UserFilt02
         .endif
            xor     eax, eax

Getlen:
         .if byte ptr[esi+eax] == 2ch
               mov     Len, eax
               inc     Len 
            INVOKE     lstrcpyn, addr szBuff1, esi, Len
            INVOKE     SendMessage, hList, LB_ADDSTRING, 0, addr szBuff1
               add     esi, Len
               xor     eax, eax
               jmp     Getlen
         .elseif byte ptr[esi+eax] == 0h
            INVOKE     SendMessage, hList, LB_SETSEL, TRUE, 0
               jmp     LoadDone
         .endif
            inc     eax
            jmp     Getlen

LoadDone:
         INVOKE     SendMessage, hWndList[ebx*4], LVM_DELETEALLITEMS, 0, 0
         .if ProjOn && !ProjDrive
            INVOKE     lstrcpy, addr szBuff, addr RootDir
;            INVOKE     lstrcat, addr szBuff, addr szPointer

            .if ProjGroup
               INVOKE     lstrcat, addr szBuff, addr szPointUser
            .endif
               mov     esi, ProjGroup
            INVOKE     lstrcat, addr szBuff, PtrArray[esi*4]

;            INVOKE     lstrcat, addr szBuff, addr szProject
            INVOKE     lstrcat, addr szBuff, ProjNamArray[esi*4]
            INVOKE     lstrcat, addr szBuff, addr PatnP+10  ; = .ptr

;---------- [See if there is a pointer file] ----------
            INVOKE     FindFirstFile, addr szBuff, addr FindData
            .if eax != INVALID_HANDLE_VALUE
               INVOKE     FindClose, eax
                  mov     Pointer, 1
            .endif
         .endif
      .endif

      INVOKE     lstrcpy, addr szBuff, Input
      INVOKE     lstrcpy, addr szPathIn, addr szBuff
      INVOKE     lstrcat, addr szBuff, addr szAll

;---------- [Check for mult exe's] ----------
      .if Run
         INVOKE     FindFirstFile, addr szBuff, addr FindData
         .if eax != INVALID_HANDLE_VALUE
               mov     hFind, eax
            .while (eax)
               .if byte ptr FindData.cFileName != '.'
                  INVOKE     lstrcpy, addr szBuff1, addr FindData.cFileName
                  INVOKE     lstrlen, addr szBuff1
                     sub     eax, 3
                  .if byte ptr szBuff1[eax] == 'e' && byte ptr szBuff1[eax+2] == 'e' ||\
                      byte ptr szBuff1[eax] == 'E' && byte ptr szBuff1[eax+2] == 'E'
                        inc     Texe
                  .endif
               .endif
               INVOKE     FindNextFile, hFind, addr FindData
            .endw
            INVOKE     FindClose, hFind
         .endif

;---------- [Get the folder name] ----------
         INVOKE     lstrlen, addr szPathIn
           push     eax
            dec     eax
         .while (eax)
               dec     eax
            .if byte ptr szPathIn[eax] == '\'
               .break
            .endif
         .endw
            pop     ecx
            sub     ecx, eax
            inc     eax
            dec     ecx
         INVOKE     lstrcpyn, addr szFolder, addr szPathIn[eax], ecx

;;;;.if ProjOn  ; $$$$
;   INVOKE     lstrcpy, addr szFolder, addr szProject
      mov     eax, ProjGroup
   INVOKE     lstrcpy, addr szFolder, ProjNamArray[eax*4]
;;;;.endif
;         INVOKE     lstrcpy, addr szProjName, addr szFolder
         INVOKE     lstrcpy, addr szFolderE, addr szFolder
         INVOKE     lstrcat, addr szFolderE, addr szExe
         .if Run == 1
            INVOKE     lstrlen, addr FileName
               sub     eax, 3
            .if byte ptr FileName[eax] == '.' || byte ptr FileName[eax-1] == '.'
               .if byte ptr FileName[eax] == '.'
                     inc     eax
               .endif
               INVOKE     lstrcpyn, addr szFileNameE, addr FileName, eax
               INVOKE     lstrcat, addr szFileNameE, addr szExe
            .endif
         .endif
      .endif

      .if Run == 4
            ret
      .endif
;DSPValue hWnd, 7777, 1, 'm'
;INVOKE     MessageBox, NULL, addr szFolderE, addr AppName, MB_OK
;INVOKE     MessageBox, NULL, addr szFileNameE, addr AppName, MB_OK

      INVOKE     FindFirstFile, addr szBuff, addr FindData
      .if eax != INVALID_HANDLE_VALUE
            mov     hFind, eax
            xor     edi, edi
         .while eax != 0
            .if byte ptr FindData.cFileName != '.'
               .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
               .else
                  INVOKE     lstrcpy, addr szBuff1, addr FindData.cFileName
                  INVOKE     lstrlen, addr szBuff1
                  .while (eax)
                     .if byte ptr szBuff1[eax] == '.'
                        .break
                     .endif
                        dec     eax
                  .endw
                  .if eax
                        inc     eax
INVOKE     lstrcpy, addr szEXT, addr FindData.cFileName[eax]
INVOKE     lstrlen, addr szEXT
   mov     ecx, eax
   lea     esi, szEXT
  call     LowerCase
;INVOKE     MessageBox, NULL, addr szEXT, addr AppName, MB_OK

                     .if Run                ; Find the exe file
                        .if byte ptr szEXT[0] == 'e' && byte ptr szEXT[1] == 'x' &&\
                            byte ptr szEXT[2] == 'e'
                           .if Texe > 1 ; Mult exe's
                              INVOKE     lstrcmpi, addr szFolderE, addr FindData.cFileName
                              .if eax == 0
                                    inc     Match
                                 .if Run == 1
                                    INVOKE     lstrcat, Input, addr FindData.cFileName
                                    .break
                                 .endif
                              .else

                                 INVOKE     lstrcmpi, addr szFileNameE, addr FindData.cFileName
                                 .if eax == 0
                                       inc     Match
                                    .if Run == 1
                                       INVOKE     lstrcat, Input, addr FindData.cFileName
                                       .break
                                    .endif
                                 .else
                                       jmp     Pass
                                 .endif

                              .endif
                           .else
                                 inc     Match
                              .if Run == 1
                                 INVOKE     lstrcat, Input, addr FindData.cFileName
                                 .break
                              .endif
                                 jmp     Pass
                           .endif

                        .elseif Run == 2    ; Copy
                             push     eax
                           INVOKE     lstrlen, addr FindData.cFileName
                              sub     eax, 3
                           INVOKE     lstrcpyn, addr szBuff, addr FindData.cFileName, eax
                           INVOKE     lstrcmpi, addr szFolder, addr szBuff
                           .if eax != 0
                                 pop     eax
                                 jmp     Pass
                           .endif
                              pop     eax
                           .if byte ptr szEXT[0] == 'd' && byte ptr szEXT[1] == 'l' &&\
                               byte ptr szEXT[2] == 'l'
                                 inc     Tdll
                           .elseif byte ptr szEXT[0] == 'l' && byte ptr szEXT[1] == 'i' &&\
                               byte ptr szEXT[2] == 'b'
                                 inc     Tlib
                           .elseif byte ptr szEXT[0] == 'i' && byte ptr szEXT[1] == 'n' &&\
                               byte ptr szEXT[2] == 'c'
                                 inc     Tinc
                           .else
                                 jmp     Pass
                           .endif          
;                           INVOKE     lstrcat, Input, addr FindData.cFileName
                              inc     Match
                        .else
                        .endif
                           jmp     Pass
                     .endif

                     .if FilterOn                              ; Get the files for the Listview
                        INVOKE     SendMessage, hList, LB_FINDSTRINGEXACT, -1, addr szEXT
                        .if eax != LB_ERR
                        .else
                              jmp     Pass
                        .endif
                     .endif

                     .if byte ptr szEXT[0] == 'a' && byte ptr szEXT[1] == 's'
                           mov     ecx, 2
                     .elseif byte ptr szEXT[0] == 'r' && byte ptr szEXT[1] == 'c'
                           mov     ecx, 5
                     .elseif byte ptr szEXT[0] == 'i' && byte ptr szEXT[1] == 'n'
                           mov     ecx, 6
                     .elseif byte ptr szEXT[0] == 'd' && byte ptr szEXT[1] == 'e'
                           mov     ecx, 3
                     .elseif byte ptr szEXT[0] == 'j' && byte ptr szEXT[1] == 'a'
                           mov     ecx, 2
                     .elseif byte ptr szEXT[0] == 'h' && byte ptr szEXT[1] == 't'
                           mov     ecx, 6
                     .else
                           mov     ecx, 4
                     .endif
                     INVOKE     LoadListView, edi, addr FindData, ecx
                        inc     edi
                  .endif
               .endif
            .endif
Pass:
            INVOKE     FindNextFile, hFind, addr FindData
         .endw

;---------- [Load the Pointer item if available] ----------
         .if !Run && Pointer && ProjOn
INVOKE     RtlZeroMemory, addr lvi, sizeof lvi
               mov     lvi.imask, LVIF_TEXT or LVIF_IMAGE or LVIF_PARAM
               mov     lvi.iItem, edi
               mov     lvi.lParam, edi
               mov     lvi.iSubItem, 0
;;;;            .if ProjOn
;               INVOKE     lstrcpy, addr szBuff1, addr szProject
                  mov     eax, ProjGroup
               INVOKE     lstrcpy, addr szBuff1, ProjNamArray[eax*4]
;;;;            .endif
            INVOKE     lstrcat, addr szBuff1, addr PatnP+10  ; = .ptr
               lea     eax, szBuff1
               mov     lvi.pszText, eax
               mov     lvi.iImage, 7
;;;;            .if ProjOn
               INVOKE     SendMessage, hWndList[ebx*4], LVM_INSERTITEM, 0, addr lvi
;;;;            .endif

jmp     Snap
            .if FileName
                  mov     lvf.flags, LVFI_STRING
                  mov     lvf.psz, offset FileName
               INVOKE     SendMessage, hWndList[ebx*4], LVM_FINDITEM, -1, addr lvf
               .if eax !=-1
                     mov     lvi.iItem, eax
                     mov     lvi.imask, LVIF_STATE
                     mov     lvi.state, LVIS_SELECTED or LVIS_FOCUSED
                     mov     lvi.stateMask, -1
                  INVOKE     SendMessage, hWndList[ebx*4], LVM_SETITEMSTATE, lvi.iItem, addr lvi
               .endif
            .endif
         .endif
Snap:

         .if hList
            INVOKE     DestroyWindow, hList
               and     hList, 0
         .endif
         .if hFind
            INVOKE     FindClose, hFind
         .endif
         .if Run && !Match
            INVOKE     MessageBox, NULL, addr szMsg01, addr szFolder, MB_OK or MB_ICONWARNING
         .endif
      .endif

         ret

ReadTheFile ENDP

;==========================================================================
; Builds the path to display in the Edit window from the Listview PROCEDURE
;==========================================================================
DisplayFileName PROC uses ebx
LOCAL    lvi:LV_ITEM
LOCAL    tvi:TV_ITEM
LOCAL    SavItem:DWORD
LOCAL    ShFileOp:SHFILEOPSTRUCT
LOCAL    szBuff[256]:BYTE, szCurDir[256]:BYTE, szTabName[64]:BYTE

         mov     ebx, ProjDrive
;      INVOKE     lstrcpy, addr szPathIn, addr szLoadPath
;         mov     tvi.imask, TVIF_HANDLE or TVIF_TEXT
;;;;      .if ProjOn
         INVOKE     SendMessage, hWndList[ebx*4], LVM_GETNEXTITEM, -1, LVNI_FOCUSED
;;;;      .endif
      .if eax == -1
            ret
      .endif

mov     SavItem, eax
         mov     lvi.iItem, eax
         mov     lvi.iSubItem, 0
         mov     lvi.imask, LVIF_TEXT ;or LVIF_STATE
         lea     eax, szTabName
         mov     lvi.pszText, eax
         mov     lvi.cchTextMax, sizeof szTabName

;;;;      .if ProjOn
         .if ProjOn
               mov     ecx, hItem
         .else
               mov     ecx, hItemD
         .endif
         INVOKE     SendMessage, hWndTree[ebx*4], TVM_GETNEXTITEM, TVGN_CARET, ecx
;;;;      .endif

         mov     tvi.hItem, eax
;;;;.if ProjOn  ; $$$$
;         lea     eax, szProject
         mov     ecx, ProjGroup
         mov     eax, ProjNamArray[ecx*4]
;;;;.endif
         mov     tvi.pszText, eax
         mov     tvi.cchTextMax, sizeof szProject

;;;;      .if ProjOn
         INVOKE     SendMessage, hWndList[ebx*4], LVM_GETITEM, 0, addr lvi
         INVOKE     SendMessage, hWndTree[ebx*4], TVM_GETITEM, 0, addr tvi
;;;;      .endif

      INVOKE     lstrlen, addr szTabName
      .if byte ptr szTabName[eax-3] == 'p' && byte ptr szTabName[eax-1] == 'r'
         INVOKE     lstrcpy, addr szBuff, addr RootDir
;         INVOKE     lstrcat, addr szBuff, addr szPointer

      .if ProjGroup
         INVOKE     lstrcat, addr szBuff, addr szPointUser
      .endif
         mov     ecx, ProjGroup
      INVOKE     lstrcat, addr szBuff, PtrArray[ecx*4]

      .elseif ;;;;ProjOn
         .if ProjOn
            INVOKE     lstrcpy, addr szBuff, addr szLoadPath
         .else
            INVOKE     lstrcpy, addr szBuff, addr szLoadPathD
            INVOKE     lstrcpy, addr szSavePathD, addr szLoadPathD
         .endif
      .endif

;---------- [Delete File] ----------
      .if Run == 75
         INVOKE     MessageBox, NULL, addr szDeleteF, addr szTabName, MB_YESNO or\
                    MB_ICONWARNING or MB_TASKMODAL
         .if eax == IDNO
               jmp     Ret0
         .endif
         INVOKE     RtlZeroMemory, addr ShFileOp, sizeof ShFileOp
;         INVOKE     GetCurrentDirectory, lengthof szCurDir, addr szCurDir
;         INVOKE     SetCurrentDirectory, addr szBuff
         INVOKE     lstrcat, addr szBuff, addr szTabName

         INVOKE     lstrlen, addr szBuff
            inc     eax
            mov     szBuff[eax], 0       ; Insert additional terminator
            mov     ShFileOp.wFunc, FO_DELETE
            mov     ShFileOp.hwnd, 0     ; If 0, then no parent can task switch away
            lea     eax, szBuff
            mov     ShFileOp.pFrom, eax
            mov     ShFileOp.fFlags, FOF_SILENT or FOF_NOCONFIRMATION or FOF_ALLOWUNDO
         INVOKE     SHFileOperation, addr ShFileOp
         .if eax != 0
;            INVOKE     MessageBox, NULL, addr szError9, addr pTitle, MB_OK or MB_ICONWARNING
         .else
;;;;            .if ProjOn
               INVOKE     SendMessage, hWndList[ebx*4], LVM_DELETEITEM, SavItem, 0
;;;;            .endif
         .endif
;            INVOKE     SetCurrentDirectory, addr szCurDir
               ret
      .endif

      INVOKE     lstrcat, addr szBuff, addr szTabName
      INVOKE     lstrcpy, addr PathName, addr szBuff
      INVOKE     lstrcpy, addr FileName, addr szTabName

Ret0:

         xor     eax, eax
         ret
DisplayFileName ENDP

;=========================================================================
; Delete project PROCEDURE
;=========================================================================
DelProj  PROC  uses ebx esi edi  PNane:DWORD, w1
LOCAL    FindData:WIN32_FIND_DATA
LOCAL    ShFileOp:SHFILEOPSTRUCT
LOCAL    hReg:DWORD, hFind, hFile, Bytesread, SPos1, sw, NoFile
LOCAL    szBuff0[256]:BYTE, szBuff1[256]:BYTE, szBuff2[256]:BYTE, szCurDir[256]:BYTE, Misc[40]:BYTE
LOCAL    szBuff3[256]:BYTE

      INVOKE     RtlZeroMemory, addr ShFileOp, sizeof ShFileOp
         and     NoFile, 0

;      .if eax == ERROR_SUCCESS
         INVOKE     lstrcpy, addr szBuff0, addr AsmRootDir
;         INVOKE     lstrcat, addr szBuff0, addr szPointer

      .if ProjGroup
         INVOKE     lstrcat, addr szBuff0, addr szPointUser
      .endif
         mov     ecx, ProjGroup
      INVOKE     lstrcat, addr szBuff0, PtrArray[ecx*4]

         INVOKE     lstrcat, addr szBuff0, PNane
         INVOKE     lstrcat, addr szBuff0, addr PatnP+10  ; = .ptr
         INVOKE     lstrcpy, addr szBuff1, addr AsmRootDir
         INVOKE     lstrcat, addr szBuff1, addr szProjects
         INVOKE     lstrcat, addr szBuff1, PNane
         INVOKE     lstrcat, addr szBuff1, addr szSlashB
         INVOKE     GetCurrentDirectory, lengthof szCurDir, addr szCurDir
;         INVOKE     SetCurrentDirectory, addr szBuff1

         .if w1 == 4444                         ; From the Project Tree
            INVOKE     DialogBoxParam, hInst, addr DlgName4, hWnd, addr ChkDelProj, 0
            .if !DeleteOn
                  jmp     DelDone

            .elseif DeleteOn == 2               ; Delete pointer file only
               INVOKE     lstrcpy, addr szBuff1, addr szBuff0
                  mov     sw, 1
                  jmp     LoopDel
            .endif
         .endif

;---------- [Delete the complete Project
         INVOKE     lstrcat, addr szBuff1, addr szAll

;---------- [Read the pointer file
         INVOKE     CreateFile, addr szBuff0,\
                    GENERIC_READ or GENERIC_WRITE ,\
                    FILE_SHARE_READ or FILE_SHARE_WRITE,\
                    0, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0
         .if eax == -1
               jmp     DelDone
         .endif
            mov     hFile, eax
         INVOKE     GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, 100000
            mov     hpMem, eax
         INVOKE     GlobalLock, hpMem
            mov     fpMem, eax
         INVOKE     ReadFile, hFile, fpMem, 100000, addr Bytesread, NULL
         INVOKE     CloseHandle, hFile

            mov     al, 3ah               ; Colon
            mov     ecx, Bytesread        ; Bytes left to analyze
            mov     edi, fpMem            ; Start address in input buffer
            mov     SPos1, edi
            cld                           ; Increment edi
          repnz     scasb                 ; Repeat until byte = al(3ah)
            mov     eax, edi
            sub     eax, fpMem
           push     eax
         INVOKE     lstrcpyn, addr Misc, SPos1, eax
            pop     eax
            inc     eax
            add     SPos1, eax
            mov     ecx, eax
            mov     eax, 256 ;Bytesread
            sub     eax, ecx
            inc     eax

            mov     ecx, 256 ;20
            mov     ebx, SPos1
         .while (ecx)
            .if byte ptr [ebx+eax] == '\'
               .break
            .endif
               dec     eax
               dec     ecx
         .endw
         .if !ecx
               mov     NoFile, 1
         .endif
            add     eax, 2

;---------- [Check for a drive letter] ----------
            mov     ebx, SPos1
         .if byte ptr [ebx+1] != ':'
              push     eax
            INVOKE     lstrcpyn, addr szBuff2, addr AsmRootDir, 3
               pop     eax
            INVOKE     lstrcpyn, addr szBuff2+2, SPos1, eax
         .else
            INVOKE     lstrcpyn, addr szBuff2, SPos1, eax
         .endif

         INVOKE     GlobalUnlock, fpMem
         INVOKE     GlobalFree, hpMem

         .if NoFile
            INVOKE     lstrcpy, addr szBuff1, addr szBuff0
               mov     sw, 1
               jmp     LoopDel
         .endif
;      .else
; Do message
;            jmp     DelDone
;      .endif
      INVOKE     MessageBox, NULL, addr szError7, addr szBuff2, MB_YESNO or MB_ICONQUESTION
      .if eax == IDNO
            jmp     DelDone
      .endif

;---------- [Make sure the files are not in the root directory] ----------
      INVOKE     lstrlen, addr szBuff1
         mov     ecx, eax
         xor     eax, eax
         xor     edx, edx
      .while (ecx)
         .if byte ptr szBuff1[eax] == '\'
               inc     edx
         .endif
            inc     eax
            dec     ecx
      .endw
      .if edx < 3
         INVOKE     lstrcpy, addr szBuff1, addr szBuff0
            mov     sw, 1
            jmp     LoopDel
      .endif

   and     sw, 0
INVOKE     lstrlen, addr szBuff1
   sub     eax, 3
INVOKE     lstrcpyn, addr szBuff1, addr szBuff1, eax
INVOKE     GetFileAttributes, addr szBuff1
.if eax == -1
   INVOKE     MessageBox, NULL, addr szError8, addr szBuff1, MB_YESNO or MB_ICONWARNING
   .if eax == IDNO
         and     w1, 0
         jmp     SetCurr
   .endif
   INVOKE     lstrlen, addr szBuff2
   INVOKE     lstrcpyn, addr szBuff1, addr szBuff2, eax
   INVOKE     GetFileAttributes, addr szBuff1
   .if eax == -1

   .endif
.endif
jmp     Pass

;---------- [Find First File in the Project Folder] ----------
      INVOKE     FindFirstFile, addr szBuff1, addr FindData
      .if eax == -1
         INVOKE     MessageBox, NULL, addr szError8, addr AppName, MB_YESNO or MB_ICONWARNING
         .if eax == IDNO
               jmp     SetCurr
         .endif
            INVOKE     SetCurrentDirectory, addr szCurDir
            INVOKE     GetCurrentDirectory, lengthof szCurDir, addr szCurDir
            INVOKE     lstrcpy, addr szBuff1, addr szBuff2
            INVOKE     SetCurrentDirectory, addr szBuff1
            INVOKE     lstrcat, addr szBuff1, addr szAll

;---------- [Find First File in a non-Project Folder] ----------
            INVOKE     FindFirstFile, addr szBuff1, addr FindData
            .if eax == -1
; Do message
                  jmp     CloseIt ;SetCurr
            .endif
      .endif
         mov     hFind, eax
         jmp     ChkFile

;---------- [Find Next File] ----------
GetNext:
      INVOKE     FindNextFile, hFind, addr FindData
        test     eax, eax
          jz     CloseIt

;---------- [Validate File] ----------
ChkFile:
      .if byte ptr FindData.cFileName == '.'
            jmp     GetNext
      .endif

INVOKE     lstrcpy, addr szBuff3, addr szBuff2
INVOKE     lstrcat, addr szBuff3, addr FindData.cFileName
;INVOKE     MessageBox, NULL, addr szBuff3, addr AppName, MB_OK

;---------- [Delete File(s)] ----------
      INVOKE     lstrlen, addr szBuff3
         inc     eax
         mov     szBuff3[eax], 0  ; Insert additional terminator
         mov     ShFileOp.wFunc, FO_DELETE
         mov     ShFileOp.hwnd, 0            ; If 0, then no parent can task switch away
         lea     eax, szBuff3
         mov     ShFileOp.pFrom, eax
         mov     ShFileOp.fFlags, FOF_SILENT or FOF_NOCONFIRMATION or FOF_ALLOWUNDO
      INVOKE     SHFileOperation, addr ShFileOp
      .if eax != 0
         INVOKE     MessageBox, NULL, addr szError9, addr AppName, MB_OK or MB_ICONWARNING
         INVOKE     FindClose, hFind
            jmp     SetCurr
      .endif
         jmp     GetNext

CloseIt:
      INVOKE     FindClose, hFind
         and     sw, 0

Pass:
;and     sw, 0
         mov     word ptr szBuff3, ':C'
         mov     byte ptr szBuff3+2, 0
      INVOKE     SetCurrentDirectory, addr szBuff3

;---------- [Delete the Folder] ----------
;      INVOKE     lstrlen, addr szBuff1
;         sub     eax, 3
;      INVOKE     lstrcpyn, addr szBuff1, addr szBuff1, eax

;If pFrom is set to a file name, deleting the file with FO_DELETE will not move it to the 
;Recycle Bin, even if the FOF_ALLOWUNDO flag is set. You must use a full path.
;You must also not set the current directory to the delete directory.

LoopDel:
      INVOKE     lstrlen, addr szBuff1
         inc     eax
         mov     szBuff1[eax], 0             ; Insert additional terminator
         mov     ShFileOp.wFunc, FO_DELETE
         mov     ShFileOp.hwnd, 0            ; If 0, then no parent can task switch away
         lea     eax, szBuff1
         mov     ShFileOp.pFrom, eax
         mov     ShFileOp.fFlags, FOF_SILENT or FOF_NOCONFIRMATION or FOF_ALLOWUNDO
      INVOKE     SHFileOperation, addr ShFileOp
      .if eax != 0 && !sw
         INVOKE     MessageBox, NULL, addr szError10, addr AppName, MB_OK or MB_ICONWARNING
;            jmp     SetCurr
      .endif

      .if !sw
            inc     sw
         INVOKE     lstrcpy, addr szBuff1, addr szBuff0
            jmp     LoopDel                  ; Delete the pointer file
      .endif
      .if w1 == 4444                         ; From the Project Tree
            jmp     SetCurr
      .endif
;      INVOKE     SendMessage, hAsmbox, LB_DELETESTRING, w1, 0

SetCurr:
      INVOKE     SetCurrentDirectory, addr szCurDir
      .if w1 == 4444                         ; From the Project Tree
            mov     eax, w1
            ret
      .endif

DelDone:
         mov     eax, FALSE

         ret
DelProj  Endp

;=========================================================================
; Check project delete type PROCEDURE
;=========================================================================
ChkDelProj proc  hdlg:DWORD, wMsg, wParam, lParam

      .if wMsg == WM_INITDIALOG
         INVOKE     CheckRadioButton, hdlg, 71, 72, 72
         INVOKE     GetDlgItem, hdlg, 1911
         INVOKE     SetFocus, eax

      .elseif wMsg == WM_COMMAND
         .if wParam == 71 || wParam == 72
            INVOKE     GetDlgItem, hdlg, 1911
            INVOKE     SetFocus, eax
         .endif

         .if wParam == 81
               mov     DeleteOn, 2
            INVOKE     IsDlgButtonChecked, hdlg, 71 ; Delete the complete project
            .if eax
                  mov     DeleteOn, 1
            .endif
               jmp     GetOut

         .elseif wParam == 82
               and     DeleteOn, 0
               jmp     GetOut
         .endif

      .elseif wMsg == WM_CLOSE

GetOut:
         INVOKE     EndDialog, hdlg, wParam
            mov     eax, TRUE
            ret
      .endif

Ret0:
         xor     eax, eax
         ret

ChkDelProj endp

;========================================================================
; Expand Tree to proper branch converts a path to a tree handle
;========================================================================
TreeBranch proc uses ebx esi
LOCAL    tvi:TV_ITEM
LOCAL    LevelCnt:DWORD, Cnt, CntL, dwState, Match
LOCAL    szPath[256]:byte, szWork[64], szBuff[64]

      INVOKE     LockWindowUpdate, hWnd           ; Lock parent to avoid flicker

      INVOKE     SendMessage, hWndTreeD, TVM_GETNEXTITEM, TVGN_ROOT, 0
      .if !eax
            ret
      .endif
         mov     hItemD, eax
         and     CntL, 0
         and     Match, 0
      INVOKE     lstrcpy, addr szPath, addr szLoadPathD

;---------- [Get the first path level] ----------
         lea     esi, szPath
         mov     LevelCnt, 1
      .while (byte ptr[esi]) != 0
         .if byte ptr[esi] == '\'
               add     LevelCnt, 1
         .endif
         inc     esi
      .endw

         xor     eax, eax
         lea     esi, szPath
      .while (byte ptr[esi]) != 0
         .if byte ptr[esi] == '\'
               inc     eax
            INVOKE     lstrcpyn, addr szBuff, addr szPath, eax
               inc     esi
            INVOKE     lstrcpy, addr szPath, esi
            .break
         .endif
         inc     eax
         inc     esi
      .endw
         mov     dwState, TVIS_SELECTED ;TVIS_BOLD

;---------- [Get the drive handle from the drive letter] ----------
      .if byte ptr szBuff >= 'a' && byte ptr szBuff <= 'a'
            sub     byte ptr szBuff, 20h
      .endif
         and     Cnt, 0
      INVOKE     lstrlen, addr szDrvLet
         mov     ecx, eax
         xor     eax, eax
         mov     dl, byte ptr szBuff
      .while (ecx)
         .if dl == byte ptr szDrvLet+[eax]
               inc     eax
            .break
         .endif
            inc     eax
            dec     ecx
      .endw

      .if ecx
         .if eax
;               dec     eax
         .endif
            mov     edx, hDrives+[eax*4]
            mov     hItemD, edx
         INVOKE     SendMessage, hWndTreeD, TVM_EXPAND, TVE_EXPAND, hItemD
            jmp     NextLev
      .else
         INVOKE     MessageBox, NULL, addr szError20, addr szLoadPathD, MB_OK or MB_ICONINFORMATION
            ret
      .endif
         xor     ebx, ebx

;---------- [Use the path to expand the tree] ----------
      .while (ebx < LevelCnt)
         .if byte ptr szPath == 0   ; Last level
               and     Match, 0
               mov     dwState, TVIS_SELECTED ;or TVIS_BOLD
            INVOKE     lstrcpy, addr szProjectD, addr szBuff
         .endif

;------------------- [First item of tree] -------------------
         INVOKE     SendMessage, hWndTreeD, TVM_GETNEXTITEM, TVGN_CHILD, hItemD
           test     eax, eax
             jz     ret_ok
            mov     hItemD, eax
          MOVmd     tvi.hItem, hItemD
            mov     tvi.imask, TVIF_TEXT
            lea     eax, szWork
            mov     tvi.pszText, eax
            mov     tvi.cchTextMax, sizeof szWork
         INVOKE     SendMessage, hWndTreeD, TVM_GETITEM, NULL, addr tvi
         INVOKE     lstrcmpi, addr szWork, addr szBuff
         .if eax == 0
             MOVmd     tvi.hItem, hItemD
               mov     tvi.imask, TVIF_STATE
             MOVmd     tvi.state, dwState ;TVIS_SELECTED
               mov     tvi.stateMask, 000000ffh
            INVOKE     SendMessage, hWndTreeD, TVM_SETITEM, NULL, addr tvi
            INVOKE     SendMessage, hWndTreeD, TVM_EXPAND, TVE_EXPAND, hItemD
               inc     Match
               jmp     NextLev
         .endif

;------------------- [Greater then first item of tree] -------------------
         INVOKE     SendMessage, hWndTreeD, TVM_GETNEXTITEM, TVGN_NEXT, hItemD
         .while (eax != 0) 
               mov     hItemD, eax
             MOVmd     tvi.hItem, hItemD
               mov     tvi.imask, TVIF_TEXT
               lea     eax, szWork
               mov     tvi.pszText, eax
               mov     tvi.cchTextMax, sizeof szWork
            INVOKE     SendMessage, hWndTreeD, TVM_GETITEM, NULL, addr tvi
            INVOKE     lstrcmpi, addr szWork, addr szBuff
            .if eax == 0
                MOVmd     tvi.hItem, hItemD
                  mov     tvi.imask, TVIF_STATE
                MOVmd     tvi.state, dwState ;TVIS_SELECTED
                  mov     tvi.stateMask, 000000ffh
               INVOKE     SendMessage, hWndTreeD, TVM_SETITEM, NULL, addr tvi
               INVOKE     SendMessage, hWndTreeD, TVM_EXPAND, TVE_EXPAND, hItemD
                  inc     Match
               .break
            .endif
            INVOKE     SendMessage, hWndTreeD, TVM_GETNEXTITEM, TVGN_NEXT, hItemD
         .endw

;------------------- [Get the directory for the next level] -------------------
NextLev:
         .if byte ptr szPath == 0 && Match
            INVOKE     SendMessage, hWndTreeD, TVM_SELECTITEM, TVGN_FIRSTVISIBLE, hItemD
            INVOKE     SendMessage, hWndTreeD, TVM_SELECTITEM, TVGN_CARET, hItemD
               jmp     ret_ok
         .elseif byte ptr szPath == 0 && !Match
            INVOKE     MessageBox, NULL, addr szError20, addr szLoadPathD, MB_OK or MB_ICONINFORMATION
               jmp     ret_ok
         .endif
            mov     szBuff, 0
            xor     eax, eax
            lea     esi, szPath
         .while (byte ptr[esi]) != 0
            .if byte ptr[esi] == '\'
                  inc     eax
               INVOKE     lstrcpyn, addr szBuff, addr szPath, eax
                  inc     esi
               INVOKE     lstrcpy, addr szPath, esi
               .break
            .endif
            inc     eax
            inc     esi
         .endw
         .if byte ptr szBuff == 0
               jmp     ret_ok
         .endif
            add     CntL, 1
            mov     ebx, CntL
      .endw

ret_ok:
      INVOKE     LockWindowUpdate, 0              ; Unock parent
         and     CreateOn, 0
         ret

TreeBranch endp

