/*
'#COMPILE EXE
'#DIM ALL
#INCLUDE ONCE .\Windows\Shell.inc
#INCLUDE ONCE .\Windows\user.inc
'#INCLUDE ONCE "shlobj.inc"

%MAX_PATH              260
%BIF_RETURNONLYFSDIRS  1
%BIF_USENEWUI          &H40
%BFFM_SETSELECTION     &H466 
%BFFM_INITIALIZED      1
%S_OK                  0


typedef struct _browseinfoA {
  HWND              hwndOwner; 'Handle per la finestra del proprietario della finestra di dialogo
  PCIDLIST_ABSOLUTE pidlRoot;  'PIDL che specifica il percorso della cartella principale da cui iniziare l'esplorazione.
                               'può essere NUL
  LPSTR             pszDisplayName;  'Puntatore a un buffer per ricevere il nome visualizzato della cartella
                                     'selezionata dall'utente. Si presuppone che la dimensione di questo
                                     'buffer sia di MAX_PATH caratteri.
  LPCSTR            lpszTitle; 'Puntatore a una stringa con terminazione null visualizzata sopra il controllo
                               'visualizzazione struttura ad albero nella finestra di dialogo. Questa stringa
                               'può essere utilizzata per specificare le istruzioni per l'utente
  UINT              ulFlags;
  BFFCALLBACK       lpfn;  'Puntatore a una funzione definita dall'applicazione chiamata dalla finestra di dialogo
                           'quando si verifica un evento. Per ulteriori informazioni, vedere la funzione
                           'BrowseCallbackProc. Questo membro può essere NULL.
  LPARAM            lParam; 'Valore definito dall'applicazione che la finestra di dialogo passa alla funzione
                            'di callback, se specificata in lpfn.
  int               iImage; 'Valore intero che riceve l'indice dell'immagine associata alla cartella selezionata,
                            'memorizzata nell'elenco delle immagini di sistema.
} BROWSEINFOA, *PBROWSEINFOA, *LPBROWSEINFOA;

 string null=nuls 1

type Browseinfo
  sys       hOwner
  sys    pidlRoot
  sys    pszDisplayName
  sys    lpszTitle
  sys       ulFlags
  sys       lpfn
  sys       lParam
  int       iImage
end type


Function SfogliaCartelle(ByVal hwnd As sys) As String
Dim BInfo As BROWSEINFO
long CartellaScelta
long PercorsoAllocato
string PercorsoScelto= space 260
'redim PercorsoScelto[max_path] as char
string title="Scegli una cartella:"
string root="C:\temp"

BInfo.hOwner    = GetActiveWindow()
'BInfo.pidlRoot  = "C:\temp"
BInfo.pidlRoot  = *root
'BInfo.pszDisplayName  = strptr(PercorsoScelto)
BInfo.pszDisplayName  = PercorsoScelto
'BInfo.lpszTitle = strptr(title)
BInfo.lpszTitle = *title
'BInfo.ulFlags   = BIF_USENEWUI
BInfo.ulFlags   = 3
BInfo.lParam   = 0
BInfo.iImage   = 0

PercorsoAllocato = SHBrowseForFolder(BInfo)
print percorsoallocato
'PercorsoScelto = Space 512
CartellaScelta = SHGetPathFromIDList(PercorsoAllocato, PercorsoScelto)
If CartellaScelta Then
  SfogliaCartelle = Left(PercorsoScelto, InStr(PercorsoScelto, Chr(0)) - 1)
  'CoTaskMemFree PercorsoAllocato
  frees PercorsoAllocato
Else
  SfogliaCartelle = ""
End If
End Function


print SfogliaCartelle(0)



'https://www.vbforums.com/showthread.php?179025-treeview-sendmessage
'
*/

/*
Option Explicit
*/
 
==================
'OXYGENBASIC
==================
#compact
uses corewin
'Used for BrowseForDir
% BIF_RETURNONLYFSDIRS = 1
% BIF_EDITBOX = &H10
% MAX_PATH = 260

'! SHBrowseForFolder Lib "shell32" (BrowseInfo *lpbi) as sys
'! SHGetPathFromIDList Lib "shell32" (sys pidList, sys lpBuffer) As sys
'! lstrcat Lib "kernel32" Alias "lstrcatA" (ByVal lpString1 As String, ByVal lpString2 as String) As Long
'! Function SendMessage Lib "user32" Alias "SendMessageA" (sys hwnd, wMsg, wParam, lParam) as int
'
Type BrowseInfo
  sys hWndOwner
  sys pIDLRoot
  sys pszDisplayName
  sys lpszTitle
  int ulFlags
  sys lpfnCallback
  sys lParam
  int  iImage
End Type
'
string strCallBackInitPath=""
 
function BrowseCallbackProc(sys hwnd, int uMsg, sys lParam, sys lpData) as int, callback
========================================================================================
'***CALLBACK FUNCTION***
'Used with the BrowseForFolder function to select a default folder
'On Error Resume Next
  long rret
  % BFFM_ENABLEOK       0x465
  % BFFM_SETSELECTION   0x466
  % BFFM_SETSTATUSTEXT  0x464
  % BFFM_INITIALIZED    1
  % BFFM_SELCHANGED     2
  % BFFM_VALIDATEFAILED 3
 
  'print hex umsg

  if uMsg = BFFM_INITIALIZED
    rret = SendMessage(hwnd, BFFM_SETSELECTION, uMsg, strptr(strCallBackInitPath) )
  endif
  return 0  ' the function should always return 0
end function
 
===================================================
function BrowseForDir(sys frmOwner, 'as Form
  string strTitle = "Please choose a directory",
  string strInitDir="\") As string
'Displays the OS browse for folder dialog.
'frmOwner is the owner form for the dialog, if blank, then the form has no owner
'strTitle is the caption that will display on the dialog, if none is supplied then
'the default is used.
'strInitDir specifies the directory that will be selected by default when the dialog
'is displayed. If none is specified then "My Computer" is selected.
'******NOTE LAST BIT HASN'T BEEN DONE YET**************
'On Error GoTo ErrorHandler
    
  sys lpIDList
  string sBuffer 
  BrowseInfo tBrowseInfo
    
  tBrowseInfo.hWndOwner = frmowner 'frmOwner.hwnd
  tBrowseInfo.lpszTitle = strptr(strTitle)
  tBrowseInfo.ulFlags = BIF_RETURNONLYFSDIRS or BIF_EDITBOX
  'tBrowseInfo.lpfnCallback = @BrowseCallbackProc
    
  'set initial directory
  if len(strInitDir) = 0
    strCallBackInitPath = "\" 'App.Path 'default
  else
    strCallBackInitPath = strInitDir
  endif
  'print strInitDir    
  lpIDList = SHBrowseForFolder(@tBrowseInfo)
        
  if lpIDList
    sBuffer = Space(MAX_PATH)
    SHGetPathFromIDList lpIDList, sBuffer
    sBuffer = left(sBuffer, instr(sBuffer, chr(0) ) - 1)
    return sBuffer
  endif
 
  int err=GetLastError()
  if not err
    exit function
  endif
  '
  ErrorHandler:
  mbox str(Err) ",  BrowseForDir, Module, NmodFile"
end function
 
'USAGE:
'browse for a directory, C:\Windows\Desktop being the default selected directory
sys hWnd=0
string strDir = BrowseForDir(hWnd,"Select a Folder","c:\cevp\")
print strDir

====
'END
====
/*
'Used for BrowseForDir
Private Const BIF_RETURNONLYFSDIRS = 1
Private Const BIF_EDITBOX = &H10
Private Const MAX_PATH = 260
Private Declare Function SHBrowseForFolder Lib "shell32" (lpbi As BrowseInfo) As Long
Private Declare Function SHGetPathFromIDList Lib "shell32" (ByVal pidList As Long, ByVal lpBuffer As String) As Long
Private Declare Function lstrcat Lib "kernel32" Alias "lstrcatA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Type BrowseInfo
    hWndOwner As Long
    pIDLRoot As Long
    pszDisplayName As Long
    lpszTitle As Long
    ulFlags As Long
    lpfnCallback As Long
    lParam As Long
    iImage As Long
End Type
Private strCallBackInitPath As String
 
Private Function BrowseCallbackProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal lParam As Long, ByVal lpData As Long) As Long
'***CALLBACK FUNCTION***
'Used with the BrowseForFolder function to select a default folder
On Error Resume Next
 
    Dim ret As Long
      
    'Const BFFM_ENABLEOK = &H465
    Const BFFM_SETSELECTION = &H466
    'Const BFFM_SETSTATUSTEXT = &H464
    Const BFFM_INITIALIZED = 1
    'Const BFFM_SELCHANGED = 2
    'Const BFFM_VALIDATEFAILED = 3
 
    If uMsg = BFFM_INITIALIZED Then
        'Send a message to the dialog box telling it to select this path.
        'Note the use of ByVal and the CLng function here.
        ret = SendMessage(hwnd, BFFM_SETSELECTION, ByVal CLng(1), _
            ByVal strCallBackInitPath)
    End If
  
    BrowseCallbackProc = 0  ' the function should always return 0
End Function
 
Public Function DummyFunc(ByVal param As Long) As Long
  DummyFunc = param
End Function
 
Public Function BrowseForDir(Optional frmOwner As Form, _
    Optional strTitle As String = "Please choose a directory", _
    Optional strInitDir As String) As String
'Displays the OS browse for folder dialog.
'frmOwner is the owner form for the dialog, if blank, then the form has no owner
'strTitle is the caption that will display on the dialog, if none is supplied then
'the default is used.
'strInitDir specifies the directory that will be selected by default when the dialog
'is displayed. If none is specified then "My Computer" is selected.
'******NOTE LAST BIT HASN'T BEEN DONE YET**************
On Error GoTo ErrorHandler
    
    Dim lpIDList As Long
    Dim sBuffer As String
    Dim tBrowseInfo As BrowseInfo
    
    With tBrowseInfo
        If Not frmOwner Is Nothing Then .hWndOwner = frmOwner.hwnd
        .lpszTitle = lstrcat(strTitle, "")
        .ulFlags = BIF_RETURNONLYFSDIRS Or BIF_EDITBOX
        .lpfnCallback = DummyFunc(AddressOf BrowseCallbackProc)
    End With
    
    'set initial directory
    If Len(strInitDir) <= 0 Then
        strCallBackInitPath = App.Path 'default
    Else
        strCallBackInitPath = strInitDir
    End If
    
    lpIDList = SHBrowseForFolder(tBrowseInfo)
        
    If (lpIDList) Then
        sBuffer = Space(MAX_PATH)
        SHGetPathFromIDList lpIDList, sBuffer
        sBuffer = Left(sBuffer, InStr(sBuffer, vbNullChar) - 1)
        BrowseForDir = sBuffer
    End If
 
    
    Exit Function
 
ErrorHandler:
    ErrLog Err, "BrowseForDir", "Module", "NmodFile"
End Function
 
 
'USAGE:
'browse for a directory, C:\Windows\Desktop being the default selected directory
strDir = BrowseForDir("C:\Windows\Desktop")
*/

