#compact
uses sysutil
uses dialogs

indexbase 1
int ID_Listbox=100
int ID_Info=101

int dmax=0
redim bstring dat[dmax]  'questa definizione dev'essere fuori la funzione

'supports names that contain spaces
'
procedure BuildDirList(bstring filter, int *count, dirq=0)
==========================================================
  '
  indexbase 1
  WIN32_FIND_DATA f
  int    a,e,fi
  sys    h
  'string cr=chr(13,10)
  '
  h=FindFirstFile filter, @f
  count=0
  if h>0 then
    do
      a=0
      if f.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY
        if dirq then a=1
        byte b at @f.cFileName
        if b=46 then  a=0 '.' ' ..'
      else 'NOT A DIRECTORY
        if not dirq then a=1
      end if
      if a then
        count++
        if count>=dmax
          dmax+=256
          redim bstring dat[dmax]
        endif
        dat[count]=f.cFileName
      end if
      e=FindNextFile h, @f
      if e=0 then
        e=GetLastError() 'should be 18 when no more files
        exit do
      end if
    end do
    FindClose h
  end if
  '
end procedure


/*
procedure SplitIntoLines(bstring s, *d[redim], int max, *n)
==========================================================
'**
  @param s is the data string to be split
  @param d is the array for the split data
  @param max is the max number of elements in d
  @param n is the count of elements split
'**
  indexbase 1
  int i = 1
  int a
  string w
  n=0
  do
    a=instr(i,s,cr)
    if a=0 then exit do
    if n>=max then exit do
    if dmax<=n
      dmax+=1000
      redim bstring d[dmax]
    endif
    w=mid(s,i,a-i)
    i=a+2
    n++
    d[n]=w 'unquote(w)
    'exit do
  end do
end procedure
*/

function DialogProc( sys hDlg, uint uMsg, sys wParam, lParam ) as int callback
===============================================================================
  static string dirname 
  static sys hList
  static sys count, c
  int i,h
 
  select case uMsg
 
    case WM_INITDIALOG
       hlist=GetDlgItem(hDlg, ID_Listbox)
       dirname="\*.*"
       BuildDirList(dirname,count,1)
       for i=1 to count
         SendMessage(hList, LB_ADDSTRING, null, dat[i])
       next
       'print DlgDirSelectex(hDlg,filter,count,hList)
       return true

    case WM_COMMAND
       zstring buffer[80]
       int index
       select case loword(wParam)
      
         case IDCANCEL
            EndDialog( hDlg, null )

         case 101 'UP
           'SetCurrentDirectory ".."
           'i=instrev(-1,dirname,"\")
           i=len(dirname)-4
           if i>3
             i=instrev(i,dirname,"\")
             if i>0
               dirname=left(dirname,i)+"*.*"
               'print dirname cr count
               for i=count to 1 step -1
                 SendMessage hlist,LB_DELETESTRING,i-1,0
               next
               BuildDirList(dirname,c,1)
               for i=1 to c
                 SendMessage(hList, LB_ADDSTRING, null, dat[i])
               next
               count=c
             endif
           endif

         case 103 'SELECT
           index = SendMessage(hList, LB_GETCURSEL, 0, 0)
           SendMessage(hList, LB_GETTEXT, index, @buffer)
           i=instrev(-1,dirname,"\")
           if i>0
             if buffer
               print left(dirname,i)+buffer+"\*.*"
             endif
           endif

         case 102 'DOWN
           'get index of List, zero-based
           index = SendMessage(hList, LB_GETCURSEL, 0, 0)
           'get Text
           'int TxtLen = SendMessage(hList,LB_GETTEXTLEN, index, 0)                                          
           SendMessage(hList, LB_GETTEXT, index, @buffer)
           'get count of items
           count = SendMessage(hList, LB_GETCOUNT, 0, 0)
           '
           'string Result
           'Result =
           '"List count = " count & chr(13) & chr(10) &
           '"Selected Item Index = " index+1 & chr(13) & chr(10) &
           '"Selected Item Text = " buffer
           '
           if buffer
             c=count
             string b=dirname
             i=len(b)-3
             dirname=left(b,i)+buffer+"\*.*"
             'print dirname
             'SetCurrentDirectory dirname
             BuildDirList(dirname,count,1)
             if count
               'print "count del " c cr count cr lista
               for i=c to 1 step -1
                 SendMessage hlist,LB_DELETESTRING,i-1,0
               next
               for i=1 to count
                 SendMessage(hList, LB_ADDSTRING, null, dat[i])
               next
               'print  ">>>" dirname
             else 'count=0
               'revert
               'SetCurrentDirectory b
               dirname=b
               count=c
               'print "<<<" b
             endif
           endif
           'mbox Result
         
       end select
 
    case WM_CLOSE
       EndDialog( hDlg, null )

  end select

  return 0
end function

sub winmain()
====================================================
  Dialog( 0, 0, 100, 150, "Select dir",
          WS_OVERLAPPED or WS_SYSMENU or DS_CENTER )

  ListBox( "", ID_Listbox, 10, 10, 60, 70 )
  PushButton( "up", ID_Info  , 10, 85, 20, 12 )
  PushButton( "down", ID_Info+1, 10, 100, 20, 12 )
  PushButton( "select", ID_Info+2, 10, 115, 20, 12 )
 
  CreateModalDialog( null, @DialogProc, 0 )
end sub

winmain()